Index: /tags/V_Nov2007/Cosmo/SimLSS/Makefile
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/Makefile	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/Makefile	(revision 3445)
@@ -0,0 +1,241 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+#include ../BuildMgr/sophyamake.inc
+
+OBJ = ${CMVPROG}/obj/
+EXE = ${CMVPROG}/exe/
+LIB = ${CMVPROG}/lib/
+MACH = $(shell echo `uname`)
+ifeq ($(MACH),OSF1)
+CXXREP = -ptr $(OBJ)/CmvBAO_cxxrep/
+endif
+
+MYEXTINC = ${EXTLIBDIR}/Include
+#MYLIB = $(SOPHYAEXTSLBLIST) -L$(LIB) -lcmvsimbao -lfftw3 -lm
+MYLIB = $(SOPHYAEXTSLBLIST) -L$(LIB) -lcmvsimbao -lfftw3_threads -lfftw3 -lm
+
+#--------------------------------------------------------------------------
+# ---- Les programmes de simulation
+PROGS = \
+       $(EXE)cmvtuniv $(EXE)cmvtransf $(EXE)cmvtgrowth $(EXE)cmvtstpk \
+       $(EXE)cmvtstsch $(EXE)cmvtstblack $(EXE)cmvtvarspec \
+       $(EXE)cmvdefsurv $(EXE)cmvobserv3d $(EXE)cmvtintfun \
+       $(EXE)cmvconcherr $(EXE)cmvtinterp $(EXE)cmvtstagn $(EXE)cmvschdist
+#$(EXE)cmvtluc
+ 
+PROGSOBJ = \
+          $(OBJ)cmvtuniv.o $(OBJ)cmvtransf.o $(OBJ)cmvtgrowth.o $(OBJ)cmvtstpk.o \
+          $(OBJ)cmvtstsch.o $(OBJ)cmvtstblack.o $(OBJ)cmvtvarspec.o $(OBJ)cmvdefsurv.o \
+          $(OBJ)cmvobserv3d.o $(OBJ)cmvtintfun.o $(OBJ)cmvtinterp.o \
+          $(OBJ)cmvconcherr.o $(OBJ)cmvtluc.o $(OBJ)cmvtstagn.o $(OBJ)cmvschdist.o
+ 
+LIBROBJ = \
+          $(OBJ)cosmocalc.o $(OBJ)pkspectrum.o $(OBJ)schechter.o \
+          $(OBJ)planckspectra.o $(OBJ)geneutils.o $(OBJ)agnjackson.o \
+          $(OBJ)genefluct3d.o
+
+LIBR = $(LIB)libcmvsimbao.a
+
+#--------------------------------------------------------------------------
+# ---- Les programmes de test
+PROGSTEST = \
+        $(EXE)cmvtluc $(EXE)cmvchkwhu $(EXE)hu_sigma8
+
+PROGSTESTOBJ = \
+        $(OBJ)hu_tf_fit.o $(OBJ)hu_power.o \
+        $(OBJ)cmvtluc.o $(OBJ)cmvchkwhu.o $(OBJ)hu_sigma8.o
+
+#--------------------------------------------------------------------------
+#---- Les programmes utilisant des librairies non standard SOPHYA
+SPROGS = \
+       $(EXE)cmvfitpk
+
+SPROGSOBJ = \
+       $(OBJ)cmvfitpk.o
+
+#----
+all: lib prog
+
+lib: $(LIBR)
+
+prog: $(PROGS)
+
+progtest: $(PROGSTEST)
+
+sprog: $(SPROGS)
+
+allprog: all progtest sprog
+
+clean:
+	rm -f *.o
+	rm -f $(PROGS) $(PROGSOBJ)
+	rm -f $(LIBR) $(LIBROBJ)
+	rm -rf $(OBJ)/CmvBAO_cxxrep/
+	rm -f $(PROGSTEST) $(PROGSTESTOBJ)
+	rm -f $(SPROGS) $(SPROGSOBJ)
+
+##############################################################################
+$(LIB)libcmvsimbao.a : $(LIBROBJ)
+	$(AR) $(ARFLAGS) $@ $? 
+
+$(OBJ)cosmocalc.o: cosmocalc.cc cosmocalc.h constcosmo.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cosmocalc.cc
+$(OBJ)schechter.o: schechter.cc schechter.h constcosmo.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ schechter.cc
+$(OBJ)planckspectra.o: planckspectra.cc planckspectra.h constcosmo.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ planckspectra.cc
+$(OBJ)pkspectrum.o: pkspectrum.cc pkspectrum.h constcosmo.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ pkspectrum.cc
+$(OBJ)geneutils.o: geneutils.cc geneutils.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ geneutils.cc
+$(OBJ)agnjackson.o: agnjackson.cc agnjackson.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ agnjackson.cc
+$(OBJ)genefluct3d.o: genefluct3d.cc genefluct3d.h
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ genefluct3d.cc
+
+##############################################################################
+cmvtuniv: $(EXE)cmvtuniv
+	echo $@ " done"
+$(EXE)cmvtuniv: $(OBJ)cmvtuniv.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtuniv.o $(MYLIB) 
+$(OBJ)cmvtuniv.o: cmvtuniv.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtuniv.cc
+
+##############################################################################
+cmvtransf: $(EXE)cmvtransf
+	echo $@ " done"
+$(EXE)cmvtransf: $(OBJ)cmvtransf.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtransf.o $(MYLIB) 
+$(OBJ)cmvtransf.o: cmvtransf.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtransf.cc
+
+##############################################################################
+cmvtgrowth: $(EXE)cmvtgrowth
+	echo $@ " done"
+$(EXE)cmvtgrowth: $(OBJ)cmvtgrowth.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtgrowth.o $(MYLIB) 
+$(OBJ)cmvtgrowth.o: cmvtgrowth.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtgrowth.cc
+
+##############################################################################
+cmvtstpk: $(EXE)cmvtstpk
+	echo $@ " done"
+$(EXE)cmvtstpk: $(OBJ)cmvtstpk.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtstpk.o $(MYLIB) 
+$(OBJ)cmvtstpk.o: cmvtstpk.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtstpk.cc
+
+##############################################################################
+cmvtstsch: $(EXE)cmvtstsch
+	echo $@ " done"
+$(EXE)cmvtstsch: $(OBJ)cmvtstsch.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtstsch.o $(MYLIB) 
+$(OBJ)cmvtstsch.o: cmvtstsch.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtstsch.cc
+
+##############################################################################
+cmvtstblack: $(EXE)cmvtstblack
+	echo $@ " done"
+$(EXE)cmvtstblack: $(OBJ)cmvtstblack.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtstblack.o $(MYLIB) 
+$(OBJ)cmvtstblack.o: cmvtstblack.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtstblack.cc
+
+##############################################################################
+cmvtvarspec: $(EXE)cmvtvarspec
+	echo $@ " done"
+$(EXE)cmvtvarspec: $(OBJ)cmvtvarspec.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtvarspec.o $(MYLIB) 
+$(OBJ)cmvtvarspec.o: cmvtvarspec.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtvarspec.cc
+
+##############################################################################
+cmvdefsurv: $(EXE)cmvdefsurv
+	echo $@ " done"
+$(EXE)cmvdefsurv: $(OBJ)cmvdefsurv.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvdefsurv.o $(MYLIB) 
+$(OBJ)cmvdefsurv.o: cmvdefsurv.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvdefsurv.cc
+
+##############################################################################
+cmvobserv3d: $(EXE)cmvobserv3d
+	echo $@ " done"
+$(EXE)cmvobserv3d: $(OBJ)cmvobserv3d.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvobserv3d.o $(MYLIB) 
+$(OBJ)cmvobserv3d.o: cmvobserv3d.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvobserv3d.cc
+
+##############################################################################
+cmvtintfun: $(EXE)cmvtintfun
+	echo $@ " done"
+$(EXE)cmvtintfun: $(OBJ)cmvtintfun.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtintfun.o $(MYLIB) 
+$(OBJ)cmvtintfun.o: cmvtintfun.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtintfun.cc
+
+##############################################################################
+cmvconcherr: $(EXE)cmvconcherr
+	echo $@ " done"
+$(EXE)cmvconcherr: $(OBJ)cmvconcherr.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvconcherr.o $(MYLIB) 
+$(OBJ)cmvconcherr.o: cmvconcherr.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvconcherr.cc
+
+##############################################################################
+cmvtinterp: $(EXE)cmvtinterp
+	echo $@ " done"
+$(EXE)cmvtinterp: $(OBJ)cmvtinterp.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtinterp.o $(MYLIB) 
+$(OBJ)cmvtinterp.o: cmvtinterp.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtinterp.cc
+
+##############################################################################
+cmvtstagn: $(EXE)cmvtstagn
+	echo $@ " done"
+$(EXE)cmvtstagn: $(OBJ)cmvtstagn.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtstagn.o $(MYLIB) 
+$(OBJ)cmvtstagn.o: cmvtstagn.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtstagn.cc
+
+##############################################################################
+cmvschdist: $(EXE)cmvschdist
+	echo $@ " done"
+$(EXE)cmvschdist: $(OBJ)cmvschdist.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvschdist.o $(MYLIB) 
+$(OBJ)cmvschdist.o: cmvschdist.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvschdist.cc
+
+
+##############################################################################
+cmvchkwhu: $(EXE)cmvchkwhu
+	echo $@ " done"
+$(EXE)cmvchkwhu: $(OBJ)cmvchkwhu.o $(OBJ)hu_tf_fit.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvchkwhu.o $(OBJ)hu_tf_fit.o $(MYLIB) 
+$(OBJ)cmvchkwhu.o: cmvchkwhu.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvchkwhu.cc
+$(OBJ)hu_tf_fit.o: hu_tf_fit.c hu_tf_fit.h
+	$(CCOMPILE) -o $@ hu_tf_fit.c
+
+hu_sigma8: $(EXE)hu_sigma8
+	echo $@ " done"
+$(EXE)hu_sigma8: $(OBJ)hu_sigma8.o $(OBJ)hu_power.o
+	$(CLINK) -o $@ $(OBJ)hu_sigma8.o $(OBJ)hu_power.o -lc -lm
+$(OBJ)hu_sigma8.o: hu_sigma8.c
+	$(CCOMPILE) -o $@ hu_sigma8.c
+$(OBJ)hu_power.o: hu_power.c hu_power.h
+	$(CCOMPILE) -o $@ hu_power.c
+
+##############################################################################
+cmvtluc: $(EXE)cmvtluc
+	echo $@ " done"
+$(EXE)cmvtluc: $(OBJ)cmvtluc.o
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvtluc.o $(SOPHYASLBLIST) -L$(SOPHYALIBP) -lLUC
+$(OBJ)cmvtluc.o: cmvtluc.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvtluc.cc
+
+##############################################################################
+cmvfitpk: $(EXE)cmvfitpk
+	echo $@ " done"
+$(EXE)cmvfitpk: $(OBJ)cmvfitpk.o $(LIBR)
+	$(CXXLINK) $(CXXREP) -o $@ $(OBJ)cmvfitpk.o $(MYLIB) -lMinuit2Base
+$(OBJ)cmvfitpk.o: cmvfitpk.cc
+	$(CXXCOMPILE) $(CXXREP) -I$(MYEXTINC) -o $@ cmvfitpk.cc
Index: /tags/V_Nov2007/Cosmo/SimLSS/Makeprog
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/Makeprog	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/Makeprog	(revision 3445)
@@ -0,0 +1,24 @@
+# make -f Makeprog 
+include $(SOPHYABASE)/include/sophyamake.inc
+
+LIB = ${CMVPROG}/lib/
+
+MYINC = -I${EXTLIBDIR}/Include -I${HOME}/Sophya/SimLSS
+MYLIB = $(SOPHYAEXTSLBLIST) -L${CMVPROG}/lib -lcmvsimbao -lfftw3_threads -lfftw3 -lm
+
+#---- Les programmes utilitaires de calcul de cartes
+myprog = cmvtest
+
+#----
+
+all: $(myprog)
+
+clean:
+	rm -f $(myprog).o $(myprog)
+
+##############################################################################
+$(myprog): $(myprog).o
+	$(CXXLINK) $(CXXREP) -o $@ $(myprog).o $(MYLIB) 
+$(myprog).o: $(myprog).cc
+	$(CXXCOMPILE) $(CXXREP) $(MYINC) -o $@ $(myprog).cc
+
Index: /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.cc	(revision 3445)
@@ -0,0 +1,98 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <vector>
+
+#include "pexceptions.h"
+
+#include "histos.h"
+#include "srandgen.h"
+
+#include "geneutils.h"
+#include "agnjackson.h"
+
+namespace SOPHYA {
+
+AGNJackson::AGNJackson(void)
+  : nobjang_(0.) , fluxang_(0.) , dndls_(NULL), tirls_(NULL)
+{
+
+  //--- Les valeurs lues sur la courbe de Jackson (from JIM)
+  const int nval = 10;
+  // log10(S en Jy)
+  double x[nval] = {-7.,-6.,-5.,-4.,-3.,-2.,-1.,0.,1.,2.};
+  // S^2.5*dN/dS (en Jy^1.5 /sr)
+  double y[nval] = {0.0035,0.14,0.95,2.5,7.,50.,260.,300.,150.,100.};
+
+  if(sizeof(x)!=sizeof(y) || sizeof(y)!=8*nval) {
+    cout<<"AGNJackson::AGNJackson_Error: incompatible x,y,nval sizes"<<endl;
+    throw SzMismatchError("AGNJackson::AGNJackson_Error: incompatible x,y,nval sizes");
+  }
+
+  xjack_.resize(0); yjack_.resize(0);
+  for(int i=0;i<nval;i++)
+    {xjack_.push_back(x[i]); yjack_.push_back(y[i]);}
+
+  // On cree l'histo: dndls = dN/dlog10(S) en fct de  log10(S en Jy)
+  int nbin = nval*20;
+  double xmin = x[0], xmax=x[nval-1];
+  dndls_ = new Histo(xmin,xmax,nbin);
+  dndls_->Zero();
+
+  // On remplit les histos
+  // yjack_ = S^2.5 * dN/dS (en Jy^1.5 /sr) en fct de xjack_ = log10(S en Jy)
+  // dndls: dN/dlog10(S)  (en 1/log10(Jy)/sr) en fct de log10(S en Jy)
+  //   avec dN/dlog10(S) = dN/dS * dS/dlog10(S)
+  //                     = (S^2.5*dN/dS)*S^(-2.5) * (ln(10)*S)
+  // On va interpoler en log(dN/dlog10(S)) versus log10(S)
+  vector<double> Y;
+  for(int i=0;i<nval;i++) {
+    double v = yjack_[i]*pow(10.,-1.5*xjack_[i])*M_LN10;
+    Y.push_back(log(v));
+  }
+  for(int i=0;i<nbin;i++) {
+    double lf = dndls_->BinCenter(i);
+    // Interpolation lineaire (parabolic not OK!)
+    double v = InterpTab(lf,xjack_,Y,1);
+    (*dndls_)(i) = exp(v);
+  }
+
+  // On remplit la fonction de tirage
+  tirls_ = new FunRan(*dndls_,true);
+
+  // On calcul le nombre moyen d'AGN et le flux moyen par sr
+  // ATTENTION: dn/dlog10(S) en fct de log10(s)
+  nobjang_ = fluxang_ = 0.;
+  for(int i=0;i<nbin;i++) {
+    double lf = dndls_->BinCenter(i);
+    nobjang_ += (*dndls_)(i);
+    fluxang_ += (*dndls_)(i)*pow(10.,lf);
+  }
+  nobjang_ *= dndls_->BinWidth();
+  fluxang_ *= dndls_->BinWidth();
+
+}
+
+AGNJackson::~AGNJackson(void)
+{
+  if(dndls_!=NULL) delete dndls_;
+  if(tirls_!=NULL) delete tirls_;
+}
+
+void AGNJackson::Print(void)
+{
+  cout<<"AGNJackson::Print: nobj="<<nobjang_
+      <<" /sr, flux="<<fluxang_<<" Jy/sr"<<endl;
+  dndls_->Show();
+}
+
+void AGNJackson::OrigJack(vector<double>& xjack,vector<double>& yjack)
+{
+  xjack = xjack_;
+  yjack = yjack_;
+}
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/agnjackson.h	(revision 3445)
@@ -0,0 +1,39 @@
+#ifndef AGNJACKSON_SEEN
+#define AGNJACKSON_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include "genericfunc.h"
+#include "histos.h"
+#include "perandom.h"
+
+namespace SOPHYA {
+
+//----------------------------------------------------
+// C.A.Jackson (New Astronomy Review 40 (2004) 1187-1193)
+class AGNJackson {
+public:
+  AGNJackson(void);
+  virtual ~AGNJackson(void);
+
+  Histo& dNdlS(void) {return *dndls_;}
+  FunRan& TirL10S(void) {return *tirls_;}
+  double NObjAng(void) {return nobjang_;}
+  double FluxAng(void) {return fluxang_;}
+  double L10FluxJY(void) {return tirls_->Random();}
+  double FluxJY(void) {return pow(10.,L10FluxJY());}
+  void Print(void);
+
+  void OrigJack(vector<double>& xjack,vector<double>& yjack);
+
+protected:
+  vector<double> xjack_,yjack_;
+  double nobjang_,fluxang_;
+  Histo *dndls_;
+  FunRan *tirls_;
+
+};
+
+}  // Fin namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvchkwhu.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvchkwhu.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvchkwhu.cc	(revision 3445)
@@ -0,0 +1,151 @@
+// Check cmv / Wayne Hu coding of the transfert functions
+// ATTENTION: ne pas appeler hu_power.c ici car il ecrase les initialisations de hu_tf_fit.c
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "ntuple.h"
+
+#include "constcosmo.h"
+#include "pkspectrum.h"
+#include "hu_tf_fit.h"
+
+int main(int narg,char *arg[])
+{
+ double k1 = 1e-6, k2 = 10.; int_4 npt = 10000;
+ double h100 = 0.71, Om0 = 0.267804, Ob0 = 0.0444356, tcmb = T_CMB_Par;
+
+ cout<<"k1="<<k1<<"  k2="<<k2<<" npt="<<npt<<endl;
+ cout<<"h100="<<h100<<" Om0="<<Om0<<" Ob0="<<Ob0<<" Tcmb="<<tcmb<<endl;
+ cout<<"Om0*h^2="<<Om0*h100*h100<<" Ob0*h^2="<<Ob0*h100*h100<<endl;
+ double fbaryon = Ob0/Om0;
+ cout<<"fbaryon="<<fbaryon<<endl;
+
+ cout<<endl<<"TFset_parameters"<<endl;
+ TFset_parameters(Om0*h100*h100,fbaryon,tcmb);
+ TFprint_parameters();
+ double soundfithu = TFsound_horizon_fit(Om0,fbaryon,h100)/h100;
+ cout<<"TFsound_horizon_fit = "<<soundfithu<<" Mpc"<<endl;
+
+ cout<<endl<<"TransfertEisenstein with baryon"<<endl;
+ TransfertEisenstein Tfull(h100,Om0-Ob0,Ob0,tcmb,false,1);
+
+ cout<<endl<<"TransfertEisenstein with baryon without oscillation approx.2"<<endl;
+ TransfertEisenstein Tnowig(h100,Om0-Ob0,Ob0,tcmb,false,1);
+ Tnowig.SetNoOscEnv(2);
+
+ cout<<endl<<"TransfertEisenstein without baryon"<<endl;
+ TransfertEisenstein Tnob(h100,Om0,0.,tcmb,true,1);
+
+ cout<<endl<<"Compare kpeak"<<endl;
+ double kpeak = Tfull.KPeak();
+ double kpeakhu = TFk_peak(Om0,fbaryon,h100)*h100;
+ cout<<"kpeak = "<<kpeak<<" "<<kpeakhu<<"  Mpc^-1  -> diff "<<kpeak-kpeakhu<<endl;
+
+ const int n = 11;
+ char *vname[n] = {"k","tf","tfnw","tfnb","tfc","tfb"
+                  ,"hutf","hutfnw","hutfnb","hutfc","hutfb"};
+ NTuple nt(n,vname);
+ double xnt[n];
+
+ double kmax[5]={0,0,0,0,0};
+ double tmax[5]={0.,0.,0.,0.,0.};
+ double lnk1 = log10(k1), lnk2=log10(k2), dlnk=(lnk2-lnk1)/npt;
+ for(double lnk=lnk1;lnk<lnk2+dlnk/2.;lnk+=dlnk) {
+   double k = pow(10.,lnk);
+   //if(fabs(lnk-log10(0.0186209))>1e-5) continue;
+   Tfull.SetReturnPart(TransfertEisenstein::ALL); double tf = Tfull(k);
+   double tfnw = Tnowig(k);
+   double tfnb = Tnob(k);
+   Tfull.SetReturnPart(TransfertEisenstein::CDM); double tfc = Tfull(k);
+   Tfull.SetReturnPart(TransfertEisenstein::BARYON); double tfb = Tfull(k);
+   double hutfc, hutfb;
+   double hutf = TFfit_onek(k,&hutfb,&hutfc); 
+   double hutfnw = TFnowiggles(Om0,fbaryon,h100,tcmb,k/h100);
+   double hutfnb = TFzerobaryon(Om0,h100,tcmb,k/h100);
+
+
+   if(fabs(tf-hutf)>tmax[0])     {kmax[0]=k; tmax[0]=fabs(tf-hutf);}
+   if(fabs(tfnw-hutfnw)>tmax[1]) {kmax[1]=k; tmax[1]=fabs(tfnw-hutfnw);}
+   if(fabs(tfnb-hutfnb)>tmax[2]) {kmax[2]=k; tmax[2]=fabs(tfnb-hutfnb);}
+   if(fabs(tfc-hutfc)>tmax[3])   {kmax[3]=k; tmax[3]=fabs(tfc-hutfc);}
+   if(fabs(tfb-hutfb)>tmax[4])   {kmax[4]=k; tmax[4]=fabs(tfb-hutfb);}
+
+   xnt[0]=k;
+   xnt[1]=tf; xnt[2]=tfnw; xnt[3]=tfnb; xnt[4]=tfc; xnt[5]=tfb;
+   xnt[6]=hutf; xnt[7]=hutfnw; xnt[8]=hutfnb; xnt[9]=hutfc; xnt[10]=hutfb;
+   nt.Fill(xnt);
+ }
+
+ cout<<"Maximum difference for:"<<endl;
+ cout<<"tf:   "<<tmax[0]<<"  for k="<<kmax[0]<<endl;
+ cout<<"tfnw: "<<tmax[1]<<"  for k="<<kmax[1]<<endl;
+ cout<<"tfnb: "<<tmax[2]<<"  for k="<<kmax[2]<<endl;
+ cout<<"tfc:  "<<tmax[3]<<"  for k="<<kmax[3]<<endl;
+ cout<<"tfb:  "<<tmax[4]<<"  for k="<<kmax[4]<<endl;
+
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvchkwhu.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+
+ return 0;
+}
+
+/*
+openppf cmvchkwhu.ppf
+
+set k k
+set k log10(k)
+
+######################
+zone 3 1
+n/plot nt.tf%$k ! ! "nsta connectpoints"
+n/plot nt.hutf%$k ! ! "nsta connectpoints red same"
+n/plot nt.tfc%$k ! ! "nsta connectpoints"
+n/plot nt.hutfc%$k ! ! "nsta connectpoints red same"
+n/plot nt.tfb%$k ! ! "nsta connectpoints"
+n/plot nt.hutfb%$k ! ! "nsta connectpoints red same"
+zone 2 1
+n/plot nt.tfnw%$k ! ! "nsta connectpoints"
+n/plot nt.hutfnw%$k ! ! "nsta connectpoints red same"
+n/plot nt.tfnb%$k ! ! "nsta connectpoints"
+n/plot nt.hutfnb%$k ! ! "nsta connectpoints red same"
+
+######################
+zone 3 1
+n/plot nt.tf-hutf%$k ! ! "nsta connectpoints"
+n/plot nt.tfc-hutfc%$k ! ! "nsta connectpoints"
+n/plot nt.tfb-hutfb%$k ! ! "nsta connectpoints"
+zone 2 1
+n/plot nt.tfnw-hutfnw%$k ! ! "nsta connectpoints"
+n/plot nt.tfnb-hutfnb%$k ! ! "nsta connectpoints"
+
+zone 3 1
+n/plot nt.(tf-hutf)/hutf%$k ! ! "nsta connectpoints"
+n/plot nt.(tfc-hutfc)/hutfc%$k ! ! "nsta connectpoints"
+n/plot nt.(tfb-hutfb)/hutfb%$k ! ! "nsta connectpoints"
+zone 2 1
+n/plot nt.(tfnw-hutfnw)/hutfnw%$k ! ! "nsta connectpoints"
+n/plot nt.(tfnb-hutfnb)/hutfnb%$k ! ! "nsta connectpoints"
+
+######################
+zone
+n/plot nt.tf%$k ! ! "nsta connectpoints"
+n/plot nt.tfnw%$k ! ! "nsta connectpoints red same"
+n/plot nt.tfnb%$k ! ! "nsta connectpoints blue same"
+
+zone
+n/plot nt.tf/tfnw%$k tfnw>0. ! "nsta connectpoints"
+n/plot nt.hutf/hutfnw%$k hutfnw>0. ! "nsta connectpoints same blue"
+addline -1000 1 1000 1 "red"
+
+zone
+n/plot nt.tf/tfnb%$k tfnb>0. ! "nsta connectpoints"
+n/plot nt.hutf/hutfnb%$k hutfnb>0. ! "nsta connectpoints same blue"
+addline -1000 1 1000 1 "red"
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvconcherr.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvconcherr.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvconcherr.cc	(revision 3445)
@@ -0,0 +1,381 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "histerr.h"
+#include "hist2err.h"
+#include "fitshisterr.h"
+
+int ObjectType(string nameh,string nameppf);
+int ConcatHistoErr(string nameh,vector<string> ppfname,int wrtyp=2,bool do_cov=false);
+int ConcatHisto2DErr(string nameh,vector<string> ppfname,int wrtyp=2,int ibinkt=-1,int ibinkz=-1);
+void usage(void);
+void usage(void)
+{
+cout
+<<"cmvconcherr -w wtyp -n name_histoerr file1.ppf file2.ppf ..."<<endl
+<<"  name_histoerr: object name"<<endl
+<<"  wtyp: bit0 write ASCII, bit1 write PPF, bit2 write FITS (all=7)"<<endl
+<<"  -C : compute covariance for 1D spectrum"<<endl
+<<"  -Z ibinKt : compute covariance of line Pk(ibinKt,.) along Kz for 2D"<<endl
+<<"  -T ibinKz : compute covariance of line Pk(.,ibinKz) along Kt for 2D"<<endl
+<<endl;
+}
+
+
+//---------------------------------------------------------------
+int main(int narg,char *arg[])
+{
+ // "hpkgen"  "hpkgenfb"  "hpkgenf"  "hpkrecb"  "hpkrec"
+ // "hpkgen2" "hpkgenfb2" "hpkgenf2" "hpkrecb2" "hpkrec2"
+ string nameh = "";
+ vector<string> ppfname;
+ int Write_Type = 2;
+ bool Do_Cov = false;
+ int ibinKt=-1, ibinKz=-1;
+
+ // --- Decodage arguments
+ char c;
+ while((c = getopt(narg,arg,"hCn:w:Z:T:")) != -1) {
+  switch (c) {
+  case 'n' :
+    nameh = optarg;
+    break;
+  case 'w' :
+    sscanf(optarg,"%d",&Write_Type);
+    break;
+  case 'C' :
+    Do_Cov = true;
+    break;
+  case 'Z' :
+    sscanf(optarg,"%d",&ibinKt);
+    break;
+  case 'T' :
+    sscanf(optarg,"%d",&ibinKz);
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+ if(nameh.size()<=0 || optind>=narg) {usage(); return -1;}
+ for (int i=optind;i<narg;i++) ppfname.push_back(arg[i]);
+ cout<<"nameh = "<<nameh
+     <<" , number of file to be read = "<<ppfname.size()
+     <<" , write_type="<<Write_Type<<" , cov="<<Do_Cov<<endl;
+
+ // --- Quel type d'objet ?
+ int obtyp = ObjectType(nameh,ppfname[0]);
+
+ // --- lecture et moyenne des HistoErr ou Histo2DErr
+ int nread=0;
+ if(obtyp==1) nread = ConcatHistoErr(nameh,ppfname,Write_Type,Do_Cov);
+ else if(obtyp==2) nread = ConcatHisto2DErr(nameh,ppfname,Write_Type,ibinKt,ibinKz);
+ else {
+   cout<<"Type of object "<<nameh<<" not decoded"<<endl;
+   return -1;
+ }
+ cout<<"Number of file read: "<<nread<<endl;
+ return 0;
+}
+
+//---------------------------------------------------------------
+int ObjectType(string nameh,string nameppf)
+// retourne: 1 si HistoErr
+//           2 si Histo2DErr,
+//           0 si autre objet
+//          -1 si il n'y a pas d'objet de nom "nameh"
+{
+ PInPersist pis(nameppf.c_str());
+
+ bool found_tag = pis.GotoNameTag(nameh.c_str());
+ if(!found_tag) return -1;
+
+ PPersist *pps = pis.ReadObject();
+ AnyDataObj *obj = pps->DataObj();
+ cout<<"Object type read from input PPF file : "<<typeid(*obj).name()<< endl;
+
+ HistoErr *herr = dynamic_cast<HistoErr *>(obj);
+ if(herr) return 1;
+
+ Histo2DErr *herr2 = dynamic_cast<Histo2DErr *>(obj);
+ if(herr2) return 2;
+
+ return 0;
+}
+
+//---------------------------------------------------------------
+int ConcatHistoErr(string nameh,vector<string> ppfname,int wrtyp,bool do_cov)
+{
+ if(ppfname.size()<=0) return 0;
+
+ HistoErr *herrconc = NULL;
+ TVector<r_8> Tsum; TMatrix<r_8> Tsum2;
+ int nherr=0, nread=0, itest=0;
+ double sum=0., sum2=0., nsum=0;
+ for (unsigned int ifile=0;ifile<ppfname.size();ifile++) {
+   PInPersist pis(ppfname[ifile].c_str());
+   HistoErr herr;
+   pis.GetObject(herr,nameh);
+   cout<<ifile<<" : "<<ppfname[ifile]<<"  nbin="<<herr.NBins()<<endl;
+
+   if(ifile==0) { 
+     herrconc = new HistoErr(herr.XMin(),herr.XMax(),herr.NBins());
+     nherr = herr.NBins();
+     itest = int(herrconc->NBins()/5.+0.5);
+     if(do_cov) {Tsum.ReSize(nherr); Tsum=0.; Tsum2.ReSize(nherr,nherr); Tsum2=0.;}
+   } else if(nherr!=herr.NBins()) {
+     cout<<"BAD NUMBER OF BINS"<<endl;
+     continue;
+   }
+
+   if(herr.NMean()!=1) cout<<"ATTENTION: file="<<ppfname[ifile]
+                           <<" nmean="<<herr.NMean()<<endl;
+   nread++;
+   for(int i=0;i<nherr;i++) herrconc->AddBin(i,herr(i));
+   sum+=herr(itest); sum2+=herr(itest)*herr(itest); nsum++;
+
+   if(do_cov) {
+     for(int i=0;i<nherr;i++) {
+       Tsum(i) += herr(i);
+       for(int j=0;j<nherr;j++) Tsum2(i,j) += herr(i)*herr(j);
+     }
+   }
+
+ }
+ herrconc->ToVariance();
+ if(nsum>0) {sum/=nsum; sum2/=nsum; sum2-=sum*sum;}
+ cout<<"Test bin "<<itest<<" mean="<<sum<<" sigma^2="<<sum2<<"  nsum="<<nsum<<endl;
+ cout<<"         "<<" mean="<<(*herrconc)(itest)
+                  <<" sigma^2="<<herrconc->Error2(itest)<<endl;
+
+ // --- Covariance
+ if(do_cov && nread>1) {
+   Tsum /= nread;
+   Tsum2 /= nread;
+   for(int i=0;i<nherr;i++)
+     for(int j=0;j<nherr;j++) Tsum2(i,j) -= Tsum(i)*Tsum(j);
+ }
+
+ // --- ecriture
+ if(wrtyp&1) {   // ecriture ASCII
+   string asname = "cmvconcherr.data";
+   herrconc->WriteASCII(asname);
+ }
+ if(wrtyp&2 || do_cov) {   // ecriture PPF
+   string tagobs = "cmvconcherr.ppf";
+   POutPersist posobs(tagobs);
+   tagobs = "herrconc"; posobs.PutObject(*herrconc,tagobs);
+   if(do_cov) {
+     tagobs = "mean"; posobs.PutObject(Tsum,tagobs);
+     tagobs = "cov"; posobs.PutObject(Tsum2,tagobs);
+   }
+ }
+ if(wrtyp&4) {   // ecriture FITS
+   FitsInOutFile fio("!cmvconcherr.fits",FitsInOutFile::Fits_Create);
+   fio << *herrconc;
+ }
+
+ delete herrconc;
+
+ return nread;
+}
+
+//---------------------------------------------------------------
+int ConcatHisto2DErr(string nameh,vector<string> ppfname,int wrtyp,int ibinkt,int ibinkz)
+{
+ if(ppfname.size()<=0) return 0;
+
+ Histo2DErr *herrconc = NULL;
+ TVector<r_8> Tsum_kz; TMatrix<r_8> Tsum2_kz;
+ TVector<r_8> Tsum_kt; TMatrix<r_8> Tsum2_kt;
+ int nherrx=0, nherry=0, nread=0, itestx=0, itesty=0;
+ double sum=0., sum2=0., nsum=0;
+ for (unsigned int ifile=0;ifile<ppfname.size();ifile++) {
+   PInPersist pis(ppfname[ifile].c_str());
+   Histo2DErr herr;
+   pis.GetObject(herr,nameh);
+   cout<<ifile<<" : "<<ppfname[ifile]<<"  nbin="
+       <<herr.NBinX()<<","<<herr.NBinY()<<endl;
+
+   if(ifile==0) { 
+     herrconc = new Histo2DErr(herr.XMin(),herr.XMax(),herr.NBinX()
+                              ,herr.YMin(),herr.YMax(),herr.NBinY());
+     nherrx = herr.NBinX(); nherry = herr.NBinY();
+     itestx = int(herrconc->NBinX()/5.+0.5);
+     itesty = int(herrconc->NBinY()/5.+0.5);
+     if(ibinkt>=0) { // matrix de covariance pour une ligne Kz
+       if(ibinkt>=nherrx) ibinkt = nherrx-1;
+       Tsum_kz.ReSize(nherry); Tsum_kz=0.;
+       Tsum2_kz.ReSize(nherry,nherry); Tsum2_kz=0.;
+     }
+     if(ibinkz>=0) { // matrix de covariance pour une ligne Kt
+       if(ibinkz>=nherry) ibinkz = nherry-1;
+       Tsum_kt.ReSize(nherrx); Tsum_kt=0.;
+       Tsum2_kt.ReSize(nherrx,nherrx); Tsum2_kt=0.;
+     }
+   } else if(nherrx!=herr.NBinX() || nherry!=herr.NBinY()) {
+     cout<<"BAD NUMBER OF BINS"<<endl;
+     continue;
+   }
+
+   if(herr.NMean()!=1) cout<<"ATTENTION: file="<<ppfname[ifile]
+                           <<" nmean="<<herr.NMean()<<endl;
+   nread++;
+   for(int i=0;i<nherrx;i++)
+     for(int j=0;j<nherry;j++) herrconc->AddBin(i,j,herr(i,j));
+   sum+=herr(itestx,itesty); sum2+=herr(itestx,itesty)*herr(itestx,itesty); nsum++;
+
+   if(ibinkt>=0) {
+     for(int i=0;i<Tsum_kz.Size();i++) {
+       Tsum_kz(i) += herr(ibinkt,i);
+       for(int j=0;j<Tsum_kz.Size();j++) Tsum2_kz(i,j) += herr(ibinkt,i)*herr(ibinkt,j);
+     }
+   }
+
+   if(ibinkz>=0) {
+     for(int i=0;i<Tsum_kt.Size();i++) {
+       Tsum_kt(i) += herr(i,ibinkz);
+       for(int j=0;j<Tsum_kt.Size();j++) Tsum2_kt(i,j) += herr(i,ibinkz)*herr(j,ibinkz);
+     }
+   }
+
+ }
+ herrconc->ToVariance();
+ if(nsum>0) {sum/=nsum; sum2/=nsum; sum2-=sum*sum;}
+ cout<<"Test bin "<<itestx<<","<<itesty
+     <<" mean="<<sum<<" sigma^2="<<sum2<<"  nsum="<<nsum<<endl;
+ cout<<"         "<<" mean="<<(*herrconc)(itestx,itesty)
+                  <<" sigma^2="<<herrconc->Error2(itestx,itesty)<<endl;
+
+ // --- Covariance
+ if(ibinkt>=0 && nread>1) {
+   Tsum_kz /= nread;
+   Tsum2_kz /= nread;
+   for(int i=0;i<Tsum_kz.Size();i++)
+     for(int j=0;j<Tsum_kz.Size();j++) Tsum2_kz(i,j) -= Tsum_kz(i)*Tsum_kz(j);
+ }
+ if(ibinkz>=0 && nread>1) {
+   Tsum_kt /= nread;
+   Tsum2_kt /= nread;
+   for(int i=0;i<Tsum_kt.Size();i++)
+     for(int j=0;j<Tsum_kt.Size();j++) Tsum2_kt(i,j) -= Tsum_kt(i)*Tsum_kt(j);
+ }
+
+ // --- ecriture
+ if(wrtyp&1) {   // ecriture ASCII
+   string asname = "cmvconcherr2.data";
+   herrconc->WriteASCII(asname);
+ }
+ if(wrtyp&2) {   // ecriture PPF
+   string tagobs = "cmvconcherr2.ppf";
+   POutPersist posobs(tagobs);
+   tagobs = "herrconc2"; posobs.PutObject(*herrconc,tagobs);
+   if(ibinkt>=0) {
+     char str[32];
+     sprintf(str,"kzm%d",ibinkt);
+     posobs.PutObject(Tsum_kz,str);
+     sprintf(str,"kzc%d",ibinkt);
+     posobs.PutObject(Tsum2_kz,str);
+   }
+   if(ibinkz>=0) {
+     char str[32];
+     sprintf(str,"ktm%d",ibinkz);
+     posobs.PutObject(Tsum_kt,str);
+     sprintf(str,"ktc%d",ibinkz);
+     posobs.PutObject(Tsum2_kt,str);
+   }
+ }
+ if(wrtyp&4) {   // ecriture FITS
+   FitsInOutFile fio("!cmvconcherr2.fits",FitsInOutFile::Fits_Create);
+   fio << *herrconc;
+ }
+
+ delete herrconc;
+
+ return nread;
+}
+
+/*
+####
+#### HistoErr 1D
+####
+openppf cmvconcherr.ppf
+
+c++exec int i = 700; \
+cout<<i<<" "<<herrconc.BinCenter(i)<<" "<<herrconc(i)<<" "<<herrconc.Error2(i)<<" "<<herrconc.NEntBin(i)<<endl;
+
+zone 2 2
+disp herrconc "hbincont err"
+disp herrconc "hbinerr"
+disp herrconc "hbinent"
+
+zone
+n/plot herrconc.val%log10(x) x>0 ! "connectpoints"
+n/plot herrconc.val-sqrt(err2)%log10(x) x>0&&err2>0 ! "connectpoints same red"
+n/plot herrconc.val+sqrt(err2)%log10(x) x>0&&err2>0 ! "connectpoints same red"
+
+n/plot herrconc.sqrt(err2)%log10(x) x>0&&err2>0 ! "connectpoints same red"
+n/plot herrconc.sqrt(err2)/val%log10(x) x>0&&err2>0&&val>0 ! "connectpoints"
+
+disp mean
+imag cov
+
+del cor
+c++exec \
+TMatrix<r_8> cor(cov,false); cor = 0.; \
+for(int i=0;i<cor.NRows();i++) { \
+  for(int j=0;j<cor.NCols();j++) { \
+    double v = cov(i,i)*cov(j,j); \
+    if(v<=0.) continue; \
+    cor(i,j) = cov(i,j)/sqrt(v); \
+} } \
+KeepObj(cor); \
+cout<<"Matrice cor cree "<<endl;
+
+imag cor
+n/plot cor.val%c r==500 ! "connectpoints"
+
+####
+#### Histo2DErr 2D
+####
+openppf cmvconcherr2.ppf
+
+zone 2 2
+imag herrconc2 "hbincont"
+imag herrconc2 "hbinerr"
+imag herrconc2 "hbinent"
+
+zone
+
+set mean kzm140
+set cov kzc140
+
+set mean ktm32
+set cov ktc32
+
+n/plot $mean.val%n ! ! "connectpoints"
+disp $cov
+n/plot $cov.val%c r==32 ! "connectpoints"
+
+set cor ${cov}cor
+del $cor
+c++exec \
+TMatrix<r_8> $cor($cov,false); $cor = 0.; \
+for(int i=0;i<$cor.NRows();i++) { \
+  for(int j=0;j<$cor.NCols();j++) { \
+    double v = $cov(i,i)*$cov(j,j); \
+    if(v<=0.) continue; \
+    $cor(i,j) = $cov(i,j)/sqrt(v); \
+} } \
+KeepObj($cor); \
+cout<<"Matrice cor cree "<<endl;
+
+disp $cor
+n/plot $cor.val%c r==32 ! "connectpoints"
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvdefsurv.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvdefsurv.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvdefsurv.cc	(revision 3445)
@@ -0,0 +1,869 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include <vector>
+
+#include "constcosmo.h"
+#include "cosmocalc.h"
+#include "geneutils.h"
+#include "schechter.h"
+#include "pkspectrum.h"
+#include "planckspectra.h"
+
+/* --- Check Peterson at al. astro-ph/0606104 v1  (pb facteur sqrt(2) sur S/N !)
+cmvdefsurv -U 0.75,0.3,0.7,-1,1 -V 300 -z 0.0025,0.2,Z -x 1,90,A -O 400000,6000 -N 75 -M 6.156e9 -F 3 -2 1.5
+ --- */
+
+//-----------------------------------------------------------------------------------------------------------
+inline double rad2deg(double trad) {return trad/M_PI*180.;}
+inline double rad2min(double trad) {return trad/M_PI*180.*60.;}
+inline double rad2sec(double trad) {return trad/M_PI*180.*3600.;}
+inline double deg2rad(double tdeg) {return tdeg*M_PI/180.;}
+inline double min2rad(double tmin) {return tmin*M_PI/(180.*60.);}
+inline double sec2rad(double tsec) {return tsec*M_PI/(180.*3600.);}
+
+inline double sr2deg2(double asr) {return asr*pow(rad2deg(1.),2.);}
+inline double sr2min2(double asr) {return asr*pow(rad2min(1.),2.);}
+inline double deg22sr(double adeg) {return adeg*pow(deg2rad(1.),2.);}
+inline double min22sr(double amin) {return amin*pow(min2rad(1.),2.);}
+
+double LargeurDoppler(double v /* km/s */, double nu);
+double DzFrV(double v /* km/s */, double zred);
+double DNuFrDz(double dzred,double nu_at_0,double zred);
+double DzFrDNu(double dnu_at_0,double nu_at_0,double zred);
+double DzFrDNuApprox(double dnu_at_0,double nu_at_0,double zred);
+double ZFrLos(double loscom /* Mpc com */,CosmoCalc& univ);
+double AngsolEqTelescope(double nu /* GHz */,double telsurf /* m^2 */);
+void usage(void);
+
+void usage(void) {
+  cout<<"cmvdefsurv [options] -x dx,txlarg[,unit_x] -y dy,tylarg[,unit_y] -z dz,tzlarg[,unit_z] redshift"<<endl
+      <<"----------------"<<endl
+      <<" -x dx,txlarg[,unit_x] : resolution et largeur dans le plan transverse selon X"<<endl
+      <<" -y dy,tylarg[,unit_y] : idem selon Y, si <=0 meme que X"<<endl
+      <<" -z dz,tzlarg[,unit_z] : resolution et largeur sur la ligne de visee"<<endl
+      <<"-- Unites pour X-Y:"<<endl
+      <<"   \'A\' : en angles (pour X-Y)  : resolution=ArcMin, largeur=Degre (defaut)"<<endl
+      <<"   \'Z\' : en redshift (pour Z)  : resolution et largeur en redshift (defaut)"<<endl
+      <<"   \'F\' : en frequence (pour Z) : resolution et largeur MHz"<<endl
+      <<"   \'M\' : en longeur comobile (pour X-Y-Z) : resolution et largeur Mpc"<<endl
+      <<"----------------"<<endl
+      <<" -K k,dk,pk : k(Mpc^-1) dk(Mpc^-1) pk(a z=0 en Mpc^-3) pour estimer la variance cosmique"<<endl
+      <<"----------------"<<endl
+      <<" -O surf,tobs,eta : surface effective (m^2), temps d\'observation (s), efficacite d\'ouverture"<<endl
+      <<" -N Tsys : temperature du system (K)"<<endl
+      <<" -L lobearea,freqlob : angle solide du lobe d\'observation en arcmin^2 (def= celle du pixel)"<<endl
+      <<"                       pour la frequence freqlob en MHz"<<endl
+      <<"            Si freqlob<=0 : la frequence de reference est celle du redshift etudie (def)"<<endl
+      <<" -2 : two polarisations measured"<<endl
+      <<" -M  : masse de HI de reference (MSol), si <=0 mean schechter in pixel"<<endl
+      <<" -F  : HI flux factor to be applied for our redshift"<<endl
+      <<" -V Vrot : largeur en vitesse (km/s) pour l\'elargissement doppler (def=300km/s)"<<endl
+      <<"----------------"<<endl
+      <<" -S Tsynch,indnu : temperature (K) synch a 408 Mhz, index d\'evolution"<<endl
+      <<"                   (indnu==0 no evolution with freq.)"<<endl
+      <<"----------------"<<endl
+      <<" -U h100,om0,ol0,w0,or0,flat : cosmology"<<endl
+      <<"----------------"<<endl
+      <<" -A <log10(S_agn)> : moyenne du flux AGN en Jy dans le pixel"<<endl
+      <<" redshift : redshift moyen du survey"<<endl
+      <<endl;
+}
+
+//-------------------------------------------------------------------------------------------
+int main(int narg,char *arg[])
+{
+ // --- 
+ // --- Valeurs fixes ou par defaut
+ // --- 
+
+ //-- WMAP
+ unsigned short flat = 0;
+ double h100=0.71, om0=0.267804, or0=7.9e-05*0., ol0=0.73,w0=-1.;
+
+ //-- Schechter HIMASS
+ double h75 = h100 / 0.75;
+ double nstar = 0.006*pow(h75,3.);  //
+ double mstar = pow(10.,9.8);  // MSol
+ double alpha = -1.37;
+ cout<<"nstar= "<<nstar<<"  mstar="<<mstar<<"  alpha="<<alpha<<endl;
+
+ double hifactor = 1.;
+ double vrot = 300.; // largeur en vitesse (km/s) pour elargissement doppler
+
+ //-- CMB , Synchrotron et AGN
+ double tcmb = T_CMB_Par;
+ // a 408 MHz (Haslam) + evol index a -2.6
+ double Tsynch408=60., nuhaslam=0.408, indnu = -2.6;
+ double lflux_agn = -3.;
+
+ //-- Appareillage
+ bool ya2polar = false;
+ double facpolar = 0.5; // si on mesure les 2 polars -> 1.0
+ double Tsys=75.;
+ double tobs = 6000., surftot = 400000., eta_eff  = 1.;
+ // taille du lobe d'observation en arcmin pour la frequence
+ double lobearea0 = -1., lobefreq0 = -1.;
+
+ //-- Variance cosmique (default = standard SDSSII)
+ double kcosm = 0.05, dkcosm = -1., pkcosm = 40000.;
+
+ // --- Pour taille du survey
+ double dx=0., dy=-1., dz=0., txlarg=0., tylarg=-1., tzlarg=0.;
+ int nx=0, ny=0, nz=0;
+ char unit_x = 'A', unit_y = 'A', unit_z = 'Z';
+ double redshift0 = 0.;
+ double mhiref = -1.; // reference Mass en HI (def integ schechter)
+
+ // --- 
+ // --- Decodage arguments
+ // --- 
+ char c;
+  while((c = getopt(narg,arg,"h2x:y:z:N:S:O:M:F:V:U:L:A:K:")) != -1) {
+  switch (c) {
+  case 'x' :
+    sscanf(optarg,"%lf,%lf,%c",&dx,&txlarg,&unit_x);
+    break;
+  case 'y' :
+    sscanf(optarg,"%lf,%lf,%c",&dy,&tylarg,&unit_y);
+    break;
+  case 'z' :
+    sscanf(optarg,"%lf,%lf,%c",&dz,&tzlarg,&unit_z);
+    break;
+  case 'O' :
+    sscanf(optarg,"%lf,%lf,%lf",&surftot,&tobs,&eta_eff);
+    break;
+  case 'L' :
+    sscanf(optarg,"%lf,%lf",&lobearea0,&lobefreq0);
+    break;
+  case 'N' :
+    sscanf(optarg,"%lf",&Tsys);
+    break;
+  case 'S' :
+    sscanf(optarg,"%lf,%lf",&Tsynch408,&indnu);
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf",&mhiref);
+    break;
+  case 'F' :
+    sscanf(optarg,"%lf",&hifactor);
+    break;
+  case 'V' :
+    sscanf(optarg,"%lf",&vrot);
+    break;
+  case 'U' :
+    sscanf(optarg,"%lf,%lf,%lf,%lf,%hu",&h100,&om0,&ol0,&w0,&flat);
+    break;
+  case '2' :
+    ya2polar = true;
+    facpolar = 1.0;
+    break;
+  case 'A' :
+    sscanf(optarg,"%lf",&lflux_agn);
+    break;
+  case 'K' :
+    sscanf(optarg,"%lf,%lf,%lf",&kcosm,&dkcosm,&pkcosm);
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ } 
+ if(optind>=narg) {usage(); return -1;}
+ sscanf(arg[optind],"%lf",&redshift0);
+ if(redshift0<=0.) {cout<<"Redshift "<<redshift0<<" should be >0"<<endl; return -2;}
+
+ // --- 
+ // --- Initialisation de la Cosmologie
+ // --- 
+ CosmoCalc univ(flat,true,2.*redshift0);
+ double perc=0.01,dzinc=redshift0/100.,dzmax=dzinc*10.; unsigned short glorder=4;
+ univ.SetInteg(perc,dzinc,dzmax,glorder);
+ univ.SetDynParam(h100,om0,or0,ol0,w0);
+
+ GrowthFactor growth(om0,ol0);
+
+ // --- 
+ // --- Mise en forme dans les unites appropriees
+ // --- 
+ // ATTENTION: le cube de simulation est en Mpc avec des pixels de taille comobile fixe
+ cout<<"\n>>>>\n>>>> Geometrie\n>>>>"<<endl;
+ if(dy<=0. || tylarg<=0.) {dy=dx; tylarg=txlarg; unit_y=unit_x;}
+ cout<<"X values: resolution="<<dx<<" largeur="<<txlarg<<" unite="<<unit_x<<endl;
+ if(unit_x == 'A') {
+   nx = int(txlarg*60./dx+0.5);
+   dx = min2rad(dx)*univ.Dtrcom(redshift0);
+   txlarg = dx*nx;
+ } else if(unit_x == 'M') {
+   nx = int(txlarg/dx+0.5);
+   txlarg = dx*nx;
+ } else {
+   cout<<"Unknown unit_x = "<<unit_x<<endl; return -2;
+ }
+ cout<<"Y values: resolution="<<dy<<" largeur="<<tylarg<<" unite="<<unit_y<<endl;
+ if(unit_y == 'A') {
+   ny = int(tylarg*60./dy+0.5);
+   dy = min2rad(dy)*univ.Dtrcom(redshift0);
+   tylarg = dy*ny;
+ } else if(unit_y == 'M') {
+   ny = int(tylarg/dy+0.5);
+   tylarg = dy*ny;
+ } else {
+   cout<<"Unknown unit_y = "<<unit_y<<endl; return -2;
+ }
+ cout<<"Z values: resolution="<<dz<<" largeur="<<tzlarg<<" unite="<<unit_z<<endl;
+ if(unit_z == 'Z') {
+   nz = int(tzlarg/dz+0.5);
+   dz = dz*univ.Dhubble()/univ.E(redshift0);
+   tzlarg = dz*nz;
+ } else if(unit_z == 'M') {
+   nz = int(tzlarg/dz+0.5);
+   tzlarg = dz*nz;
+ } else if(unit_z == 'F') { // unite en MHz
+   nz = int(tzlarg/dz+0.5);
+   dz = DzFrDNu(dz,Fr_HyperFin_Par*1.e3,redshift0);  //dzred
+   dz = dz*univ.Dhubble()/univ.E(redshift0);
+   tzlarg = dz*nz;
+ } else {
+   cout<<"Unknown unit_z = "<<unit_z<<endl; return -2;
+ }
+
+ // --- 
+ // --- Calcul des valeurs au centre du cube et aux faces limites av/ar
+ // --- 
+ cout<<"\n>>>>\n>>>> Cosmologie generale\n>>>>"<<endl;
+ double adtx[3], adty[3], atxlarg[3], atylarg[3];
+ double loscom[3], redshift[3], unplusz[3], dred[3], growthfac[3], rhocz[3];
+ double dang[3], dtrcom[3], dlum[3], dloscom[3], dlosdz[3];
+ double nuhiz[3], lambdahiz[3], dnuhiz[3];
+ double angsol_pix[3], angsol_tot[3];
+
+ redshift[0] = redshift0;
+ loscom[0] = univ.Dloscom(redshift0);
+ loscom[1] = loscom[0]-tzlarg/2.;
+ loscom[2] = loscom[0]+tzlarg/2.;
+ //if(loscom[1]<=0.) {cout<<"Lower distance limit "<<loscom[1]<<" should be >0"<<endl; return -3;}
+ for(int i=0;i<3;i++) {
+   double l = loscom[i]; if(l<=0.) l = dz/2.;
+   redshift[i]  = ZFrLos(l,univ);
+   unplusz[i]   = 1. + redshift[i];
+   growthfac[i] = growth(redshift[i]);
+   rhocz[i]     = univ.Rhoc(redshift[i])*GCm3toMsolMpc3_Cst;;
+   dang[i]      = univ.Dang(redshift[i]);
+   dtrcom[i]    = univ.Dtrcom(redshift[i]);
+   dlum[i]      = univ.Dlum(redshift[i]);
+   dloscom[i]   = univ.Dloscom(redshift[i]);
+   dlosdz[i]    = univ.Dhubble()/univ.E(redshift[i]);
+   dred[i]      = dz/dlosdz[i];
+   adtx[i]      = dx/dtrcom[i];
+   atxlarg[i]   = adtx[i]*nx;
+   adty[i]      = dy/dtrcom[i];
+   atylarg[i]   = adty[i]*ny;
+   nuhiz[i]     = Fr_HyperFin_Par / unplusz[i];  // GHz
+   lambdahiz[i] = SpeedOfLight_Cst*1000./(nuhiz[i]*1.e9);  // m
+   dnuhiz[i]    = DNuFrDz(dred[i],Fr_HyperFin_Par,redshift[i]);  // GHz
+   angsol_pix[i] = AngSol(adtx[i]/2.,adty[i]/2.,M_PI/2.);
+   angsol_tot[i] = AngSol(atxlarg[i]/2.,atylarg[i]/2.,M_PI/2.);
+ }
+ 
+
+ cout<<"--- Cosmology for z = "<<0.<<endl;
+ univ.Print(0.);
+ double rhoc0 = univ.Rhoc(0.)*GCm3toMsolMpc3_Cst;
+
+ for(int i=0;i<3;i++) {
+   cout<<"\n--- Cosmology for z = "<<redshift[i]<<endl;
+   univ.Print(redshift[i]);
+ }
+
+ cout<<endl;
+ cout<<"Facteur de croissance lineaire = "<<growthfac[0]
+     <<" in ["<<growthfac[1]<<","<<growthfac[2]<<"]"<<endl;
+ cout<<"                       1/(1+z) = "<<1./(1.+redshift[0])
+     <<" in ["<<1./(1.+redshift[1])<<","<<1./(1.+redshift[2])<<"]"<<endl;
+ cout<<"Facteur de croissance lineaire^2 = "<<growthfac[0]*growthfac[0]
+     <<" in ["<<growthfac[1]*growthfac[1]<<","<<growthfac[2]*growthfac[2]<<"]"<<endl;
+
+ cout<<"Rho_c (z=0) =  "<<rhoc0<<", a z="<<0<<": "<<rhoc0<<" Msol/Mpc^3"<<endl;
+ cout<<"Rho_c a z = "<<rhocz[0]
+     <<" Msol/Mpc^3 in ["<<rhocz[1]<<","<<rhocz[2]<<"]"<<endl;
+
+ cout<<endl;
+ cout<<"dang= "<<dang[0]<<" Mpc in ["<<dang[1]<<","<<dang[2]<<"]"<<endl;
+ cout<<"dtrcom= "<<dtrcom[0]<<" Mpc com in ["<<dtrcom[1]<<","<<dtrcom[2]<<"]"<<endl;
+ cout<<"dlum= "<<dlum[0]<<" Mpc in ["<<dlum[1]<<","<<dlum[2]<<"]"<<endl;
+ cout<<"dloscom= "<<dloscom[0]<<" Mpc com in ["<<dloscom[1]<<","<<dloscom[2]<<"]"<<endl;
+ cout<<"dz=1 -> dlosdz= "<<dlosdz[0]<<" Mpc com in ["<<dlosdz[1]<<","<<dlosdz[2]<<"]"<<endl;
+ cout<<"1 Mpc los com -> dz = "<<1./dlosdz[0]<<" in ["<<1./dlosdz[1]<<","<<1./dlosdz[2]<<"]"<<endl;
+
+ cout<<endl;
+ for(int i=0;i<3;i++) {
+   cout<<"...Redshift="<<redshift[i]<<endl;
+   cout<<"1\" -> "<<dang[i]*sec2rad(1.)<<" Mpc = "<<dtrcom[i]*sec2rad(1.)<<" Mpc com"<<endl;
+   cout<<"1\' -> "<<dang[i]*min2rad(1.)<<" Mpc = "<<dtrcom[i]*min2rad(1.)<<" Mpc com"<<endl;
+   cout<<"1d -> "<<dang[i]*deg2rad(1.)<<" Mpc = "<<dtrcom[i]*deg2rad(1.)<<" Mpc com"<<endl;
+   cout<<"1 Mpc transv com -> "<<rad2sec(1./dtrcom[i])<<"\" = "
+       <<rad2min(1./dtrcom[i])<<" \' = "<<rad2deg(1./dtrcom[i])<<" d"<<endl;
+   cout<<"dz=1 -> dlosdz= "<<dlosdz[i]<<" Mpc com"<<endl;
+   cout<<"1 Mpc los com -> dz = "<<1./dlosdz[0]<<endl;
+ }
+
+ // --- 
+ // --- Cosmolographie Transverse
+ // --- 
+ cout<<"\n>>>>\n>>>> Cosmologie & Geometrie transverse\n>>>>"<<endl;
+
+ cout<<"dx = "<<dx<<", txlarg = "<<txlarg<<" Mpc (com), nx="<<nx<<endl;
+ cout<<"adtx = "<<adtx[0]<<" rd in ["<<adtx[1]<<","<<adtx[2]<<"]"<<endl;
+ cout<<"     = "<<rad2min(adtx[0])<<"\' in ["<<rad2min(adtx[1])<<","<<rad2min(adtx[2])<<"]"<<endl;
+ cout<<"atxlarg = "<<atxlarg[0]<<" rd in ["<<atxlarg[1]<<","<<atxlarg[2]<<"]"<<endl;
+ cout<<"          "<<rad2deg(atxlarg[0])<<" d in ["<<rad2deg(atxlarg[1])<<","<<rad2deg(atxlarg[2])<<"]"<<endl;
+
+ if(fabs(dx-dy)>1.e-20 && fabs(txlarg-tylarg)>1.e-20) {
+   cout<<"\ndy = "<<dy<<", tylarg = "<<tylarg<<" Mpc (com), ny="<<ny<<endl;
+   cout<<"adty = "<<adty[0]<<" rd in ["<<adty[1]<<","<<adty[2]<<"]"<<endl;
+   cout<<"     = "<<rad2min(adty[0])<<"\' in ["<<rad2min(adty[1])<<","<<rad2min(adty[2])<<"]"<<endl;
+   cout<<"atylarg = "<<atylarg[0]<<" rd in ["<<atylarg[1]<<","<<atylarg[2]<<"]"<<endl;
+   cout<<"          "<<rad2deg(atylarg[0])<<" d in ["<<rad2deg(atylarg[1])<<","<<rad2deg(atylarg[2])<<"]"<<endl;
+ }
+
+ // --- 
+ // --- Cosmolographie Line of sight
+ // --- 
+ cout<<"\n>>>>\n>>>> Cosmologie & Geometrie ligne de visee\n>>>>"<<endl;
+ cout<<"dz = "<<dz<<", tzlarg = "<<tzlarg<<" Mpc (com), nz="<<nz<<endl;
+ cout<<"Redshift = "<<redshift[0]<<" in ["<<redshift[1]<<","<<redshift[2]<<"]"<<endl;
+ cout<<"dred = "<<dred[0]<<" in ["<<dred[1]<<","<<dred[2]<<"]"<<endl;
+ cout<<"nu HI = "<<nuhiz[0]<<" GHz in ["<<nuhiz[1]<<","<<nuhiz[2]<<"]"<<endl;
+ cout<<"lambda HI = "<<lambdahiz[0]<<" m in ["<<lambdahiz[1]<<","<<lambdahiz[2]<<"]"<<endl;
+ cout<<"dnu HI= "<<dnuhiz[0]*1e3<<" MHz in ["<<dnuhiz[1]*1e3<<","<<dnuhiz[2]*1e3<<"]"<<endl;
+
+ // --- 
+ // --- Volume
+ // --- 
+ cout<<"\n>>>>\n>>>> Volumes\n>>>>"<<endl;
+ double Npix = (double)nx*(double)ny*(double)nz;
+ double vol_pixel = dx*dy*dz;
+ double vol_survey = vol_pixel*Npix;
+ cout<<"Npix total = "<<Npix<<" -> "<<Npix*sizeof(double)/1.e6<<" Mo"<<endl;
+ cout<<"Volume pixel = "<<vol_pixel<<" Mpc^3 com"<<endl;
+ cout<<"Volume total = "<<vol_survey<<" Mpc^3 com = "<<vol_survey/1.e9<<" Gpc^3"<<endl;
+
+ double vol = univ.Vol4Pi(redshift[1],redshift[2])/(4.*M_PI)*angsol_tot[0];
+ cout<<"Calcul avec angsol et redshift: vol = "<<vol<<" Mpc^3 = "<<vol/1.e9<<" Gpc^3"<<endl
+     <<"       -> pixel volume comoving = vol/Npix = "<<vol/Npix<<" Mpc^3"<<endl;
+
+ // --- 
+ // --- Angles solides
+ // --- 
+ cout<<"\n>>>>\n>>>> Angles solides\n>>>>"<<endl;
+ cout<<"Pixel solid angle = "<<angsol_pix[0]<<" sr ("<<angsol_pix[0]/(4.*M_PI)<<" *4Pi)"
+     <<" in ["<<angsol_pix[1]<<","<<angsol_pix[2]<<"]"<<endl;
+ cout<<"                  = "<<sr2min2(angsol_pix[0])<<"\'^2"
+     <<" in ["<<sr2min2(angsol_pix[1])<<","<<sr2min2(angsol_pix[2])<<"]"<<endl;
+ cout<<"Total solid angle = "<<angsol_tot[0]<<" sr ("<<angsol_tot[0]/(4.*M_PI)<<" *4Pi)"
+     <<" in ["<<angsol_tot[1]<<","<<angsol_tot[2]<<"]"<<endl;
+
+ // --- 
+ // --- Fourier space: k = omega = 2*Pi*Nu = 2*Pi*C/Lambda
+ // --- 
+ cout<<"\n>>>>\n>>>> Geometrie dans l'espace de Fourier\n>>>>"<<endl;
+ cout<<"Array size: nx = "<<nx<<",  ny = "<<ny<<",  nz = "<<nz<<endl;
+ double dk_x = 2.*M_PI/(nx*dx), knyq_x = M_PI/dx;
+ double dk_y = 2.*M_PI/(nx*dy), knyq_y = M_PI/dy;
+ double dk_z = 2.*M_PI/(nz*dz), knyq_z = M_PI/dz;
+ cout<<"Transverse:"<<endl
+     <<"  Resolution: dk_x = "<<dk_x<<" Mpc^-1  (2Pi/dk_x="<<2.*M_PI/dk_x<<" Mpc)"<<endl
+     <<"              dk_y = "<<dk_y<<" Mpc^-1  (2Pi/dk_y="<<2.*M_PI/dk_y<<" Mpc)"<<endl
+     <<"  Nyquist:    kx = "<<knyq_x<<" Mpc^-1  (2Pi/knyq_x="<<2.*M_PI/knyq_x<<" Mpc)"<<endl
+     <<"              ky = "<<knyq_y<<" Mpc^-1  (2Pi/knyq_y="<<2.*M_PI/knyq_y<<" Mpc)"<<endl;
+ cout<<"Line of sight:"<<endl
+     <<"  Resolution: dk_z = "<<dk_z<<" Mpc^-1  (2Pi/dk_z="<<2.*M_PI/dk_z<<" Mpc)"<<endl
+     <<"  Nyquist:    kz = "<<knyq_z<<" Mpc^-1  (2Pi/knyq_z="<<2.*M_PI/knyq_z<<" Mpc)"<<endl;
+
+ // --- 
+ // --- Variance cosmique
+ // --- 
+ //                      cosmique                    poisson
+ // (sigma/P)^2 = 2*(2Pi)^3 / (4Pi k^2 dk Vsurvey) * [(1+n*P)/(n*P)]^2
+ // nombre de mode = 1/2 * Vsurvey/(2Pi)^3 * 4Pi*k^2*dk
+ if(kcosm>0. && pkcosm>0.) {
+   double pk = pkcosm*pow(growthfac[0],2.);
+   cout<<"\n>>>>\n>>>> variance cosmique pour k="<<kcosm<<" Mpc^-1, pk(z=0)="
+       <<pkcosm<<", pk(z="<<redshift[0]<<")="<<pk<<"\n>>>>"<<endl;
+   for(int i=0;i<3;i++) {  // la correction de variance du au bruit de poisson
+     double v = 1.1; if(i==1) v=1.5; if(i==2) v=2.0;
+     double ngal = 1./(v-1.)/pk;
+     cout<<"  pour "<<ngal<<" gal/Mpc^3 on multiplie par "<<v<<" sigma/P"<<endl;
+   }
+
+   cout<<endl;
+   vector<double> dk; if(dkcosm>0.) dk.push_back(dkcosm);
+   dk.push_back(dk_x); dk.push_back(dk_y); dk.push_back(dk_z);
+   for(int i=0;i<(int)dk.size();i++) { // la variance cosmique pure
+     double vcosm = sqrt( 2.*pow(2.*M_PI,3.)/(4.*M_PI*pow(kcosm,2.)*dk[i]*vol_survey) );
+     double nmode = 0.5*vol_survey/pow(2.*M_PI,3.) * 4.*M_PI*pow(kcosm,2.)*dk[i];
+     cout<<"  pour dk = "<<dk[i]<<" Mpc^-1:  sigma/P = "<<vcosm
+         <<" , Nmode = "<<nmode<<endl;
+   }
+ }
+
+ // --- 
+ // --- Masse de HI
+ // --- 
+ cout<<"\n>>>>\n>>>> Mass HI\n>>>>"<<endl;
+ Schechter sch(nstar,mstar,alpha);
+ sch.SetOutValue(1);
+ cout<<"nstar= "<<nstar<<"  mstar="<<mstar<<"  alpha="<<alpha<<endl;
+ cout<<"mstar*sch(mstar) = "<<sch(mstar)<<" Msol/Mpc^3/Msol"<<endl;
+ int npt = 10000;
+ double lnx1=log10(1.e+6), lnx2=log10(1.e+13), dlnx=(lnx2-lnx1)/npt;
+ double masshimpc3 = IntegrateFuncLog(sch,lnx1,lnx2,0.001,dlnx,10.*dlnx,6);
+ cout<<"Mass density: "<<masshimpc3<<" Msol/Mpc^3"<<endl;
+
+ double masshipix = masshimpc3*vol_pixel;
+ double masshitot = masshimpc3*vol_survey;
+ cout<<"Pixel mass = "<<masshipix<<" Msol"<<endl
+     <<"Total mass in survey = "<<masshitot<<" Msol"<<endl;
+ cout<<"OmegaHI a z=0: "<<masshimpc3/rhoc0<<endl;
+ for(int i=0;i<3;i++)
+   cout<<"        a z="<<redshift[i]<<": "<<masshimpc3/rhocz[i]<<endl;
+ if(mhiref<=0.)  mhiref = masshipix;
+
+ sch.SetOutValue(0);
+ cout<<"\nsch(mstar) = "<<sch(mstar)<<" /Mpc^3/Msol"<<endl;
+ cout<<"Galaxy number density:"<<endl;
+ for(double x=lnx1; x<lnx2-0.5; x+=1.) {
+   double n = IntegrateFuncLog(sch,x,lnx2,0.001,dlnx,10.*dlnx,6);
+   cout<<"  m>"<<x<<" Msol: "<<n<<" /Mpc^3, "<<n*vol_pixel<<" /pixel, "
+       <<n*vol_survey<<" in survey"<<endl;
+ }
+ sch.SetOutValue(1);
+
+ // --- 
+ // --- Survey values
+ // --- 
+ cout<<"\n>>>>\n>>>> Observations\n>>>>"<<endl;
+ double surfeff = surftot * eta_eff;
+ cout<<"surf_tot="<<surftot<<" m^2, eta="<<eta_eff<<"  surf_eff="<<surfeff<<" m^2, tobs="<<tobs<<" s"<<endl;
+
+ // Angles solides pour un telescope plein
+ double angSEq[4], angEq[4];
+ for(int i=0;i<4;i++) {
+   double nu = Fr_HyperFin_Par;
+   if(i<3) nu = nuhiz[i];
+   angSEq[i] = AngsolEqTelescope(nu,surftot);
+   angEq[i] = 2.*FrAngSol(angSEq[i]);
+ }
+ cout<<"\nFor a "<<surftot<<" m^2 telescope:"<<endl
+     <<"    equivalent Omega = "<<angSEq[0]<<" sr in ["<<angSEq[1]<<","<<angSEq[2]<<"]"<<endl
+     <<"    angular diameter = "<<angEq[0]<<" rd = "<<rad2min(angEq[0])
+     <<"\' in ["<<angEq[2]<<","<<angEq[2]<<"]"<<endl;
+ cout<<"At z=0: equivalent Omega = "<<angSEq[3]<<" sr"<<endl
+     <<"        angular diameter = "<<angEq[3]<<" rd = "<<rad2min(angEq[3])<<"\'"<<endl;
+
+ // Pour une observation ou le lobe est + petit ou grand que le pixel de simulation
+ // La taille angulaire du lobe change avec la frequence donc avec le redshift
+ // La taille du lobe "lobearea0" est donnee pour une frequence de reference "lobefreq0" en MHz
+ double nlobes[3] = {1.,1.,1.};
+ // Si "lobefreq0" negatif c'est la frequence du centre du cube
+ if(lobefreq0<=0.) lobefreq0 = nuhiz[0]*1.e3;
+ // Si "lobearea0" negatif c'est la taille du pixel ramenee a lobefreq0
+ if(lobearea0<=0.) lobearea0 = sr2min2(angsol_pix[0])*pow(nuhiz[0]*1.e3/lobefreq0,2.);
+ cout<<"\n--- Lobe: angsol="<<lobearea0<<"\'^2 pour "<<lobefreq0<<" MHz"<<endl;
+ double lobearea[3];
+ for(int i=0;i<3;i++) {
+   lobearea[i] = lobearea0*pow(lobefreq0/(nuhiz[0]*1.e3),2.);
+   nlobes[i] = sr2min2(angsol_pix[i])/lobearea[i];
+ }
+ cout<<"Lobe cylindrique area "<<lobearea[0]<<"\'^2 in ["<<lobearea[1]<<","<<lobearea[2]<<"]"<<endl;
+ cout<<"Number of beams in one transversal pixel "<<nlobes[0]<<" in ["<<nlobes[1]<<","<<nlobes[2]<<"]"<<endl;
+
+ // --- 
+ // --- Signal analysis
+ // --- 
+ // --- Temperature d'antenne Ta et temperature de brillance Tb
+ // La puissance d'une source de brillance I non polarisee est:
+ // P = I * S * Omega * dNu
+ // La puissance recue pour une seule polarisation est:
+ // P = 1/2 * I * S * Omega * dNu
+ // La puissance recue pour un telescope (plein) est
+ //    en remplacant Omega = lambda^2/S
+ // P = 1/2 * I * lambda^2 * dNu
+ // En appliquant la loi de Rayleigh: I = 2*k*Tb/lambda^2
+ //   on obtient
+ // P = 1/2 * 2*k*Tb * dNu = k * Tb * dNu
+ // La temperature d'antenne est definie comme
+ // P = k * Ta * dNu
+ // Donc pour un ciel de temperature de brillance Tb
+ //   et pour une antenne qui mesure une seule polarisation
+ // on a: Ta = Tb
+
+ cout<<"\n>>>>\n>>>> Signal Analysis\n>>>>"<<endl;
+ cout<<"Facteur polar = "<<facpolar<<endl;
+
+ PlanckSpectra planck(T_CMB_Par);
+ planck.SetSpectraApprox(PlanckSpectra::RAYLEIGH);  // Rayleigh spectra
+ planck.SetSpectraVar(PlanckSpectra::NU); // frequency
+ planck.SetSpectraPower(PlanckSpectra::POWER); // output en W/....
+ planck.SetSpectraUnit(PlanckSpectra::ANGSFLUX); // radiance W/m^2/Sr/Hz
+
+ // --- 
+ // --- Signal HI
+ // --- 
+ // Power emitted by HI
+ cout<<"--- Power from HI for M = "<<mhiref<<" Msol"<<endl;
+ cout<<"Flux factor = "<<hifactor<<" at redshift = "<<redshift[0]<<endl;
+ cout<<"Luminosite = "<<hifactor*Msol2LumiHI(mhiref)<<" W"<<endl;
+
+ double fhi_ref[3], sfhi_ref[3];
+ for(int i=0;i<3;i++) {
+   fhi_ref[i] = hifactor*Msol2FluxHI(mhiref,dlum[i]);
+   sfhi_ref[i] = fhi_ref[i] / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
+ }
+ cout<<"FluxHI("<<dlum[0]<<" Mpc) all polar: "<<fhi_ref[0]<<" W/m^2 = "
+     <<fhi_ref[0]/Jansky2Watt_cst<<" Jy.Hz"
+     <<" in ["<<fhi_ref[1]/Jansky2Watt_cst<<","<<fhi_ref[2]/Jansky2Watt_cst<<"]"<<endl;
+ cout<<"If spread over pixel depth ("<<dnuhiz[0]<<" GHz):"<<endl
+     <<"  flux density = "<<sfhi_ref[0]*1.e6<<" mu_Jy"
+     <<" in ["<<sfhi_ref[1]<<","<<sfhi_ref[2]<<"]"<<endl;
+
+ // Signal HI
+ double psig_2polar[3], tasig_2polar[3], ssig_2polar[3], isig_2polar[3], tsig_2polar[3];
+ double psig[3], tasig[3], ssig[3], isig[3], tsig[3];
+ double doplarge[3], dzvrot[3];
+ 
+ for(int i=0;i<3;i++) {
+   psig_2polar[i] = fhi_ref[i] * surfeff;
+   tasig_2polar[i] = psig_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
+   ssig_2polar[i] = psig_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
+   isig_2polar[i] = ssig_2polar[i] / angsol_pix[i];
+   tsig_2polar[i] = isig_2polar[i]*Jansky2Watt_cst
+                    / (2.*pow(nuhiz[i]*1e9/(SpeedOfLight_Cst*1000.),2.)*k_Boltzman_Cst);
+   psig[i] = facpolar * psig_2polar[i];
+   tasig[i] = facpolar * tasig_2polar[i];
+   ssig[i] = facpolar * ssig_2polar[i];
+   isig[i] = facpolar * isig_2polar[i];
+   tsig[i] = facpolar * tsig_2polar[i];
+   doplarge[i] = LargeurDoppler(vrot,nuhiz[i]);
+   dzvrot[i] = DzFrV(vrot,redshift[i]);
+ }
+ cout<<"\n--- Signal HI("<<mhiref<<" Msol) for Dnu="<<dnuhiz[0]<<" GHz :"<<endl
+     <<" Observation:"<<endl
+     <<"    Power="<<psig[0]<<" W in ["<<psig[1]<<","<<psig[2]<<"]"<<endl
+     <<"    Flux density = "<<ssig[0]*1.e6<<" mu_Jy in ["<<ssig[1]*1.e6<<","<<ssig[2]*1.e6<<"]"<<endl
+     <<"    Intensity = "<<isig[0]<<" Jy/sr in ["<<isig[1]<<","<<isig[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tasig[0]<<" K in ["<<tasig[1]<<","<<tasig[2]<<"]"<<endl
+     <<"    Brightness temperature = "<<tsig[0]<<" K in ["<<tsig[1]<<","<<tsig[2]<<"]"<<endl
+     <<" 2 polars:"<<endl
+     <<"    Power="<<psig_2polar[0]<<" W in ["<<psig_2polar[1]<<","<<psig_2polar[2]<<"]"<<endl
+     <<"    Flux density = "<<ssig_2polar[0]*1.e6<<" mu_Jy in ["<<ssig_2polar[1]*1.e6<<","<<ssig_2polar[2]*1.e6<<"]"<<endl
+     <<"    Intensity = "<<isig_2polar[0]<<" Jy/sr in ["<<isig_2polar[1]<<","<<isig_2polar[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tasig_2polar[0]<<" K in ["<<tasig_2polar[1]<<","<<tasig_2polar[2]<<"]"<<endl
+     <<"    Brightness temperature = "<<tsig_2polar[0]<<" K in ["<<tsig_2polar[1]<<","<<tsig_2polar[2]<<"]"<<endl;
+
+ // Elargissement doppler de la raie a 21cm: dNu = vrot/C * Nu(21cm) / (1+z)
+ cout<<"    Doppler for rotation width of "<<vrot<<" km/s"<<endl
+     <<"            width="<<doplarge[0]*1.e3<<" MHz  in ["<<doplarge[1]*1.e3<<","<<doplarge[2]*1.e3<<"]"<<endl
+     <<"            dzvrot= "<<dzvrot[0]<<" in ["<<dzvrot[1]<<","<<dzvrot[2]<<"]"<<endl;
+ if(doplarge[0]>dnuhiz[0])
+   cout<<"Warning: doppler width "<<doplarge[0]<<" GHz > "<<dnuhiz[0]<<" GHz redshift bin width"<<endl;
+
+ // --- 
+ // --- Synchrotron  (T en -2.7  -> Flux en -0.7  dans l'approximation Rayleigh)
+ // --- 
+ double tsynch[3];
+ double psynch_2polar[3], tasynch_2polar[3], ssynch_2polar[3], isynch_2polar[3];
+ double psynch[3], tasynch[3], ssynch[3], isynch[3];
+
+ for(int i=0;i<3;i++) {
+   tsynch[i] = Tsynch408;
+   if(fabs(indnu)>1.e-50) tsynch[i] *= pow(nuhiz[i]/nuhaslam,indnu);
+   planck.SetTemperature(tsynch[i]);
+   psynch_2polar[i] = planck(nuhiz[i]*1.e+9) * surfeff * angsol_pix[i] * (dnuhiz[i]*1e9);
+   tasynch_2polar[i] = psynch_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
+   ssynch_2polar[i] = psynch_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
+   isynch_2polar[i] = ssynch_2polar[i] / angsol_pix[i];
+   psynch[i] = facpolar * psynch_2polar[i];
+   tasynch[i] = facpolar * tasynch_2polar[i];
+   ssynch[i] = facpolar * ssynch_2polar[i];
+   isynch[i] = ssynch[i] / angsol_pix[i];
+ }
+ cout<<"\n--- Synchrotron: T="<<Tsynch408<<" K ("<<nuhaslam<<" GHz), "<<endl
+     <<"    tsynch="<<tsynch[0]<<" K ("<<nuhiz[0]<<" GHz) in ["<<tsynch[1]<<","<<tsynch[2]<<"]"<<endl
+     <<" Observation:"<<endl
+     <<"    Power="<<psynch[0]<<" W for pixel in ["<<psynch[1]<<","<<psynch[2]<<"]"<<endl
+     <<"    Flux density = "<<ssynch[0]<<" Jy for pixel solid angle in ["<<ssynch[1]<<","<<ssynch[2]<<"]"<<endl
+     <<"    Intensity = "<<isynch[0]<<" Jy/sr in ["<<isynch[1]<<","<<isynch[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tasynch[0]<<" K in ["<<tasynch[1]<<","<<tasynch[2]<<"]"<<endl
+     <<" 2 polars:"<<endl
+     <<"    Power="<<psynch_2polar[0]<<" W for pixel in ["<<psynch_2polar[1]<<","<<psynch_2polar[2]<<"]"<<endl
+     <<"    Flux density = "<<ssynch_2polar[0]<<" Jy for pixel solid angle in ["<<ssynch_2polar[1]<<","<<ssynch_2polar[2]<<"]"<<endl
+     <<"    Intensity = "<<isynch_2polar[0]<<" Jy/sr in ["<<isynch_2polar[1]<<","<<isynch_2polar[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tasynch_2polar[0]<<" K in ["<<tasynch_2polar[1]<<","<<tasynch_2polar[2]<<"]"<<endl;
+
+ // --- 
+ // --- CMB
+ // --- 
+ planck.SetTemperature(tcmb);
+ double pcmb_2polar[3], tacmb_2polar[3], scmb_2polar[3], icmb_2polar[3];
+ double pcmb[3], tacmb[3], scmb[3], icmb[3];
+
+ for(int i=0;i<3;i++) {
+   pcmb_2polar[i] = planck(nuhiz[i]*1.e+9) * surfeff * angsol_pix[i] * (dnuhiz[i]*1e9);
+   tacmb_2polar[i] = pcmb_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
+   scmb_2polar[i] = pcmb_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
+   icmb_2polar[i] = scmb_2polar[i] / angsol_pix[i];
+   pcmb[i] = facpolar * pcmb_2polar[i];
+   tacmb[i] = facpolar * tacmb_2polar[i];
+   scmb[i] = facpolar * scmb_2polar[i];
+   icmb[i] = scmb[i] / angsol_pix[i];
+ }
+ cout<<"\n--- CMB: T="<<tcmb<<" K"<<endl
+     <<" Observation:"<<endl
+     <<"    Power="<<pcmb[0]<<" W for pixel in ["<<pcmb[1]<<","<<pcmb[2]<<"]"<<endl
+     <<"    Flux density = "<<scmb[0]<<" Jy for pixel solid angle in ["<<scmb[1]<<","<<scmb[2]<<"]"<<endl
+     <<"    Intensity = "<<icmb[0]<<" Jy/sr in ["<<icmb[1]<<","<<icmb[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tacmb[0]<<" K in ["<<tacmb[1]<<","<<tacmb[2]<<"]"<<endl
+     <<" 2 polars:"<<endl
+     <<"    Power="<<pcmb_2polar[0]<<" W for pixel in ["<<pcmb_2polar[1]<<","<<pcmb_2polar[2]<<"]"<<endl
+     <<"    Flux density = "<<scmb_2polar[0]<<" Jy for pixel solid angle in ["<<scmb_2polar[1]<<","<<scmb_2polar[2]<<"]"<<endl
+     <<"    Intensity = "<<icmb_2polar[0]<<" Jy/sr in ["<<icmb_2polar[1]<<","<<icmb_2polar[2]<<"]"<<endl
+     <<"    Antenna temperature = "<<tacmb_2polar[0]<<" K in ["<<tacmb_2polar[1]<<","<<tacmb_2polar[2]<<"]"<<endl;
+
+ // --- 
+ // --- AGN
+ // --- 
+ double flux_agn = pow(10.,lflux_agn);
+ double mass_agn[3], flux_agn_pix[3], mass_agn_pix[3], lmass_agn_pix[3];
+ for(int i=0;i<3;i++) {
+   mass_agn[i] = FluxHI2Msol(flux_agn*Jansky2Watt_cst,dlum[i]);
+   flux_agn_pix[i] = flux_agn*(dnuhiz[i]*1e9);
+   mass_agn_pix[i] = FluxHI2Msol(flux_agn_pix[i]*Jansky2Watt_cst,dlum[i]);
+   lmass_agn_pix[i] = log10(mass_agn_pix[i]);
+ }
+ cout<<"\n--- AGN: log10(S_agn)="<<lflux_agn<<"   S_agn="<<flux_agn<<" Jy :"<<endl
+     <<"  mass_agn = "<<mass_agn[0]<<" equiv. Msol/Hz in ["<<mass_agn[1]<<","<<mass_agn[2]<<"]"<<endl
+     <<"  flux_agn_pix = "<<flux_agn_pix[0]<<" 10^-26 W/m^2 in ["<<flux_agn_pix[1]<<","<<flux_agn_pix[2]<<"]"<<endl
+     <<"  mass_agn_pix = "<<mass_agn_pix[0]<<" Msol in ["<<mass_agn_pix[1]<<","<<mass_agn_pix[2]<<"]"<<endl
+     <<"  log10(mass_agn_pix) = "<<lmass_agn_pix[0]<<"  in ["<<lmass_agn_pix[1]<<","<<lmass_agn_pix[2]<<"]"<<endl;
+
+ // =====================================================================
+ // ---
+ // --- Noise analysis
+ // ---
+ // --- Puissance du bruit pour un telescope de surface Ae et de BW dNu
+ // Par definition la puissance du bruit est:
+ //     Pb = k * Tsys * dNu  (W)
+ // Pour une source (non-polarisee) de densite de flux (totale 2 polars)
+ //     St (exprimee en Jy = 10^-26 W/m^2/Hz)
+ //     Pt = St * Ae * dNu   (puissance totale emise en W pour 2 polars)
+ //     P1 = 1/2 * St * Ae * dNu   (puissance emise en W pour une polar)
+ // la SEFD (system equivalent flux density en Jy) est definie comme
+ //   la densite de flux total (2 polars) "St" d'une source (non-polarisee)
+ //   dont la puissance P1 mesuree pour une seule polarisation
+ //   serait egale a la puissance du bruit. De P1 = Pb on deduit:
+ //   SEFD = 2 * k * Tsys / Ae    (en Jy)
+ //   la puissance du bruit est: Pb = 1/2 * SEFD * Ae * dNu  (en W)
+ // la sensibilite Slim tient compte du temps d'integration et de la BW:
+ //   le nombre de mesures independantes est "2*dNu*Tobs" donc
+ //   Slim = SEFD / sqrt(2*dNu*Tobs) =  2*k*Tsys/[Ae*sqrt(2*dNu*Tobs) (en Jy)
+ // --- Puissance du bruit pour un interferometre
+ // Ae = surface d'un telescope elementaire
+ // N  = nombre de telescopes dans l'interferometre (Atot = N*Ae)
+ // La sensibilite Slim en Jy est:
+ // Slim = 2 * k * Tsys / [ Ae * Sqrt(2*N(N-1)/2 *dnu*Tobs) ]
+ //      = 2 * k * Tsys / [ Atot/N * Sqrt(2*N(N-1)/2*dnu*Tobs) ]
+ //      = 2 * k * Tsys / [ Atot * Sqrt((N-1)/N *dnu*Tobs) ]
+ // - Interferometre a deux antennes:
+ // Slim =  2 * k * Tsys / [ Atot * Sqrt(1/2 *dnu*Tobs) ]
+ // - Interferometre a N antennes (N grand):
+ // Slim ->  2 * k * Tsys / [ Atot * Sqrt(dnu*Tobs) ]
+ //      C'est aussi la formule pour un telescope unique de surface Atot
+ // --- On ne mesure qu'une seule polarisation
+ // Ces formules sont valables si on mesure 1 polarisation:
+ // Slim est la densite de flux total "St" (2 polars) d'une source (non-polarisee)
+ //   qui donne la meme puissance que le bruit dans un detecteur qui ne
+ //   mesure qu'une seule polarisation:
+ // Le rapport S/N pour une source de densite de flux St (totale 2 polars):
+ //    S/N = St / Slim
+ // La puissance de bruit est, par definition:
+ //    Pb = 1/2 *Slim*Atot*dNu
+ //         = k*Tsys*sqrt(2*dNu/Tobs)  pour N=2
+ //         = k*Tsys*sqrt(dNu/Tobs)    pour N>>grand
+ // La densite de flux d'une source a S/N=1 est:
+ //    St = Slim
+ // La puissance d'une source a S/N=1 mesuree par un detecteur
+ //    qui ne mesure qu'une polar est:
+ //    P1_lim = 1/2 *Slim*Atot*dNu
+ // --- On mesure les 2 polarisations avec deux voies d'electronique distinctes
+ // la puissance du signal mesure est multipliee par 2
+ // la puissance du bruit est multipliee par sqrt(2)
+ // on a donc un gain d'un facteur sqrt(2) sur le rapport S/N
+ // (cela revient d'ailleur a doubler le temps de pose: Tobs -> 2*Tobs)
+ // En notant arbitrairement: Slim' = Slim / sqrt(2)
+ //    ou Slim est defini par les formules ci-dessus
+ // Le rapport S/N pour une source de densite de flux St (totale 2 polars):
+ //   (S/N)_2 = (S/N)_1 * sqrt(2) = (St / Slim) * sqrt(2) = St / Slim'
+ // La densite de flux d'une source a S/N=1 est:
+ //    St = Slim' = Slim / sqrt(2)
+ // La puissance d'une source a S/N=1 cumulee par les 2 detecteurs est:
+ //    P_lim = St*Atot*dNu = Slim'*Atot*dNu = 1/sqrt(2) *Slim*Atot*dNu
+ //          = P1_lim * sqrt(2)
+ // La puissance de bruit cumulee par les 2 detecteurs est, par definition:
+ //    Pb = P_lim = Slim'*Atot*dNu = P1_lim * sqrt(2)
+ //               = 2*k*Tsys*sqrt(dNu/Tobs)   pour N=2
+ //               = k*Tsys*sqrt(2*dNu/Tobs)   pour N>>grand
+ // =====================================================================
+
+ cout<<"\n>>>>\n>>>> Noise analysis\n>>>>"<<endl;
+ double psys[3];
+ for(int i=0;i<3;i++) psys[i] = k_Boltzman_Cst * Tsys * (dnuhiz[i]*1.e+9);
+ cout<<"Noise: T="<<Tsys<<" K"<<endl
+     <<"       P="<<psys[0]<<" W in ["<<psys[1]<<","<<psys[2]<<"]"<<endl;
+
+ cout<<"...Computation assume that noise dominate the signal."<<endl;
+ if(ya2polar)
+   cout<<"...Assuming 2 polarisations measurements with 2 different electronics."<<endl;
+
+
+ //---
+ for(unsigned short it=0;it<2;it++) {
+
+   double fac = 1.;
+   if(it==0) { // Interferometre a 2 telescopes
+     fac = 0.5;
+     cout<<"\n...Observation limits for a 2 telescope interferometer (with complex correlator)"<<endl
+         <<"   (sensitivity is given for real or complex correlator output)"<<endl;
+   } else if (it==1) { // Interferometre a N>> telescopes
+     fac = 1.;
+     cout<<"\n...Observation limits for a N (large) telescope interferometer (with complex correlator)"<<endl
+         <<"     (weak source limit sensitivity in a synthetised image)"<<endl
+         <<"     Also valid for a single dish telescope."<<endl;
+   } else continue;
+
+   double slim[3], SsN[3], smass[3], pkbruit[3];
+   for(int i=0;i<3;i++) {
+     slim[i] = 2. * k_Boltzman_Cst * Tsys / surfeff
+               / sqrt(fac*(dnuhiz[i]*1.e+9)*tobs) /Jansky2Watt_cst;
+     if(ya2polar) slim[i] /= sqrt(2.);
+     SsN[i] = ssig_2polar[i] / slim[i];  // independant de  angsol_pix*surfeff
+     smass[i] = mhiref / ssig_2polar[i] * slim[i];
+     pkbruit[i] = pow(smass[i]/mhiref,2.)*vol_pixel;
+   }
+   cout<<"for 1 lobe:"<<endl
+       <<"   Slim    = "<<slim[0]*1.e6<<" mu_Jy in ["<<slim[1]*1.e6<<","<<slim[2]*1.e6<<"]"<<endl
+       <<"   S/N     = "<<SsN[0]<<" in ["<<SsN[1]<<","<<SsN[2]<<"]"<<endl
+       <<"   Mass HI = "<<smass[0]<<" Msol in ["<<smass[1]<<","<<smass[2]<<"]"<<endl
+       <<"   Pk      = "<<pkbruit[0]<<" Mpc^3 in ["<<pkbruit[1]<<","<<pkbruit[2]<<"]"<<endl;
+
+   double slim_nl[3], SsN_nl[3], smass_nl[3], pkbruit_nl[3];
+   for(int i=0;i<3;i++) {
+     slim_nl[i] = slim[i] * sqrt(nlobes[i]);
+     SsN_nl[i] = ssig_2polar[i] / slim_nl[i];
+     smass_nl[i] = mhiref / ssig_2polar[i] * slim_nl[i];
+     pkbruit_nl[i] = pow(smass_nl[i]/mhiref,2.)*vol_pixel;
+   }
+   cout<<"for "<<nlobes[0]<<" lobes[i] in ["<<nlobes[1]<<","<<nlobes[2]<<"] :"<<endl
+       <<"   Slim    = "<<slim_nl[0]*1.e6<<" mu_Jy in ["<<slim_nl[1]*1.e6<<","<<slim_nl[2]*1.e6<<"]"<<endl
+       <<"   S/N     = "<<SsN_nl[0]<<" in ["<<SsN_nl[1]<<","<<SsN_nl[2]<<"]"<<endl
+       <<"   Mass HI = "<<smass_nl[0]<<" Msol in ["<<smass_nl[1]<<","<<smass_nl[2]<<"]"<<endl
+       <<"   Pk      = "<<pkbruit_nl[0]<<" Mpc^3 in ["<<pkbruit_nl[1]<<","<<pkbruit_nl[2]<<"]"<<endl;
+
+ }
+
+ return 0;
+ }
+
+
+//-------------------------------------------------------------------------------------------
+double LargeurDoppler(double v, double nu)
+// largeur doppler pour une vitesse v en km/s et une frequence nu
+{
+ return v / SpeedOfLight_Cst * nu;
+}
+
+double DzFrV(double v, double zred)
+// largeur en redshift pour une vitesse v en km/s au redshift zred
+{
+  return v / SpeedOfLight_Cst * (1. + zred);
+}
+
+double DNuFrDz(double dzred,double nu_at_0,double zred)
+// Largeur DNu pour une largeur en redshift "dzred" au redshift "zred"
+//    pour la frequence "nu_at_0" a z=0
+// nu =  NuHi(z=0)/(1.+z0)
+// dnu = NuHi(z=0)/(1.+z0-dz/2) - NuHi/(1.+z0+dz/2)
+//     = NuHi(z=0)*dz/[ (1+z0)^2 - (dz/2)^2 ]
+//     = NuHi(z=0)*dz/(1.+z0)^2 / [ 1 - [dz/(1+z0)/2)]^2 ]
+//     = NuHi(z=0)*dz/(1.+z0)^2 / [1 - dz/(1+z0)/2] / [1 + dz/(1+z0)/2]
+//    ~= NuHi(z=0)*dz/(1.+z0)^2   (approx. pour dz<<z0 a l'ordre (dz/z0)^2)
+{
+  double zp1 = 1.+zred;
+  return nu_at_0*dzred/(zp1*zp1)/(1.-dzred/zp1/2.)/(1.+dzred/zp1/2.);
+}
+
+double DzFrDNu(double dnu_at_0,double nu_at_0,double zred)
+// Largeur en redshift au redshift "zred" pour une largeur
+// en frequence "dnu_at_0" a la frequence "nu_at_0" a z=0
+{
+  if(dnu_at_0<=0.) return 0.;
+  double zp1 = 1.+zred;
+  double dnusnu0 = dnu_at_0/nu_at_0;
+  return 2./dnusnu0 * (sqrt(1.+(dnusnu0*zp1)*(dnusnu0*zp1)) - 1.);
+}
+double DzFrDNuApprox(double dnu_at_0,double nu_at_0,double zred)
+// idem DzFrDNu mais on utilise l'approximation: dnu=NuHi(z=0)*dz/(1.+z0)^2
+{
+  double zp1 = 1.+zred;
+  return dnu_at_0/nu_at_0 *(zp1*zp1);
+}
+
+double ZFrLos(double loscom,CosmoCalc& univ)
+// Recherche du redshift correspondant a une distance comobile
+// le long de la ligne de visee egale a "loscom" Mpc
+// et pour un univers "univ"
+{
+  double dz = univ.ZMax()/10.; if(dz<=0.) dz = 0.1;
+  double zmin=0., zmax=0.;
+  while(univ.Dloscom(zmax)<loscom) zmax += dz;
+  if(zmax==0.) return 0.;
+  for(int i=0; i<6; i++) {
+    zmin=zmax-dz; if(zmin<0.) zmin=0.;
+    dz /= 10.;
+    for(double z=zmin; z<zmax+dz; z+=dz) {
+      double d = univ.Dloscom(z);
+      if(d<loscom) continue;
+      zmax = z;
+      //cout<<"ZFrLos: z="<<zmax<<" d="<<d<<" / "<<loscom<<endl;
+      break;
+    }
+  }
+  return zmax;
+}
+
+double AngsolEqTelescope(double nu /* GHz */,double telsurf /* m^2 */)
+/*
+Calcul de l'angle solide (sr) equivalent pour un telescope
+de surface totale "telsurf" (m^2) a la frequence "nu" (GHz)
+- Soit D(t) la figure de diffraction du telescope telle que D(t=0)=1
+       (t = angle depuis l'axe optique)
+  telescope circulaire de diametre D:
+      D(t) = [2J1(Pi*D*t/l)/(Pi*D*t/l)]
+  telescope rectangulaire axb:
+      D(t) = [sin(Pi*a*t/l)/(Pi*a*t/l)]*[sin(Pi*b*t/l)/(Pi*b*t/l)]
+- On cherche l'angle solide equivalent (par ex d'un cylindre de hauteur 1)
+  Int[ D(t)^2 dOmega ] =  Int[ D(t)^2 2Pi t dt ] = Lambda^2/S
+- En conclusion, pour un ciel d'intensite uniforme I, on a:
+  P = I * S * Omega * dNu = I * S * (Lambda^2/S) * dNu
+*/
+{
+  double lambda = SpeedOfLight_Cst*1000./(nu*1.e9);
+  return lambda*lambda / telsurf;
+}
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvfitpk.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvfitpk.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvfitpk.cc	(revision 3445)
@@ -0,0 +1,340 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "ntuple.h"
+#include "histerr.h"
+
+#include "constcosmo.h"
+#include "pkspectrum.h"
+
+#include "Minuit2/FunctionMinimum.h"
+#include "Minuit2/MnMigrad.h"
+#include "Minuit2/MnUserParameters.h"
+#include "Minuit2/MnPrint.h"
+#include "Minuit2/MnMinos.h"
+#include "Minuit2/MinosError.h"
+#include "Minuit2/FCNBase.h"
+using namespace ROOT::Minuit2;
+
+namespace ROOT { namespace Minuit2 {
+class MyFCN : public FCNBase {
+public:
+  MyFCN(HistoErr& herr,PkSpectrumZ& pk);
+  void Init(const vector<double>& par) const;
+  double Func(double x,const vector<double>& par) const;
+  double operator()(const vector<double>& par) const;
+  double Up(void) const {return 1.;}
+private:
+  HistoErr& herr_;
+  PkSpectrumZ& pk_;
+};
+} }  // namespace ROOT + Minuit2
+
+void usage(void);
+void usage(void)
+{
+cout<<"usage: cmvfitpk [-k kmin,kmax] -e conchpkrec.ppf observ3d_1.ppf observ3d_2.ppf ..."<<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ // --- Cosmography definition (WMAP)
+ double zref = 0.175;
+ double ob0 = 0.0444356;
+ double h100=0.71, om0=0.267804, ol0=0.73;
+
+ // --- Spectrum and variance definition
+ double ns = 1., as = 1.;
+ double R=8./h100, sigmaR = 1.;
+ double kmin=1e-5,kmax=1000.;
+ int npt = 10000;
+ double eps=1.e-3;
+
+ // --- les fichiers
+ double klim[2]={0.,-1.};
+ string fconc = "";
+
+ // --- les options de print/plot
+ int nprint = 3, nplot = -1;  // -1 = all
+
+ // --- Reading arguments
+ char c;
+ while((c = getopt(narg,arg,"hk:e:")) != -1) {
+  switch (c) {
+  case 'k' :
+    sscanf(optarg,"%lf,%lf",&klim[0],&klim[1]);
+    break;
+  case 'e' :
+    fconc = optarg;
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+
+ if(optind>=narg) return -2;
+
+ // --- Create spectrum
+ cout<<endl<<"\n--- Create Spectrum"<<endl;
+ InitialSpectrum pkini(ns,as);
+ bool nobaryon = false;
+ double ocdm0 = om0-ob0;
+ TransfertEisenstein tf(h100,ocdm0,ob0,T_CMB_Par,nobaryon);
+ GrowthFactor growth(om0,ol0); cout<<"...Growth="<<growth(zref)<<endl;
+ PkSpectrum0 pk0(pkini,tf);
+ PkSpectrumZ pkz(pk0,growth,zref);
+
+ // --- Compute variance and normalize spectrum
+ pkz.SetZ(0.);
+ cout<<endl<<"\n--- Compute variance for top-hat R="<<R
+     <<" at z="<<pkz.GetZ()<<endl;
+ VarianceSpectrum varpk_th(pkz,R,VarianceSpectrum::TOPHAT);
+ double kfind_th = varpk_th.FindMaximum(kmin,kmax,eps);
+ double pkmax_th = varpk_th(kfind_th);
+ cout<<"kfind_th = "<<kfind_th<<" ("<<log10(kfind_th)<<"), integrand="<<pkmax_th<<endl;
+ double k1=kmin, k2=kmax;
+ int rc = varpk_th.FindLimits(pkmax_th/1.e4,k1,k2,eps);
+ cout<<"limit_th: rc="<<rc<<" : "<<k1<<" ("<<log10(k1)<<") , "
+     <<k2<<" ("<<log10(k2)<<")"<<endl;
+
+ double ldlk = (log10(k2)-log10(k1))/npt;
+ varpk_th.SetInteg(0.01,ldlk,-1.,4);
+ double sr2 = varpk_th.Variance(k1,k2);
+ cout<<"varpk_th="<<sr2<<"  ->  sigma="<<sqrt(sr2)<<endl;
+
+ double normpkz = sigmaR*sigmaR/sr2;
+ pkz.SetScale(normpkz);
+ cout<<"Spectrum normalisation = "<<pkz.GetScale()<<endl;
+ pkz.SetZ(zref);
+
+ // --- Reading reference mean spectrum
+ cout<<endl<<"\n--- Reading spectrum form file "<<fconc<<endl;
+ HistoErr herrconc;
+ {
+ PInPersist pis(fconc.c_str());
+ pis >> PPFNameTag("herrconc") >> herrconc;
+ }
+ cout<<herrconc;
+ if(herrconc.NBins()<1) return -3;
+ double b_ini = herrconc(2*herrconc.NBins()/3);
+ cout<<"b_ini = "<<b_ini<<endl;
+ if(klim[1]<=klim[0]) klim[1] = herrconc.XMax();
+
+ // --- NTuple et ppf
+ const int npar = 7;  // Number of parameters in the fit
+ TMatrix<r_8> Cov(npar,npar); Cov = 0.;
+ POutPersist pos("cmvfitpk.ppf");
+ const int nvar = 2*npar+1;
+ char *vname[nvar] = {
+       "xi2"
+       ,"b","a","oc","ob","ol","h","n"
+       ,"eb","ea","eoc","eob","eol","eh","en"
+       };
+ NTuple nt(nvar,vname);
+ double xnt[nvar];
+
+ // ***
+ // --- Boucle sur les fichiers a fitter
+ // ***
+ int nfile=0, ncov=0;
+ for(int ifile=optind;ifile<narg;ifile++) {
+
+   // --- lecture du fichier
+   cout<<">>> Reading["<<nfile<<","<<ifile<<"]: "<<arg[ifile]<<endl;
+   HistoErr herr;
+   PInPersist pis(arg[ifile]);
+   pis >> PPFNameTag("hpkrec") >> herr;
+   if(herr.NBins()!=herrconc.NBins()) {
+     cout<<"... bad number of bins: "<<herr.NBins()<<endl;
+     continue;
+   }
+
+   // --- Mise en forme
+   unsigned int nbinok = 0;
+   for(int i=0;i<herr.NBins();i++) {
+     double k = herr.BinCenter(i);
+     if(i==0 || k<klim[0] || k>klim[1]) {herr.SetErr2(i,-1.); continue;}
+     herr.SetErr2(i,herrconc.Error2(i));
+     nbinok++;
+   }
+
+   // --- Initialisation de minuit
+    MnUserParameters upar;
+    upar.Add("B",b_ini,b_ini/100.);
+    upar.Add("A",1.,0.01);
+    upar.Add("Ocdm",ocdm0,0.001,ocdm0/2.,2.*ocdm0);
+    //upar.Fix("Ocdm");
+    upar.Add("Ob",ob0,0.001,ob0/10.,10.*ob0);
+    //upar.Fix("Ob");
+    upar.Add("Ol",ol0,0.001,0.1,2.);
+    upar.Fix("Ol");
+    upar.Add("h100",h100,0.01,10.,150.);
+    upar.Fix("h100");
+    upar.Add("ns",ns,0.001,0.7,1.5);
+    upar.Fix("ns");
+    MyFCN fcn(herr,pkz);
+    if(nbinok<upar.VariableParameters()) {
+      cout<<"... nombre de degres de liberte <0: nbinok="<<nbinok<<endl;
+      continue;
+    }
+
+   // --- Fit minuit
+   unsigned int nfcall = 1000; double tolerance = 0.05;
+   MnMigrad migrad(fcn,upar,MnStrategy(1));
+   FunctionMinimum min = migrad(nfcall,tolerance);
+   if(!min.IsValid()) {
+     cout<<"!!!!!!!!! Echec Minuit"<<endl;
+     //cout<<"minimum: "<<min<<endl;
+     continue;
+   }
+
+   MnUserParameterState ustate = min.UserState();
+   double xi2r = ustate.Fval()/(nbinok-ustate.VariableParameters());
+   vector<double> parfit  = ustate.Parameters().Params();
+   vector<double> eparfit = ustate.Parameters().Errors();
+   if(ustate.HasCovariance()) {
+     MnUserCovariance ucov = ustate.Covariance();
+     for(unsigned int i=0;i<upar.VariableParameters();i++)
+       for(unsigned int j=0;j<upar.VariableParameters();j++)
+	 Cov(ustate.ExtOfInt(i),ustate.ExtOfInt(j)) += ucov(i,j);
+     ncov++;
+   }
+
+   // --- Recuperation des informations et remplissage NTuple
+   for(int i=0;i<nvar;i++) xnt[i] = 0.;
+   xnt[0] = xi2r;
+   for(int i=0;i<npar;i++) xnt[1+i] = parfit[i];
+   for(int i=0;i<npar;i++) xnt[npar+1+i] = eparfit[i];
+   nt.Fill(xnt);
+
+   // --- stoquage des histos de plots
+   if(nfile<nplot || nplot<0) {
+     HistoErr herrf(herr); herrf.Zero();
+     HistoErr herrd(herr); herrd.Zero();
+     fcn.Init(parfit);
+     for(int i=1;i<herr.NBins();i++) {
+       double f = fcn.Func(herr.BinCenter(i),parfit);
+       herrf.SetBin(i,f,herr.Error(i),1.);
+       herrd.SetBin(i,herr(i)-f,herr.Error(i),1.);
+     }
+     char str[64];
+     sprintf(str,"h%d",nfile); pos.PutObject(herr,str);
+     sprintf(str,"hf%d",nfile); pos.PutObject(herrf,str);
+     sprintf(str,"hd%d",nfile); pos.PutObject(herrd,str);
+   }
+
+   // --- Print de debug
+   if(nfile<nprint) {
+     cout<<"minimum: "<<min<<endl;
+     for(int i=0;i<nvar;i++) cout<<"["<<i<<"] = "<<xnt[i]<<endl;
+
+     MnMinos Minos(fcn,min);
+     pair<double,double> eminos[npar];
+     for(int ip=0;ip<npar;ip++) {
+       eminos[ip].first = eminos[ip].second = 0.;
+       if(!ustate.Parameter(ip).IsFixed()) eminos[ip] = Minos(ip);
+       cout<<"Minos: "<<ip<<" err=["<<eminos[ip].first<<","<<eminos[ip].second<<"]"<<endl;
+     }
+   }
+
+   nfile++;
+ }
+
+ // --- Fin du job
+ if(nfile>0) pos.PutObject(nt,"nt");
+ if(ncov>0) {Cov /= (double)ncov; pos.PutObject(Cov,"cov");}
+
+ return 0;
+}
+
+//--------------------------------------------------
+MyFCN::MyFCN(HistoErr& herr,PkSpectrumZ& pk)
+  : herr_(herr) , pk_(pk)
+{
+}
+
+void MyFCN::Init(const vector<double>& par) const
+{
+ double A=par[1], Ocdm0=par[2], Ob0=par[3], Ol0=par[4], h100=par[5], ns=par[6];
+ pk_.GetPk0().GetPkIni().SetSlope(ns);
+ pk_.GetPk0().GetPkIni().SetNorm(A);
+ pk_.GetPk0().GetTransfert().SetParTo(h100,Ocdm0,Ob0);
+ pk_.GetGrowthFactor().SetParTo(Ocdm0+Ob0,Ol0);
+}
+
+double MyFCN::Func(double x,const vector<double>& par) const
+// par: [0]=B,  [1]=A,  [2]=Ocdm0,  [3]=Ob0,  [4]=Ol0, [5]=h100, [6]=npow
+{
+ Init(par);
+ return pk_(x) + par[0];
+}
+
+double MyFCN::operator()(const vector<double>& par) const
+{
+ Init(par);
+ double xi2 = 0.;
+ for(int i=0;i<herr_.NBins();i++) {
+   double e2 = herr_.Error2(i);
+   if(e2<=0.) continue;
+   double x = herr_.BinCenter(i);
+   double v = herr_(i);
+   double f = Func(x,par);
+   xi2 += (v-f)*(v-f)/e2;
+ }
+ return xi2;
+}
+
+/*
+openppf cmvfitpk.ppf
+
+print nt
+
+set i 0
+zone
+disp h$i "nsta hbincont err"
+disp hf$i "nsta same red"
+
+zone
+disp hd$i "nsta hbincont err red"
+disp hd$i "nsta same"
+
+zone
+n/plot nt.xi2
+
+zone
+n/plot nt.a
+n/plot nt.b
+n/plot nt.b%a ! ! "crossmarker5"
+
+n/plot nt.oc
+n/plot nt.ob
+n/plot nt.oc+ob
+n/plot nt.ob%oc ! ! "crossmarker5"
+
+n/plot nt.ea
+n/plot nt.eb
+n/plot nt.ea%eb ! ! "crossmarker5"
+
+disp cov "zoomx30"
+del cor
+c++exec \
+TMatrix<r_8> cor(cov,false); cor = 0.; \
+for(int i=0;i<cor.NRows();i++) { \
+  for(int j=0;j<cor.NCols();j++) { \
+    double v = cov(i,i)*cov(j,j); \
+    if(v<=0.) continue; \
+    cor(i,j) = cov(i,j)/sqrt(v); \
+} } \
+KeepObj(cor); \
+cout<<"Matrice cor cree "<<endl;
+
+disp cor "zoomx30"
+
+ */
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvobserv3d.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvobserv3d.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvobserv3d.cc	(revision 3445)
@@ -0,0 +1,719 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+#include "matharr.h"
+
+#include "constcosmo.h"
+#include "cosmocalc.h"
+#include "schechter.h"
+#include "geneutils.h"
+#include "genefluct3d.h"
+
+void usage(void);
+void usage(void)
+{
+ cout<<"cmvobserv3d [...options...]"<<endl
+     <<" -a : auto init random seed (needed for multiple simul)"<<endl
+     <<" -0 : use ComputeFourier0 method (defaut: no, use normal way)"<<endl
+     <<" -G typevol: compute Pk(z=0) and apply growth factor in real space"<<endl
+     <<"             typevol=1 noise evolved with distance / observateur (def)"<<endl
+     <<"             typevol=2 noise evolved with distance to middle of Z planes"<<endl
+     <<"      (default: no, spectrum Pk(z=z_median) for all cube)"<<endl
+     <<" -F : filter spectrum by pixel shape (0=no 1=yes(default)"<<endl
+     <<" -U typ : do not poisson fluctuate with Ngal, convert directly to HI mass"<<endl
+     <<"          (typ<0 just multiply dRho/Rho by mass_by_pixel)"<<endl
+     <<" -x nx,dx : size along x axis (npix,Mpc)"<<endl
+     <<" -y ny,dy : size along y axis (npix,Mpc)"<<endl
+     <<"            if ny or dy <=0 take same value as for x"<<endl
+     <<" -z nz,dz : size along z axis (redshift axis, npix,Mpc)"<<endl
+     <<" -Z zref : redshift for the center of the simulation cube"<<endl
+     <<" -s snoise,typevol : gaussian noise sigma in equivalent Msol"<<endl
+     <<"           typevol=0 no evolution (def)"<<endl
+     <<"           typevol=1 noise evolved with distance / observateur"<<endl
+     <<"           typevol=2 noise evolved with distance to middle of Z planes"<<endl
+     <<" -2 : compute also 2D spectrum (default: no)"<<endl
+     <<" -N scalemass: facteur d\'unite pour la masse (default: -1)"<<endl
+     <<"               ex: si on veut unites 10^8 Msol -> scalemass=1.e-8"<<endl
+     <<"               si <0 alors facteur=-scalemass*Mpix"<<endl
+     <<" -M schmin,schmax,nsch : min,max mass and nb points for schechter HI"<<endl
+     <<"                         If nsch<0 alors no,bre de points par decade"<<endl
+     <<" -Q naleagal : use quick method for turning ngal to mass"<<endl
+     <<" -R schmassdist.ppf : read mass distribution for trials from file"<<endl
+     <<"               instead of computing it (ONLY if \"-Q\" option is activated)"<<endl
+     <<" -8 sigmaR,R : normalisation du spectre de puissance, R en Mpc"<<endl
+     <<"               (default sigmaR=1, R=8/h100 Mpc)"<<endl
+     <<" -W : write cube in FITS format (complex cube is coded as real cube)"<<endl
+     <<" -P : write cube in PPF format"<<endl
+     <<" -S : write cube slices in PPF format"<<endl
+     <<" -V : compute variance from real space (for check, default: no)"<<endl
+     <<" -T nth : nombre de threads (si compil multi-thread, default: 0)"<<endl
+     <<endl;
+     ////<<" -A <log10(S_agn in Jy at 1.4 GHz)>,sigma,powlaw :"<<endl
+     ////<<"    AGN mean and sigma gaussian equiv. distrib. for solid angle of centeral pixel"<<endl
+     ////<<"    powlaw: apply S_agn evolution as (Nu/1.4)^powlaw"<<endl
+}
+
+int main(int narg,char *arg[])
+{
+ InitTim();
+
+ //-----------------------------------------------------------------
+ // *** Survey definition
+ long nx=360, ny=-1, nz=64; double dx=1., dy=-1., dz=-1.;
+ //long nx=1000, ny=-1, nz=128; double dx=3., dy=-1., dz=6.;
+ //long nx=1200, ny=-1, nz=128; double dx=1., dy=-1., dz=3;
+
+ // *** Cosmography definition   (WMAP)
+ unsigned short flat = 0;
+ double ob0 = 0.0444356;
+ double h100=0.71, om0=0.267804, or0=7.9e-05, ol0=0.73,w0=-1.;
+ double zref = 0.5;
+ double perc=0.01,dzinc=-1.,dzmax=-1.; unsigned short glorder=4;
+
+ // *** Spectrum and variance definition
+ double ns = 1., as = 1.;
+ double R=8./h100, Rg=R/sqrt(5.);
+ double sigmaR = 1.;
+
+ double kmin=1e-5,kmax=1000.;
+ int npt = 10000;
+ double lkmin=log10(kmin), lkmax=log10(kmax);
+ double eps=1.e-3;
+
+ // *** Schechter mass function definition
+ double h75 = h100 / 0.75;
+ double nstar = 0.006*pow(h75,3.);
+ double mstar = pow(10.,9.8);  // MSol
+ double alpha = -1.37;
+
+ double schmin=1.e7, schmax=1.e13;
+ int schnpt = -100;
+ bool use_schmassdist = false;
+ long naleagal = 100000;
+ bool recompute_schmassdist = true;
+ string schmassdistfile = "";
+ bool no_poisson = false;
+ int no_poisson_type = 1;
+
+ double scalemass = -1.;
+
+ // *** Niveau de bruit
+ double snoise= 0.;   // en equivalent MSol
+ int noise_evol = 0;
+
+ //// *** AGN
+ ////bool do_agn = false;
+ ////double lfjy_agn=-99., lsigma_agn=0.;   // en Jy
+ ////double powlaw_agn = 0.;
+
+ // *** type de generation
+ bool computefourier0=false;
+ int use_growth_factor = 0;
+ unsigned short nthread=0;
+ int filter_by_pixel = 1;
+
+ // *** What to do
+ bool comp2dspec = false;
+ bool wfits = false;
+ bool wppf = false;
+ bool wslice = false;
+ bool compvarreal = false;
+
+ // --- Decodage arguments
+ if(narg>0) {
+   cout<<"\n--- Arguments: "<<endl;
+   for(int i=0;i<narg;i++) cout<<arg[i]<<" ";
+   cout<<endl;
+ }
+
+ char c;
+ while((c = getopt(narg,arg,"ha0PWSV2U:G:F:x:y:z:s:Z:M:A:T:N:Q:R:8:")) != -1) {
+  int nth = 0;
+  switch (c) {
+  case 'a' :
+    Auto_Ini_Ranf(5);
+    break;
+  case '0' :
+    computefourier0 = true;
+    break;
+  case 'G' :
+    sscanf(optarg,"%d",&use_growth_factor);
+    break;
+  case 'U' :
+    no_poisson = true;
+    sscanf(optarg,"%d",&no_poisson_type);
+    break;
+  case 'F' :
+    sscanf(optarg,"%d",&filter_by_pixel);
+    break;
+  case 'x' :
+    sscanf(optarg,"%ld,%lf",&nx,&dx);
+    break;
+  case 'y' :
+    sscanf(optarg,"%ld,%lf",&ny,&dy);
+    break;
+  case 'z' :
+    sscanf(optarg,"%ld,%lf",&nz,&dz);
+    break;
+  case 's' :
+    sscanf(optarg,"%lf,%d",&snoise,&noise_evol);
+    break;
+  case 'Z' :
+    sscanf(optarg,"%lf",&zref);
+    break;
+  case '2' :
+    comp2dspec = true;
+    break;
+  case 'N' :
+    sscanf(optarg,"%lf",&scalemass);
+    if(scalemass==0.) scalemass = 1.;
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf,%lf,%d",&schmin,&schmax,&schnpt);
+    break;
+  case 'Q' :
+    use_schmassdist = true;
+    sscanf(optarg,"%ld",&naleagal);
+    break;
+  case 'R' :
+    schmassdistfile = optarg;
+    break;
+    ////  case 'A' :
+    ////do_agn = true;
+    ////sscanf(optarg,"%lf,%lf,%lf",&lfjy_agn,&lsigma_agn,&powlaw_agn);
+    ////break;
+  case '8' :
+    sscanf(optarg,"%lf,%lf",&sigmaR,&R);
+    break;
+  case 'V' :
+    compvarreal = true;
+    break;
+  case 'W' :
+    wfits = true;
+    break;
+  case 'P' :
+    wppf = true;
+    break;
+  case 'S' :
+    wslice = true;
+    break;
+  case 'T' :
+    sscanf(optarg,"%d",&nth);
+    nthread = (nth<1)? 0: nth;
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+
+ double lschmin=log10(schmin), lschmax=log10(schmax);
+ if(schnpt<=0) {  // alors c'est un nombre de points par decade
+   schnpt = long( (-schnpt)*(lschmax-lschmin+1.) + 0.5 );
+   if(schnpt<=2) schnpt = 1000;
+ }
+ if(naleagal<=2) naleagal = 100000;
+
+ cout<<"zref="<<zref<<endl;
+ cout<<"nx="<<nx<<" dx="<<dx<<" ny="<<ny<<" dy="<<dy<<" nz="<<nz<<" dz="<<dz<<endl;
+ cout<<"kmin="<<kmin<<" ("<<lkmin<<"), kmax="<<kmax<<" ("<<lkmax<<") Mpc^-1"
+     <<", npt="<<npt<<endl;
+ cout<<"Filter by pixel = "<<filter_by_pixel<<endl;
+ cout<<"R="<<R<<" Rg="<<Rg<<" Mpc, sigmaR="<<sigmaR<<endl;
+ cout<<"Use_growth_factor = "<<use_growth_factor<<endl;
+ cout<<"nstar= "<<nstar<<"  mstar="<<mstar<<"  alpha="<<alpha<<endl;
+ cout<<"schmin="<<schmin<<" ("<<lschmin
+     <<"), schmax="<<schmax<<" ("<<lschmax<<") Msol"
+     <<", schnpt="<<schnpt<<endl;
+ if(no_poisson) cout<<"No poisson fluctuation, direct conversion to HI mass, typ="
+                    <<no_poisson_type<<endl;
+ cout<<"snoise="<<snoise<<" equivalent Msol, evolution="<<noise_evol<<endl;
+ cout<<"scalemass="<<scalemass<<endl;
+ ////if(do_agn)
+ ////  cout<<"AGN: <log10(Jy)>="<<lfjy_agn<<" , sigma="<<lsigma_agn
+ ////      <<" , powlaw="<<powlaw_agn<<endl;
+
+ string tagobs = "cmvobserv3d.ppf";
+ POutPersist posobs(tagobs);
+
+ //-----------------------------------------------------------------
+ cout<<endl<<"\n--- Create Cosmology"<<endl;
+
+ CosmoCalc univ(flat,true,zref+1.);
+ univ.SetInteg(perc,dzinc,dzmax,glorder);
+ univ.SetDynParam(h100,om0,or0,ol0,w0);
+ univ.PrtInteg();
+ univ.Print();
+ double loscomref = univ.Dloscom(zref);
+ cout<<"\nzref = "<<zref<<" -> dloscom = "<<loscomref<<" Mpc"<<endl;
+ univ.Print(zref);
+
+ //-----------------------------------------------------------------
+ cout<<endl<<"\n--- Create Spectrum"<<endl;
+
+ InitialSpectrum pkini(ns,as);
+
+ TransfertEisenstein tf(h100,om0-ob0,ob0,T_CMB_Par,false);
+ //tf.SetNoOscEnv(2);
+
+ GrowthFactor growth(om0,ol0);
+ // GrowthFactor growth(1.,0.); // D(z) = 1/(1+z)
+ double growth_at_z = growth(zref);
+ cout<<"...Growth factor at z="<<zref<<" = "<<growth_at_z<<endl;
+
+ PkSpectrum0 pk0(pkini,tf);
+
+ PkSpectrumZ pkz(pk0,growth,zref);
+
+ //-----------------------------------------------------------------
+ pkz.SetZ(0.);
+ cout<<endl<<"\n--- Compute variance for top-hat R="<<R
+     <<" at z="<<pkz.GetZ()<<endl;
+ VarianceSpectrum varpk_th(pkz,R,VarianceSpectrum::TOPHAT);
+ double kfind_th = varpk_th.FindMaximum(kmin,kmax,eps);
+ double pkmax_th = varpk_th(kfind_th);
+ cout<<"kfind_th = "<<kfind_th<<" ("<<log10(kfind_th)<<"), integrand="<<pkmax_th<<endl;
+ double k1=kmin, k2=kmax;
+ int rc = varpk_th.FindLimits(pkmax_th/1.e4,k1,k2,eps);
+ cout<<"limit_th: rc="<<rc<<" : "<<k1<<" ("<<log10(k1)<<") , "
+     <<k2<<" ("<<log10(k2)<<")"<<endl;
+
+ double ldlk = (log10(k2)-log10(k1))/npt;
+ varpk_th.SetInteg(0.01,ldlk,-1.,4);
+ double sr2 = varpk_th.Variance(k1,k2);
+ cout<<"varpk_th="<<sr2<<"  ->  sigma="<<sqrt(sr2)<<endl;
+
+ double normpkz = sigmaR*sigmaR/sr2;
+ pkz.SetScale(normpkz);
+ cout<<"Spectrum normalisation = "<<pkz.GetScale()<<endl;
+
+ {
+ Histo hpkz0(lkmin,lkmax,npt); hpkz0.ReCenterBin();
+ FuncToHisto(pkz,hpkz0,true);
+ tagobs = "hpkz0"; posobs.PutObject(hpkz0,tagobs);
+ }
+
+ pkz.SetZ(zref);
+
+ {
+ Histo hpkz(lkmin,lkmax,npt); hpkz.ReCenterBin();
+ FuncToHisto(pkz,hpkz,true);
+ tagobs = "hpkz"; posobs.PutObject(hpkz,tagobs);
+ }
+
+ //-----------------------------------------------------------------
+ cout<<endl<<"\n--- Compute variance for Pk at z="<<pkz.GetZ()<<endl;
+ VarianceSpectrum varpk_int(pkz,R,VarianceSpectrum::NOFILTER);
+
+ double kfind_int = varpk_int.FindMaximum(kmin,kmax,eps);
+ double pkmax_int = varpk_int(kfind_int);
+ cout<<"kfind_int = "<<kfind_int<<" ("<<log10(kfind_int)<<"), integrand="<<pkmax_int<<endl;
+ double k1int=kmin, k2int=kmax;
+ int rcint = varpk_int.FindLimits(pkmax_int/1.e4,k1int,k2int,eps);
+ cout<<"limit_int: rc="<<rcint<<" : "<<k1int<<" ("<<log10(k1int)<<") , "
+     <<k2int<<" ("<<log10(k2int)<<")"<<endl;
+
+ double ldlkint = (log10(k2int)-log10(k1int))/npt;
+ varpk_int.SetInteg(0.01,ldlkint,-1.,4);
+ double sr2int = varpk_int.Variance(k1int,k2int);
+ cout<<"varpk_int="<<sr2int<<"  ->  sigma="<<sqrt(sr2int)<<endl;
+ 
+ //-----------------------------------------------------------------
+ cout<<endl<<"\n--- Create mass function, compute number/mass density, init mass trials"<<endl;
+
+ Schechter sch(nstar,mstar,alpha);
+ sch.Print();
+
+ sch.SetOutValue(0);
+ cout<<"sch(mstar) = "<<sch(mstar)<<" /Mpc^3/Msol"<<endl;
+ double ngal_by_mpc3 = sch.Integrate(schmin,schmax,schnpt);
+ cout<<"Galaxy density number = "<<ngal_by_mpc3<<" /Mpc^3 between limits"<<endl;
+
+ sch.SetOutValue(1);
+ cout<<"mstar*sch(mstar) = "<<sch(mstar)<<" Msol/Mpc^3/Msol"<<endl;
+ double mass_by_mpc3 = sch.Integrate(schmin,schmax,schnpt);
+ cout<<"Galaxy mass density= "<<mass_by_mpc3<<" Msol/Mpc^3 between limits"<<endl;
+ cout<<"Omega_HI at z=0 is "<<mass_by_mpc3/(univ.Rhoc(0.)*GCm3toMsolMpc3_Cst)<<endl
+     <<"         at z="<<zref<<" is "<<mass_by_mpc3/(univ.Rhoc(zref)*GCm3toMsolMpc3_Cst)<<endl;
+
+ SchechterMassDist schmdist(sch,schmin,schmax,schnpt);
+ if(use_schmassdist && schmassdistfile.size()>0) {
+   cout<<"\nSchechterMassDist read from "<<schmassdistfile<<endl;
+   schmdist.ReadPPF(schmassdistfile);
+   bool compsch = IsCompatible(sch,schmdist.GetSchechter());
+   double m1,m2; schmdist.GetMassLim(m1,m2);
+   if( !compsch || fabs(m1-schmin)>1e-4*schmin || fabs(m2-schmax)>1e-4*schmax) {
+     cout<<"FATAL_ERROR: INCONSISTENT SchechterMassDist file / Schechter or limits"<<endl;
+     cout<<"Schechter:"<<endl; sch.Print();
+     cout<<"schmin="<<schmin<<" schmax="<<schmax<<endl;
+     cout<<"SchechterMassDist:"<<endl; schmdist.Print();
+     return -10;
+   }
+   recompute_schmassdist = false;
+ }
+ schmdist.Print();
+ Histo hmdndm = schmdist.GetHmDnDm();
+ FunRan tirhmdndm = schmdist.GetTmDnDm();
+ {
+ tagobs = "hmdndm"; posobs.PutObject(hmdndm,tagobs);
+ Histo hdum1(tirhmdndm);
+ tagobs = "tirhmdndm"; posobs.PutObject(hdum1,tagobs);
+ }
+
+ PrtTim(">>>> End of definition");
+
+ //-----------------------------------------------------------------
+ // FFTW3 (p26): faster if sizes 2^a 3^b 5^c 7^d 11^e 13^f  with e+f=0 ou 1
+ cout<<endl<<"\n--- Initialisation de GeneFluct3D"<<endl;
+
+ GeneFluct3D fluct3d(nx,ny,nz,dx,dy,dz,nthread,2);
+ fluct3d.SetObservator(zref,-nz/2.);
+ fluct3d.SetCosmology(univ);
+ fluct3d.SetGrowthFactor(growth);
+ fluct3d.LosComRedshift(0.001,-1);
+ TArray< complex<r_8> >& pkgen = fluct3d.GetComplexArray();
+ TArray<r_8>& rgen = fluct3d.GetRealArray();
+ cout<<endl; fluct3d.Print();
+ cout<<"\nMean number of galaxies per pixel = "<<ngal_by_mpc3*fluct3d.GetDVol()<<endl;
+ double mass_by_pixel = mass_by_mpc3 * fluct3d.GetDVol();
+ cout<<"Mean mass per pixel = "<<mass_by_pixel<<endl;
+
+ double dkmin = fluct3d.GetKincMin();
+ double knyqmax = fluct3d.GetKmax();
+ long nherr = long(knyqmax/dkmin+0.5);
+ cout<<"\nFor HistoErr: d="<<dkmin<<" max="<<knyqmax<<" n="<<nherr<<endl;
+
+ double dktmin = fluct3d.GetKTincMin();
+ double ktnyqmax = fluct3d.GetKTmax();
+ long nherrt = long(ktnyqmax/dktmin+0.5);
+ double dkzmin = fluct3d.GetKinc()[2];
+ double kznyqmax = fluct3d.GetKnyq()[2];
+ long nherrz = long(kznyqmax/dkzmin+0.5);
+ cout<<"For Histo2DErr: d="<<dktmin<<","<<dkzmin
+     <<" max="<<ktnyqmax<<","<<kznyqmax<<" n="<<nherrt<<","<<nherrz<<endl;
+
+ //-----------------------------------------------------------------
+ cout<<"\n--- Computing spectra variance up to Kmax at z="<<pkz.GetZ()<<endl;
+ // En fait on travaille sur un cube inscrit dans la sphere de rayon kmax:
+ // sphere: Vs = 4Pi/3 k^3 , cube inscrit (cote k*sqrt(2)): Vc = (k*sqrt(2))^3
+ // Vc/Vs = 0.675   ->  keff = kmax * (0.675)^(1/3) = kmax * 0.877
+ double knyqmax_mod = 0.877*knyqmax;
+ ldlkint = (log10(knyqmax_mod)-log10(k1int))/npt;
+ varpk_int.SetInteg(0.01,ldlkint,-1.,4);
+ double sr2int_kmax = varpk_int.Variance(k1int,knyqmax_mod);
+ cout<<"varpk_int(<"<<knyqmax_mod<<")="<<sr2int_kmax<<"  ->  sigma="<<sqrt(sr2int_kmax)<<endl;
+
+ PrtTim(">>>> End Initialisation de GeneFluct3D");
+
+ //-----------------------------------------------------------------
+ cout<<"\n--- Computing a realization in Fourier space"<<endl;
+ if(use_growth_factor>0) pkz.SetZ(0.); else pkz.SetZ(zref);
+ cout<<"Power spectrum set at redshift: "<<pkz.GetZ()<<endl;
+ if(computefourier0) fluct3d.ComputeFourier0(pkz);
+   else              fluct3d.ComputeFourier(pkz);
+ PrtTim(">>>> End Computing a realization in Fourier space");
+
+ cout<<"\n--- Checking realization spectra"<<endl;
+ HistoErr hpkgen(0.,knyqmax,nherr);
+ hpkgen.ReCenterBin(); hpkgen.Zero();
+ hpkgen.Show();
+ fluct3d.ComputeSpectrum(hpkgen);
+ {
+ tagobs = "hpkgen"; posobs.PutObject(hpkgen,tagobs);
+ }
+ PrtTim(">>>> End Checking realization spectra");
+
+ if(comp2dspec) {
+   cout<<"\n--- Checking realization 2D spectra"<<endl;
+   Histo2DErr hpkgen2(0.,ktnyqmax,nherrt,0.,kznyqmax,nherrz);
+   hpkgen2.ReCenterBin(); hpkgen2.Zero();
+   hpkgen2.Show();
+   fluct3d.ComputeSpectrum2D(hpkgen2);
+   {
+   tagobs = "hpkgen2"; posobs.PutObject(hpkgen2,tagobs);
+   }
+   PrtTim(">>>> End Checking realization 2D spectra");
+ }
+
+ if(filter_by_pixel!=0) {
+   cout<<"\n--- Computing convolution by pixel shape"<<endl;
+   fluct3d.FilterByPixel();
+   PrtTim(">>>> End Computing convolution by pixel shape");
+
+   cout<<"\n--- Checking realization spectra after pixel shape convol."<<endl;
+   HistoErr hpkgenfb(0.,knyqmax,nherr);
+   hpkgenfb.ReCenterBin(); hpkgenfb.Zero();
+   hpkgenfb.Show();
+   fluct3d.ComputeSpectrum(hpkgenfb);
+   {
+   tagobs = "hpkgenfb"; posobs.PutObject(hpkgenfb,tagobs);
+   }
+   PrtTim(">>>> End Checking realization spectra");
+
+   cout<<"\n--- Checking realization spectra after pixel shape convol. with pixel correc."<<endl;
+   HistoErr hpkgenf(hpkgenfb); hpkgenf.Zero();
+   fluct3d.ComputeSpectrum(hpkgenf,0.,filter_by_pixel);
+   {
+   tagobs = "hpkgenf"; posobs.PutObject(hpkgenf,tagobs);
+   }
+   PrtTim(">>>> End Checking realization spectra with pixel correc.");
+
+   if(comp2dspec) {
+     cout<<"\n--- Checking realization 2D spectra after pixel shape convol."<<endl;
+     Histo2DErr hpkgenfb2(0.,ktnyqmax,nherrt,0.,kznyqmax,nherrz);
+     hpkgenfb2.ReCenterBin(); hpkgenfb2.Zero();
+     hpkgenfb2.Show();
+     fluct3d.ComputeSpectrum2D(hpkgenfb2);
+     {
+     tagobs = "hpkgenfb2"; posobs.PutObject(hpkgenfb2,tagobs);
+     }
+     PrtTim(">>>> End Checking realization 2D spectra");
+
+     cout<<"\n--- Checking realization 2D spectra after pixel shape convol. with pixel correc."<<endl;
+     Histo2DErr hpkgenf2(hpkgenfb2); hpkgenf2.Zero();
+     fluct3d.ComputeSpectrum2D(hpkgenf2,0.,filter_by_pixel);
+     {
+     tagobs = "hpkgenf2"; posobs.PutObject(hpkgenf2,tagobs);
+     }
+     PrtTim(">>>> End Checking realization 2D spectra with pixel correc.");
+   }
+ }
+
+ if(wfits) {
+   fluct3d.WriteFits("!cmvobserv3d_k0.fits");
+   PrtTim(">>>> End WriteFits");
+ }
+ if(wppf) {
+   fluct3d.WritePPF("cmvobserv3d_k0.ppf",false);
+   PrtTim(">>>> End WritePPF");
+ }
+
+ //-----------------------------------------------------------------
+ cout<<"\n--- Computing a realization in real space"<<endl;
+ fluct3d.ComputeReal();
+ double rmin,rmax; fluct3d.MinMax(rmin,rmax);
+ cout<<"rgen.Min = "<<rmin<<" , Max="<<rmax<<endl;
+ PrtTim(">>>> End Computing a realization in real space");
+
+ if(use_growth_factor>0) {
+   cout<<"\n--- Apply Growth factor"<<endl;
+   cout<<"...D(z=0)="<<growth(0.)<<"  D(z="<<zref<<")="<<growth(zref)<<endl;
+   fluct3d.ApplyGrowthFactor(use_growth_factor);
+   fluct3d.MinMax(rmin,rmax);
+   cout<<"rgen.Min = "<<rmin<<" , Max="<<rmax<<endl;
+   PrtTim(">>>> End Applying growth factor");
+ }
+
+ int_8 nm;
+ double rmref,rs2ref;
+ cout<<"\n--- Computing reference variance in real space"<<endl;
+ nm = fluct3d.MeanSigma2(rmref,rs2ref);
+ cout<<" rs2ref= "<<rs2ref<<" , rmref="<<rmref<<" ("<<nm<<")"<<endl;
+ PrtTim(">>>> End Computing reference variance in real space");
+
+ if(wfits) {
+   fluct3d.WriteFits("!cmvobserv3d_r0.fits");
+   PrtTim(">>>> End WriteFits");
+ }
+ if(wppf) {
+   fluct3d.WritePPF("cmvobserv3d_r0.ppf",true);
+   PrtTim(">>>> End WritePPF");
+ }
+ if(wslice) {
+   fluct3d.WriteSlicePPF("cmvobserv3d_s_r0.ppf");
+   PrtTim(">>>> End WriteSlicePPF");
+ }
+
+ cout<<"\n--- Check mean and variance in real space"<<endl;
+ fluct3d.NumberOfBad(-1.,1e+200);
+ double rm,rs2;
+ nm = fluct3d.MeanSigma2(rm,rs2);
+ PrtTim(">>>> End Check mean and variance in real space");
+
+ if(compvarreal) {
+   cout<<"\n--- Check variance sigmaR in real space"<<endl;
+   double varr;
+   fluct3d.VarianceFrReal(R,varr);
+   cout<<"...Computed variance = "<<varr
+       <<" , Theorical variance at (z=0) = "<<pow(sigmaR,2.)
+       <<" , at (z="<<zref<<") = "<<pow(sigmaR*growth_at_z,2.)<<endl;
+   PrtTim(">>>> End Check variance sigmaR in real space");
+ }
+
+ //-----------------------------------------------------------------
+ if(no_poisson) {
+   cout<<"\n--- Converting !!!DIRECTLY!!! mass into HI mass: mass per pixel ="
+       <<mass_by_pixel<<endl;
+   if(no_poisson_type<0) {
+     cout<<"!!!WARNING!!! dRho/Rho is just multiplied by "<<mass_by_pixel<<endl;
+     fluct3d.ScaleOffset(mass_by_pixel);
+   } else {
+     rm = fluct3d.TurnFluct2MeanNumber(mass_by_mpc3); // ici on doit donner Msol/Mpc^3
+   }
+ } else {
+   cout<<"\n--- Converting mass into galaxy number: gal per pixel ="
+       <<ngal_by_mpc3*fluct3d.GetDVol()<<endl;
+   rm = fluct3d.TurnFluct2MeanNumber(ngal_by_mpc3); // ici on doit donner Ngal/Mpc^3
+ }
+ nm = fluct3d.MeanSigma2(rm,rs2,0.,1e200);
+ nm = fluct3d.MeanSigma2(rm,rs2);
+ if(rm>0.) cout<<"normalised sigma(dM/M) is "<<sqrt(rs2)/rm<<endl;
+ PrtTim(">>>> End Converting mass into galaxy number or mass");
+
+ if( !no_poisson ) {
+
+   cout<<"\n--- Apply poisson on galaxy number"<<endl;
+   fluct3d.ApplyPoisson();
+     nm = fluct3d.MeanSigma2(rm,rs2,0.,1e200);
+     nm = fluct3d.MeanSigma2(rm,rs2);
+   double xgalmin,xgalmax; fluct3d.MinMax(xgalmin,xgalmax,0.1,1.e50);
+   PrtTim(">>>> End Apply poisson on galaxy number");
+   if(wslice) {
+     fluct3d.WriteSlicePPF("cmvobserv3d_s_rn.ppf");
+     PrtTim(">>>> End WriteSlicePPF");
+   }
+
+   cout<<"\n--- Convert Galaxy number to HI mass"<<endl;
+   double mhi = 0.;
+   if(use_schmassdist) {
+     if(recompute_schmassdist) {
+       int ngalmax = int(xgalmax+0.5);
+       schmdist.SetNgalLim(ngalmax,1,naleagal);
+       PrtTim(">>>> End creating tabulated histograms for trials");
+     }
+     mhi = fluct3d.TurnNGal2MassQuick(schmdist);
+     schmdist.PrintStatus();
+   } else {
+     mhi = fluct3d.TurnNGal2Mass(tirhmdndm,true);
+   }
+   cout<<mhi<<" MSol in survey / "<<mass_by_mpc3*fluct3d.GetVol()<<endl;
+     nm = fluct3d.MeanSigma2(rm,rs2,0.,1e200);
+     cout<<"Equivalent: "<<rm*nm/fluct3d.NPix()<<" Msol / pixels"<<endl;
+     nm = fluct3d.MeanSigma2(rm,rs2);
+   PrtTim(">>>> End Convert Galaxy number to HI mass");
+
+ }
+
+ //-----------------------------------------------------------------
+ if(wfits) {
+   fluct3d.WriteFits("!cmvobserv3d_r.fits");
+   PrtTim(">>>> End WriteFits");
+ }
+ if(wppf) {
+   fluct3d.WritePPF("cmvobserv3d_r.ppf",true);
+   PrtTim(">>>> End WritePPF");
+ }
+ if(wslice) {
+   fluct3d.WriteSlicePPF("cmvobserv3d_s_r.ppf");
+   PrtTim(">>>> End WriteSlicePPF");
+ }
+
+ //-----------------------------------------------------------------
+ ////if(do_agn) {
+ ////  cout<<"\n--- Add AGN: <log10(S Jy)>="<<lfjy_agn<<" , sigma="<<lsigma_agn
+ ////      <<" , powlaw="<<powlaw_agn<<endl;
+ ////  fluct3d.AddAGN(lfjy_agn,lsigma_agn,powlaw_agn);
+ ////    nm = fluct3d.MeanSigma2(rm,rs2);
+ ////   PrtTim(">>>> End Add AGN");
+ ////}
+
+ //-----------------------------------------------------------------
+ double snoisesave = 0.;
+ if(snoise>0.) {
+   cout<<"\n--- Add noise to HI Flux snoise="<<snoise<<", evolution="<<noise_evol<<endl;
+   fluct3d.AddNoise2Real(snoise,noise_evol);
+   snoisesave = snoise;
+     nm = fluct3d.MeanSigma2(rm,rs2);
+   PrtTim(">>>> End Add noise");
+ }
+
+ //-----------------------------------------------------------------
+ if(scalemass!=0. && scalemass!=1.) {  // Si scalemass==0 pas de normalisation
+   if(scalemass<0.) scalemass = 1. / (-scalemass * mass_by_pixel);
+   cout<<"\n--- Scale cube scale="<<scalemass<<endl;
+   fluct3d.ScaleOffset(scalemass);
+   snoisesave *= scalemass;
+     nm = fluct3d.MeanSigma2(rm,rs2);
+   PrtTim(">>>> End Scale cube");
+ }
+
+ //----------------------------------------------------------------- 
+ if(wfits) {
+   fluct3d.WriteFits("!cmvobserv3d_rf.fits");
+   PrtTim(">>>> End WriteFits");
+ }
+ if(wppf) {
+   fluct3d.WritePPF("cmvobserv3d_rf.ppf",true);
+   PrtTim(">>>> End WritePPF");
+ }
+ if(wslice) {
+   fluct3d.WriteSlicePPF("cmvobserv3d_s_rf.ppf");
+   PrtTim(">>>> End WriteSlicePPF");
+ }
+
+ //-----------------------------------------------------------------
+ // -- NE PAS FAIRE CA SI ON VEUT CONTINUER LA SIMULATION -> d_rho/rho ecrase
+ 
+ cout<<endl<<"\n--- ReComputing spectrum from real space"<<endl;
+ fluct3d.ReComputeFourier();
+ PrtTim(">>>> End ReComputing spectrum");
+
+ if(wfits) {
+   fluct3d.WriteFits("!cmvobserv3d_k.fits");
+   PrtTim(">>>> End WriteFits");
+ }
+ if(wppf) {
+   fluct3d.WritePPF("cmvobserv3d_k.ppf",false);
+   PrtTim(">>>> End WritePPF");
+ }
+
+ cout<<endl<<"\n--- Computing final spectrum"<<endl;
+ HistoErr hpkrecb(0.,knyqmax,nherr); hpkrecb.Zero();
+ hpkrecb.ReCenterBin();
+ hpkrecb.Show();
+ fluct3d.ComputeSpectrum(hpkrecb);
+ {
+ tagobs = "hpkrecb"; posobs.PutObject(hpkrecb,tagobs);
+ }
+ PrtTim(">>>> End Computing final spectrum");
+
+ cout<<endl<<"\n--- Computing final spectrum with pixel deconv."<<endl;
+ HistoErr hpkrec(hpkrecb); hpkrec.Zero();
+ fluct3d.ComputeSpectrum(hpkrec,snoisesave,filter_by_pixel);
+ {
+ tagobs = "hpkrec"; posobs.PutObject(hpkrec,tagobs);
+ }
+ PrtTim(">>>> End Computing final spectrum with pixel deconv.");
+
+ if(comp2dspec) {
+   cout<<"\n--- Computing final 2D spectrum"<<endl;
+   Histo2DErr hpkrecb2(0.,ktnyqmax,nherrt,0.,kznyqmax,nherrz);
+   hpkrecb2.ReCenterBin(); hpkrecb2.Zero();
+   hpkrecb2.Show();
+   fluct3d.ComputeSpectrum2D(hpkrecb2);
+   {
+   tagobs = "hpkrecb2"; posobs.PutObject(hpkrecb2,tagobs);
+   }
+   PrtTim(">>>> End Computing final 2D spectrum");
+
+   cout<<"\n--- Computing final 2D spectrum with pixel deconv."<<endl;
+   Histo2DErr hpkrec2(hpkrecb2); hpkrec2.Zero();
+   fluct3d.ComputeSpectrum2D(hpkrec2,snoisesave,filter_by_pixel);
+   {
+   tagobs = "hpkrec2"; posobs.PutObject(hpkrec2,tagobs);
+   }
+   PrtTim(">>>> End Computing final 2D spectrum with pixel deconv.");
+
+ }
+
+ PrtTim(">>>> End Of Job");
+ return 0;
+}
+
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvschdist.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvschdist.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvschdist.cc	(revision 3445)
@@ -0,0 +1,255 @@
+/* Distributions de masse pour n=1,2,3,... tirages */
+#include "sopnamsp.h"
+#include "machdefs.h"
+// Pour faire les histogrammes des distributions de masses
+//  pour ntirages:
+// ex: on a un pixel qui a N galaxies, quelle est la distribution
+//     statistique de masse dans un tel pixel ?
+// > cmvschdist -a -v -m 1e+7,1e+13 -n -100 -r 200 -N 100000
+// compare with:
+// > cmvschdist -a -v -m 1e+7,1e+13 -n -100 -r 200 -N 100000 -0
+// Fabriquer un fichier pour la prod
+// > cmvschdist -a -m 1e+7,1e+13 -n -100 -r 2000 -N 5000000 -W schdist_2000.ppf
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "histos.h"
+#include "ntuple.h"
+#include "srandgen.h"
+#include "perandom.h"
+
+#include "geneutils.h"
+#include "cosmocalc.h"
+#include "schechter.h"
+
+#include <vector>
+
+void usage(void);
+void usage(void)
+{
+ cout<<"cmvschdist -m xmin,xmax -a -0 -n nbin -r ngmax,ngmin -N nalea "
+     <<"-R readfile.ppf -W writefile.ppf"<<endl
+     <<"  -m xmin,xmax : limites en masse"<<endl
+     <<"  -n nbin : nombre de bins (si <0 alors nb par decade)"<<endl
+     <<"  -r ngmax,ngmin : distribution pour tirage de ngmin a ngmax galaxies"<<endl
+     <<"  -N nalea : nombre de tirages aleatoires"<<endl
+     <<"  -v : back verification of random trials"<<endl
+     <<"  -0 : only use ngal=1 histogram"<<endl
+     <<"  -a : init auto de l\'aleatoire"<<endl
+     <<"  -R readfile.ppf : read SchechterMassDist from ppf file"<<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ double h75 = 0.71 / 0.75;
+ double nstar = 0.006*pow(h75,3.);  //  
+ double mstar = pow(10.,9.8);  // MSol
+ double alpha = -1.37;
+ cout<<"h75= "<<h75<<" nstar= "<<nstar<<"  mstar="<<mstar<<"  alpha="<<alpha<<endl;
+
+ double xmin=1.e7, xmax=1.e13;
+ int npt = -100;
+ int ngmax = 200, ngmin = 1;
+ bool useonly1 = false;
+ unsigned long long nalea = 10000;
+ bool verif = false;
+ bool readfrppf = false;
+ string namefrppf = "";
+ string nametoppf = "";
+
+ char c;
+ while((c = getopt(narg,arg,"h0avm:N:n:r:R:W:")) != -1) {
+   switch (c) {
+   case 'm' :
+     sscanf(optarg,"%lf,%lf",&xmin,&xmax);
+     if(xmin<=0.) xmin=1e6;
+     if(xmax<=0.) xmax=xmin;
+     if(xmin>xmax) xmax=10.*xmin;
+     break;
+   case 'r' :
+     sscanf(optarg,"%d,%d",&ngmax,&ngmin);
+     if(ngmin<=0) ngmin=1;
+     if(ngmax<=0) ngmax=ngmin;
+     if(ngmin>ngmax) ngmin=ngmax;
+     break;
+   case 'n' :
+     sscanf(optarg,"%d",&npt);
+     if(npt<=0) npt = -100;
+     break;
+   case 'N' :
+     sscanf(optarg,"%llu",&nalea);
+     if(nalea<=0) nalea=10000;
+     break;
+   case 'v' :
+     verif = true;
+     break;
+   case '0' :
+     useonly1 = true;
+     break;
+   case 'R' :
+     readfrppf = true;
+     namefrppf = optarg;
+     break;
+   case 'W' :
+     nametoppf = optarg;
+     break;
+   case 'a' :
+     Auto_Ini_Ranf(5);
+     break;
+   case 'h' :
+   default :
+     usage(); return -1;
+   }
+ }
+
+ double lnx1=log10(xmin), lnx2=log10(xmax);
+ cout<<"xmin="<<xmin<<" ("<<lnx1<<") xmax="<<xmax<<" ("<<lnx2<<")"<<endl;
+ cout<<"npt="<<npt<<",  nalea="<<nalea<<endl;
+ cout<<"useonly1="<<useonly1<<" ngmin="<<ngmin<<" ngmax="<<ngmax<<endl;
+ cout<<"verif="<<verif<<endl;
+ if(readfrppf) cout<<"SchechterMassDist will be read from file "<<namefrppf<<endl;
+ if(nametoppf.size()>0) cout<<"SchechterMassDist will be written to file "<<nametoppf<<endl;
+
+
+ //-------m*dn/dm
+ cout<<"> Schechter m*dn/dm nstar="<<nstar<<" mstar="<<mstar<<" alpha="<<alpha<<endl;
+ Schechter sch(nstar,mstar,alpha);
+
+ //------- Construct Mass Distribution
+ cout<<"> Creating  Mass Distribution"<<endl;
+ SchechterMassDist schdmass(sch,xmin,xmax,npt);
+ if(readfrppf) {
+   cout<<"> Mass Distribution read from "<<namefrppf<<endl;
+   schdmass.ReadPPF(namefrppf);
+ }
+ Histo hmdndm = schdmass.GetHmDnDm();
+ FunRan tirhmdndm = schdmass.GetTmDnDm();
+
+ //------- Random
+ InitTim();
+ if(!useonly1 && !readfrppf) {
+   cout<<"> Creating "<<ngmax-ngmin+1<<" histos and filling with  "<<nalea<<" trials"<<endl;
+   schdmass.SetNgalLim(ngmax,ngmin,nalea);
+   PrtTim("End of filling histos for trials");
+ }
+ schdmass.Print();
+
+ //------- Generation des histos de verif
+ vector<Histo> vthisto; vector<string> vthname;
+ if(verif) {
+   cout<<"> Creating "<<ngmax-ngmin+1<<" Histos for back-verif"<<endl;
+   for(int i=ngmin;i<=ngmax;i++) {
+     Histo h(hmdndm); h.Zero();
+     vthisto.push_back(h);
+     char str[32]; sprintf(str,"th%d",i);
+     vthname.push_back(string(str));
+   }
+   cout<<"   "<<vthisto.size()<<" Histos created"<<endl;
+   vthisto[20].Show();
+
+   cout<<"> Checking tirage"<<endl;
+   int lpmod = nalea/20; if(lpmod<=0) lpmod=1;
+   for(unsigned long long ia=0;ia<nalea;ia++) {
+     if(ia%lpmod==0) cout<<"...filling tirage "<<ia<<endl;
+     for(unsigned int i=0;i<vthisto.size();i++) {
+       int ng = ngmin+i;
+       double v = schdmass.TirMass(ng)/(double)ng;
+       vthisto[i].Add(log10(v));
+     }
+   }
+   schdmass.PrintStatus();
+   PrtTim("End Random loop back-tirage");
+ }
+
+ //------- Ecritures ppf
+ if(nametoppf.size()>0) {
+   cout<<"Ecriture de l\'objet SchechterMassDist dans "<<nametoppf<<endl;
+   schdmass.WritePPF(nametoppf);
+ }
+
+ cout<<"Ecriture pour verification"<<endl;
+ string tag = "cmvschdist.ppf";
+ POutPersist pos(tag);
+ {
+ cout<<"  writing hmdndm tirhmdndm"<<endl;
+ tag = "hmdndm"; pos.PutObject(hmdndm,tag);
+ Histo hdum(tirhmdndm);
+ tag = "tirhmdndm"; pos.PutObject(hdum,tag);
+ }
+ if(schdmass.GetNgalLim()>0) {
+   cout<<"  writing h t"<<endl;
+   for(int i=0;i<schdmass.GetNgalLim();i++) {
+     int ng = schdmass.NGalFrIndex(i);
+     if(ng<=0) continue;
+     char str[32];
+     sprintf(str,"h%d",ng);
+     Histo hdum = schdmass.GetHisto(i);
+     tag = str; pos.PutObject(hdum,tag);
+     sprintf(str,"t%d",ng);
+     Histo hdum2(schdmass.GetFunRan(i));
+     tag = str; pos.PutObject(hdum2,tag);
+   }
+ }
+ if(vthisto.size()>0) {
+  cout<<"  writing th"<<endl;
+  for(unsigned int i=0;i<vthisto.size();i++)
+     if(vthisto[i].NEntries()>0) pos.PutObject(vthisto[i],vthname[i]);
+ }
+
+ PrtTim("End of Job");
+
+ return 0;
+}
+
+/*
+delobjs *
+openppf cmvschdist.ppf
+
+set n 70
+echo ${h70.vmax}
+
+set h h$n
+set t t$n
+set th th$n
+
+disp tirhmdndm
+disp $t "same red"
+
+disp $h
+disp $th "same red"
+
+n/plot $h.val%x ! ! "connectpoints"
+n/plot $th.val%x ! ! "nsta connectpoints same red"
+
+n/plot $h.log10(val)%x val>0. ! "connectpoints"
+n/plot $th.log10(val)%x val>0. ! "nsta connectpoints same red"
+
+n/plot $h.val%pow(10.,x) ! ! "connectpoints"
+n/plot $th.val%pow(10.,x) ! ! "nsta connectpoints same red"
+
+c++exec \
+for(int i=0;i<$h.NBins();i++) \
+  if($h(i)>0.) { \
+  cout<<i<<" m="<<$h.BinCenter(i)<<" ("<<pow(10.,$h.BinCenter(i))<<") h="<<$h(i)<<endl; \
+  break; \
+} \
+for(int i=$h.NBins()-1;i>=0;i--) \
+  if($h(i)>0.) { \
+  cout<<i<<" m="<<$h.BinCenter(i)<<" ("<<pow(10.,$h.BinCenter(i))<<") h="<<$h(i)<<endl; \
+  break; \
+}
+
+# Compare evolution
+disp h2000               
+disp h1000 "same red"        
+disp h500 "same blue"        
+disp h200 "same green"     
+disp h100 "same red"
+disp h50 "same blue"
+disp h10 "same green"
+disp h1 "same yellow"
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtgrowth.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtgrowth.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtgrowth.cc	(revision 3445)
@@ -0,0 +1,63 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "cosmocalc.h"
+#include "pkspectrum.h"
+
+void usage(void);
+void usage(void) {cout<<"cmvtgrowth z1,z2,dz [Omatter0,Lambda0]"<<endl;}
+
+void tstprint(CosmoCalc& univ,double z1,double z2,double dz);
+void tstspeed(CosmoCalc& univ,double z1,double z2,double dz);
+void tstntuple(CosmoCalc& univ,double z1,double z2,double dz);
+
+int main(int narg,char *arg[])
+{
+
+ double z1=0., z2=10., dz=1.;
+ if(narg>1) sscanf(arg[1],"%lf,%lf,%lf",&z1,&z2,&dz);
+ cout<<"z1="<<z1<<"  z2="<<z2<<"  dz="<<dz<<endl;
+
+ double om0=0.267804, ol0=0.73;
+ if(narg>2) sscanf(arg[2],"%lf,%lf",&om0,&ol0);
+ cout<<"Om0="<<om0<<"  Ol0="<<ol0<<endl;
+
+ GrowthFactor growth(om0,ol0);
+ cout<<"D1(z=0) = "<<growth(0.)<<endl;
+
+ const int n = 2;
+ char *vname[n] = {"z","d1"};
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   xnt[0]  = z;
+   xnt[1]  = growth(z);
+   nt.Fill(xnt);
+ }
+
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtgrowth.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+
+ return 0;
+}
+
+
+/*
+openppf cmvtgrowth.ppf
+
+set cut 1
+set cut z<5
+
+n/plot nt.d1%z $cut ! "nsta connectpoints"
+n/plot nt.1./(1.+z)%z $cut ! "nsta connectpoints red same"
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtinterp.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtinterp.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtinterp.cc	(revision 3445)
@@ -0,0 +1,163 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "cosmocalc.h"
+#include "geneutils.h"
+
+int main(int narg,char *arg[])
+{
+ double zmax = 2.5;
+ unsigned short flat = 0;
+ // -- WMAP
+ double h100=0.71, om0=0.267804, or0=7.9e-05, ol0=0.73,w0=-1.;
+ // -- ouvert matter only
+ //double h100=0.71, om0=0.3, or0=0., ol0=0.,w0=-1.;
+ // -- plat matter only
+ //double h100=0.71, om0=1., or0=0., ol0=0.,w0=-1.; flat = 1;
+ // -- plat lambda only
+ //double h100=0.71, om0=0., or0=0., ol0=1.,w0=-1.; flat = 2;
+
+ // --- la cosmologie
+ double perc=0.01,dzinc=-1.,dzmax=5.; unsigned short glorder=4;
+ cout<<" perc="<<perc<<" dzinc="<<dzinc<<" dzmax="<<dzmax<<" glorder="<<glorder<<endl;
+ CosmoCalc univ(flat,true,zmax);
+ univ.SetInteg(perc,dzinc,dzmax,glorder);
+ univ.SetDynParam(h100,om0,or0,ol0,w0);
+ univ.Print();
+
+ // --- Remplissage de Dloscom en fct de z
+ int_4 lmod=10 , nzfin = lmod*100;
+ cout<<"Remplissage de loscom vs z: nzfin="<<nzfin<<" , lmod="<<lmod<<endl;
+ vector<double> zfin, dlcfin;
+ vector<double> zgros, dlcgros;
+ for(int_4 i=0;i<=nzfin;i++) {
+   double z = i*zmax/(nzfin-1.);
+   double loscom = univ.Dloscom(z); // pour test:  loscom = z*(z+4);
+   zfin.push_back(z); dlcfin.push_back(loscom);
+   if(i%lmod==0) { // ATTENTION il faut etre equidistant en z !
+     zgros.push_back(z);
+     dlcgros.push_back(loscom);
+   }
+ }
+ nzfin = zfin.size();
+ printf("Fin: z(%d) : [%f,%f]  -> loscom : [%f,%f]\n"
+       ,nzfin,zfin[0],zfin[nzfin-1],dlcfin[0],dlcfin[nzfin-1]);
+ int_4 nzgros = zgros.size();
+ printf("Gros: z(%d) : [%f,%f]  -> loscom : [%f,%f]\n"
+       ,nzgros,zgros[0],zgros[nzgros-1],dlcgros[0],dlcgros[nzgros-1]);
+
+ // --- Check interpolation en z
+ cout<<"Check interpolation en z"<<endl;
+ InterpFunc interpgros(zgros[0],zgros[nzgros-1],dlcgros);
+ double xnt[10];
+ vector<string> noms;
+ noms.push_back("z"); noms.push_back("d");
+ noms.push_back("d0"); noms.push_back("d1"); noms.push_back("d2");
+ NTuple ntg(noms);
+ for(int_4 i=0;i<nzfin;i++) {
+   unsigned short ok;
+   double z = zfin[i];
+   xnt[0] = z;
+   xnt[1] = dlcfin[i];
+   xnt[2] = interpgros(z);
+   xnt[3] = interpgros.Linear(z,ok);
+   xnt[4] = interpgros.Parab(z,ok);
+   ntg.Fill(xnt);
+ }
+
+ // --- Check interpolation en los avec inversion
+ cout<<"Check interpolation en los avec inversion"<<endl;
+ InverseFunc invfun(zgros,dlcgros);
+ vector<double> zbackl;
+ invfun.ComputeLinear(nzfin,zbackl);
+ vector<double> zbackp;
+ invfun.ComputeParab(nzfin,zbackp);
+ printf("YMin=%f , YMax=%f\n",invfun.YMin(),invfun.YMax());
+ printf("Linear ZBack: z(%d) : [%f,%f]\n"
+       ,zbackl.size(),zbackl[0],zbackl[zbackl.size()-1]);
+ printf("Parab ZBack: z(%d) : [%f,%f]\n"
+       ,zbackp.size(),zbackp[0],zbackp[zbackp.size()-1]);
+
+ InterpFunc interpinvl(invfun.YMin(),invfun.YMax(),zbackl);
+ InterpFunc interpinvp(invfun.YMin(),invfun.YMax(),zbackp);
+
+ noms.resize(0);
+ noms.push_back("z"); noms.push_back("d");
+ noms.push_back("zl"); noms.push_back("zp");
+ NTuple ntinv(noms);
+ for(int_4 i=0;i<nzfin;i++) {
+   double z = zfin[i];
+   double d = dlcfin[i];
+   unsigned short ok;
+   xnt[0] = z;
+   xnt[1] = d;
+   xnt[2] = interpinvl.Parab(d,ok);
+   xnt[3] = interpinvp.Parab(d,ok);
+   ntinv.Fill(xnt);
+ }
+
+ // --- Write PPF
+ string tag = "cmvtinterp.ppf";
+ cout<<"Write PPF : "<<tag<<endl;
+ POutPersist pos(tag);
+ tag = "ntg"; pos.PutObject(ntg,tag);
+ tag = "ntinv"; pos.PutObject(ntinv,tag);
+
+ return 0;
+}
+
+/*
+openppf cmvtinterp.ppf
+
+#### Check interpolation
+n/plot ntg.d%z ! ! "nsta connectpoints"
+n/plot ntg.d0%z ! ! "nsta connectpoints same green"
+n/plot ntg.d1%z ! ! "nsta connectpoints same blue"
+n/plot ntg.d2%z ! ! "nsta connectpoints same red"
+
+n/plot ntg.d0-d%z ! ! "nsta connectpoints green"
+n/plot ntg.d1-d%z ! ! "nsta connectpoints same blue"
+n/plot ntg.d2-d%z ! ! "nsta connectpoints same red"
+addline 0 0 1000 0
+
+n/plot ntg.d0-d%d ! ! "nsta connectpoints green"
+n/plot ntg.d1-d%d ! ! "nsta connectpoints same blue"
+n/plot ntg.d2-d%d ! ! "nsta connectpoints same red"
+addline 0 0 1000 0
+
+n/plot ntg.(d0-d)/d%d fabs(d)>1e-13 ! "nsta connectpoints green"
+n/plot ntg.(d1-d)/d%d fabs(d)>1e-13 ! "nsta connectpoints same blue"
+n/plot ntg.(d2-d)/d%d fabs(d)>1e-13 ! "nsta connectpoints same red"
+addline 0 0 1000 0
+
+#### Check inversion
+n/plot ntinv.d%_nl ! ! "connectpoints"
+
+n/plot ntinv.z%d ! ! "nsta connectpoints"
+n/plot ntg.z%d ! ! "nsta connectpoints same red"
+
+n/plot ntinv.z%d ! ! "nsta connectpoints"
+n/plot ntinv.zl%d ! ! "nsta connectpoints same blue"
+n/plot ntinv.zp%d ! ! "nsta connectpoints same red"
+
+n/plot ntinv.zl-z%d ! ! "nsta connectpoints blue"
+n/plot ntinv.zp-z%d ! ! "nsta connectpoints same red"
+addline 0 0 10000 0
+
+n/plot ntinv.zl-z%z ! ! "nsta connectpoints blue"
+n/plot ntinv.zp-z%z ! ! "nsta connectpoints same red"
+addline 0 0 10000 0
+
+n/plot ntinv.(zl-z)/z%z z>0 ! "nsta connectpoints blue"
+n/plot ntinv.(zp-z)/z%z z>0 ! "nsta connectpoints same red"
+addline 0 0 10000 0
+
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtintfun.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtintfun.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtintfun.cc	(revision 3445)
@@ -0,0 +1,61 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "geneutils.h"
+
+// cmvtintfun [n] [xmin,xmax,npt]
+
+class MyFunc : public GenericFunc {
+public:
+  MyFunc(double n) {n_=n;}
+  virtual ~MyFunc(void) {};
+  virtual double operator() (double x)
+          {return (n_>=0.) ? pow(x,n_) : exp(n_*x);}
+  double integ(double xmin,double xmax) {
+    return (n_>=0.) ? (pow(xmax,n_+1.)-pow(xmin,n_+1.))/(n_+1.)
+                    : (exp(n_*xmax)-exp(n_*xmin))/n_;
+  }
+protected:
+  double n_;
+};
+
+
+int main(int narg,char *arg[])
+{
+
+  double n=3.;
+  if(narg>1) sscanf(arg[1],"%lf",&n);
+  double xmin=1., xmax=10.;
+  int npt = 100;
+  if(narg>2) sscanf(arg[2],"%lf,%lf,%d",&xmin,&xmax,&npt);
+
+  double lxmin=log10(xmin), lxmax=log10(xmax);
+  double perc=0.01;
+  double dxinc=(xmax-xmin)/npt, dxmax=-1.;
+  double dlxinc=(lxmax-lxmin)/npt, dlxmax=-1.;
+  unsigned short glorder=4;
+
+  if(narg>1) sscanf(arg[1],"%lf",&n);
+  if(narg>2) sscanf(arg[2],"%lf,%lf,%d",&xmin,&xmax,&npt);
+  cout<<"n="<<n<<" xmin="<<xmin<<" xmax="<<xmax<<" npt="<<npt<<endl;
+
+  MyFunc myfunc(n);
+
+  double integ = IntegrateFunc(myfunc,xmin,xmax,perc,dxinc,dxmax,glorder);
+  cout<<"IntegrateFunc() = "<<integ<<endl;
+
+  double integlog = IntegrateFuncLog(myfunc,lxmin,lxmax,perc,dlxinc,dlxmax,glorder);
+  cout<<"IntegrateFuncLog() = "<<integlog<<endl;
+
+  cout<<"Integrate() = "<<myfunc.integ(xmin,xmax)<<endl;
+
+ return 0;
+}
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtluc.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtluc.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtluc.cc	(revision 3445)
@@ -0,0 +1,103 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "luc.h"
+
+void usage(void);
+void usage(void)
+{
+  cout<<"cmvtuniv z1,z2,dz"<<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ // -- WMAP
+ double h100=0.71, om0=0.267804, or0=7.9e-05, ol0=0.73,w0=-1., ob0=0.045, oph0=5e-5;
+ // -- ouvert matter only
+ //double h100=0.71, om0=0.3, or0=0., ol0=0.,w0=-1., ob0=0.045, oph0=5e-5;
+ // -- plat matter only
+ //double h100=0.71, om0=1., or0=0., ol0=0.,w0=-1., ob0=0.045, oph0=5e-5;
+
+ double z1=0., z2=10., dz=1.;
+ if(narg>1) sscanf(arg[1],"%lf,%lf,%lf",&z1,&z2,&dz);
+
+ SimpleUniverse univ;
+ univ.SetPrtDbgLevel(1);
+
+ univ.Seth(h100);
+ univ.SetOmegaMatter(om0);
+ univ.SetOmegaLambda(ol0);
+ //univ.SetDarkEnergy(ol0,w0);
+ univ.SetOmegaRadiation(or0);
+ univ.SetOmegaBaryon(ob0);
+ univ.SetOmegaPhoton(oph0);
+
+ //univ.SetFlatUniverse_OmegaMatter();
+ //univ.SetFlatUniverse_OmegaLambda();
+
+ /*
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   univ.SetEmissionRedShift(z,0.001);
+   cout<<endl;
+   univ.Print();
+ }
+ */
+
+ /**/
+ double norm = univ.HubbleLengthMpc(); // 1.;
+ double norm3 = pow(norm,3.);
+ const int n = 11;
+ char *vname[n] = {
+   "z","hz","om","or","ol","ok","ot",
+   "da","dl","dvc","vc0"
+ };
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   univ.SetEmissionRedShift(z,0.001);
+   xnt[0]  = univ.ZE();
+   xnt[1]  = univ.HZE();
+   xnt[2]  = univ.OmegaMatterZE();
+   xnt[3]  = univ.OmegaRadiationZE();
+   xnt[4]  = 0.; //univ.OmegaLambdaZE()+univ.OmegaDarkZE();
+   xnt[5]  = univ.OmegaCurvZE();
+   xnt[6]  = 0.; //univ.OmegaTotalZE();
+   xnt[7]  = univ.AngularDiameterDistanceMpc()/norm;
+   xnt[8]  = univ.LuminosityDistanceMpc()/norm;
+   if(xnt[8]<0.) cout<<xnt[8]<<endl;
+   xnt[9]  = 0.; //univ.dVolZE()/norm3;
+   xnt[10] = 0.; //univ.Vol4PiZE()/norm3;
+   nt.Fill(xnt);
+ }
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtluc.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+ /**/
+
+ return 0;
+}
+
+
+/*
+openppf cmvtluc.ppf
+
+set cut 1
+set cut z<100.
+
+zone
+n/plot nt.hz%z $cut ! "nsta"
+
+zone
+n/plot nt.dl%z $cut ! "nsta"
+n/plot nt.da%z $cut ! "nsta same red"
+
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtransf.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtransf.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtransf.cc	(revision 3445)
@@ -0,0 +1,128 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "constcosmo.h"
+#include "pkspectrum.h"
+
+void usage(void);
+void usage(void) {
+cout
+<<"cmvtransf [options]"<<endl
+<<"  -k k1,k2,npt : k range in Mpc^-1"<<endl
+<<"  -U h100,Om0,Ob0,tcmb : cosmology"<<endl
+<<"  -F filename : read also CMBFast file"<<endl
+<<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ double k1 = 1e-6, k2 = 10.; int_4 npt = 100;
+ double h100 = 0.71, Om0 = 0.267804, Ob0 = 0.0444356, tcmb = T_CMB_Par;
+ string fcmbfast = "";
+
+ char c;
+  while((c = getopt(narg,arg,"hk:U:F:")) != -1) {
+  switch (c) {
+  case 'k' :
+    sscanf(optarg,"%d,%lf,%lf",&npt,&k1,&k2);
+    break;
+  case 'U' :
+    sscanf(optarg,"%lf,%lf,%lf,%lf",&h100,&Om0,&Ob0,&tcmb);
+    break;
+  case 'F' :
+    fcmbfast = optarg;
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+
+ if(k1<=0.) {cout<<"k1 must be >0"<<endl; return -1;}
+ if(npt<=0) npt = 1000;
+ if(k2<=k1) {k1=1.e-4; k2=1.e+2;}
+ cout<<"k1="<<k1<<"  k2="<<k2<<" npt="<<npt<<endl;
+ cout<<"h100="<<h100<<" Om0="<<Om0<<" Ob0="<<Ob0<<" Tcmb="<<tcmb<<endl;
+ cout<<"fcmbfast="<<fcmbfast<<endl;
+
+ cout<<"TransfertEisenstein with baryon"<<endl;
+ TransfertEisenstein tf(h100,Om0-Ob0,Ob0,tcmb);
+ cout<<"KPeak = "<<tf.KPeak()<<"  1/Mpc"<<endl;
+
+ cout<<endl<<"TransfertEisenstein with baryon without oscillation approx.1"<<endl;
+ TransfertEisenstein tfnosc1(h100,Om0-Ob0,Ob0,tcmb);  // No oscillation approx.1
+ tfnosc1.SetNoOscEnv(1);
+
+ cout<<endl<<"TransfertEisenstein with baryon without oscillation approx.2"<<endl;
+ TransfertEisenstein tfnosc2(h100,Om0-Ob0,Ob0,tcmb);  // No oscillation approx.2
+ tfnosc2.SetNoOscEnv(2);
+
+ cout<<endl<<"TransfertEisenstein without baryon"<<endl;
+ TransfertEisenstein tfnob(h100,Om0-Ob0,Ob0,tcmb,true);  // No baryons
+
+ TransfertTabulate tfcmbfast(h100,Om0-Ob0,Ob0);
+ bool cmbfastOK = false;
+ if(fcmbfast.size()>0) {
+   cout<<endl<<"TransfertTabulate for CMBfast"<<endl;
+   tfcmbfast.ReadCMBFast(fcmbfast);
+   tfcmbfast.SetInterpTyp(1);
+   if(tfcmbfast.NPoints()>0) cmbfastOK = true;
+ }
+
+ const int n = 6;
+ char *vname[n] = {"k","t","tnosc1","tnosc2","tnob","tcmbf"};
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(int i=0;i<n;i++) xnt[i]=0.;
+
+ double lnk1 = log10(k1), lnk2=log10(k2), dlnk=(lnk2-lnk1)/npt;
+ for(double lnk=lnk1;lnk<lnk2+dlnk/2.;lnk+=dlnk) {
+   double k = pow(10.,lnk);
+   xnt[0]  = k;
+   xnt[1]  = tf(k);
+   xnt[2]  = tfnosc1(k);
+   xnt[3]  = tfnosc2(k);
+   xnt[4]  = tfnob(k);
+   if(cmbfastOK) xnt[5]  = tfcmbfast(k);
+   nt.Fill(xnt);
+ }
+
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtransf.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+
+ return 0;
+}
+
+/*
+openppf cmvtransf.ppf
+
+set k k
+set k log10(k)
+
+# Eisenstein
+n/plot nt.t%$k ! ! "nsta connectpoints"
+n/plot nt.tnob%$k ! ! "nsta red same connectpoints"
+n/plot nt.tnosc2%$k ! ! "nsta blue same connectpoints"
+n/plot nt.tnosc1%$k ! ! "nsta green same connectpoints"
+
+n/plot nt.t/tnob%$k   tnob>0   ! "nsta red connectpoints"
+n/plot nt.t/tnosc2%$k tnosc2>0 ! "nsta blue same connectpoints"
+n/plot nt.t/tnosc1%$k tnosc1>0 ! "nsta green same connectpoints"
+
+# CMBFast
+n/plot nt.t%$k ! ! "nsta connectpoints"
+n/plot nt.tcmbf%$k ! ! "nsta red same connectpoints"
+
+n/plot nt.(tcmbf-t)%$k tcmbf>0. ! "nsta connectpoints"
+n/plot nt.(tcmbf-t)/tcmbf%$k tcmbf>0. ! "nsta connectpoints"
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtstagn.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtstagn.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtstagn.cc	(revision 3445)
@@ -0,0 +1,198 @@
+// Distribution des flux des AGN dans un pixel de taille donne
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "geneutils.h"
+#include "agnjackson.h"
+
+void usage(void);
+void usage(void)
+{
+cout<<"cmvtstagn "<<endl
+ <<" -a angsol: taille pixel (en sr si >0 ou arcmin^2 si <0)"<<endl
+ <<" -x nbin,xmin,xmax: def histo des log10(S Jy)/pixel"<<endl
+ <<"              si nbin<0 on a de <S>+xmin , <S>-xmax"<<endl
+ <<" -n npix: nombre de tirages de pixel"<<endl;
+}
+
+
+int main(int narg,char *arg[])
+{
+ double angsol = 1.;  // sr
+ double lxmin=-3.,lxmax=4.; int nbinlx = -100;
+ int npix = 100;
+
+ // --- Decodage arguments
+ char c;
+ while((c = getopt(narg,arg,"ha:x:n:")) != -1) {
+  switch (c) {
+  case 'a' :
+    sscanf(optarg,"%lf",&angsol);
+    break;
+  case 'x' :
+    sscanf(optarg,"%d,%lf,%lf",&nbinlx,&lxmin,&lxmax);
+    break;
+  case 'n' :
+    sscanf(optarg,"%d",&npix);
+    break;
+  case 'h' :
+  default :
+    usage();
+    return -1;
+  }
+ }
+
+ // --- Class de distribution d'AGN
+ double sr2amin = AngSol(M_PI/180./60./2.,M_PI/180./60./2.);
+ if(angsol<0) angsol *= -sr2amin;
+ cout<<"angsol = "<<angsol<<" sr -> "<<angsol/sr2amin<<" arcmin^2"<<endl;
+ AGNJackson agn;
+ agn.Print();
+
+ cout<<endl;
+ vector<double> xjack, yjack; agn.OrigJack(xjack,yjack);
+ Histo hdndls0 = agn.dNdlS();
+ Histo hdndls(hdndls0); hdndls *= angsol;
+ Histo htirls = agn.TirL10S();
+ double nobjang = agn.NObjAng()*angsol;
+ double fluxang = agn.FluxAng()*angsol;
+ cout<<"Nombre moyen d\'objets dans notre pixel: "<<nobjang<<endl;
+ cout<<"Flux moyen dans notre pixel: "<<fluxang<<" Jy"<<endl;
+
+ // --- Distribution sur angsol
+ // Histo du nombre d'objets / angsol
+ cout<<endl;
+ double mu = nobjang; if(mu<=0.) mu=1.;
+ double xmin = mu-5.*sqrt(mu); if(xmin<0.) xmin=0.; xmin=floor(xmin);
+ double xmax = mu+7.*sqrt(mu); xmax=floor(xmax+1.);
+ long nb = long(xmax-xmin+1.01); while(nb>250) nb /= 2;
+ // Histo du nombre d'objets/pixel
+ Histo hnobj(xmin,xmax,nb); hnobj.ReCenterBin();
+ cout<<"hnobj: "; hnobj.Show();
+ // Histo de check du tirage
+ Histo hlflux(htirls); hlflux.Zero();
+ // Histo du flux/pixel
+ if(nbinlx==0 || nbinlx==1) nbinlx = -100;
+ if(nbinlx<0) {
+   nbinlx = -nbinlx;
+   lxmin = log10(fluxang) + lxmin;
+   lxmax = log10(fluxang) + lxmax;
+   cout<<"Recomputing: lxmin="<<lxmin<<" lxmax="<<lxmax<<" nbin="<<nbinlx<<endl;
+ }
+ Histo hlfang(lxmin,lxmax,nbinlx); hlfang.Zero();
+ cout<<"hlfang: "; hlfang.Show();
+
+ // Tirage aleatoire
+ cout<<endl;
+ if(npix>1) {
+   long l = npix/10; if(l<=0) l=1;
+   cout<<"Making "<<npix<<" trials"<<endl;
+   unsigned long nzero=0, ntir=0;
+   double sumpix=0., sumpix2=0., sumn=0., sumn2=0.;
+   for(long i=0;i<npix;i++) {
+     if(i%l==0) cout<<"...trial: "<<i<<endl;
+     unsigned long n = PoissRandLimit(mu,10.);
+     hnobj.Add((double)n);
+     sumn += n; sumn2 += n*n;
+     double fsum = 0.; unsigned long nf = 0;
+     for(unsigned long j=0;j<n;j++) {
+       double f = agn.FluxJY();
+       hlflux.Add(log10(f));
+       fsum += f;
+       nf++;
+     }
+     ntir += nf;
+     if(nf==0) {
+       nzero++;
+     } else {
+       sumpix += fsum; sumpix2 += fsum*fsum;
+       hlfang.Add(log10(fsum));
+     }
+   }
+   sumn /= (double)npix;
+   sumn2 = sumn2/(double)npix - sumn*sumn;
+   sumpix /= (double)npix;
+   sumpix2 = sumpix2/(double)npix - sumpix*sumpix;
+   cout<<"Number of try: "<<ntir<<endl;
+   cout<<"Number of pixels with no flux: "<<nzero<<" / "<<npix<<endl;
+   cout<<"Mean object number/pix: "<<sumn<<" (check "<<(double)ntir/(double)npix
+       <<") s^2="<<sumn2<<" s="<<sqrt(fabs(sumn2))<<endl;
+   cout<<"Mean flux/pix: "<<sumpix<<" s^2="<<sumpix2<<" s="<<sqrt(fabs(sumpix2))<<endl;
+   // Info de l'histo des flux
+   cout<<"hlfang: "; hlfang.Show();
+   // normalisation de hlflux
+   hlflux *= hdndls.BinWidth()/hlflux.BinWidth()*hdndls.Sum()/hlflux.Sum();
+ }
+
+ // --- Ecriture sur fichier ppf
+ string tag = "cmvtstagn.ppf";
+ POutPersist pos(tag);
+
+ TVector<r_8> vxjack(xjack), vyjack(yjack);
+ tag = "xjack"; pos.PutObject(vxjack,tag);
+ tag = "yjack"; pos.PutObject(vyjack,tag);
+
+ tag = "dndls0"; pos.PutObject(hdndls0,tag);
+ tag = "dndls"; pos.PutObject(hdndls,tag);
+
+ tag = "tirls"; pos.PutObject(htirls,tag);
+ tag = "hlflux"; pos.PutObject(hlflux,tag);
+
+ tag = "nobj"; pos.PutObject(hnobj,tag);
+ tag = "hlfang"; pos.PutObject(hlfang,tag);
+
+ return 0;
+}
+
+
+/*
+openppf cmvtstagn.ppf
+
+del ntjack
+c++exec char *vname[2] = {"x","y"}; double xnt[2]; \
+NTuple ntjack(2,vname); \
+for(int i=0;i<xjack.Size();i++) \
+  {xnt[0]=xjack(i); xnt[1]=yjack(i); ntjack.Fill(xnt);} \
+KeepObj(ntjack); cout<<"OK";
+
+# Jackson initial (Jy^1.5/sr)
+n/plot ntjack.y%x ! ! "nsta connectpoints"
+vecplot xjack yjack "same red fcirclemarker7"
+
+# Check de ce qu'on a extrapole
+set yxt "y*pow(10.,-1.5*x)*M_LN10"
+n/plot dndls0.log10(val)%x ! ! "nsta connectpoints"
+n/plot ntjack.log10($yxt)%x ! ! "nsta red fcirclemarker7 same"
+
+# la pdf : histo en 1/log10(Jy)/sr
+disp dndls0 "nsta"
+n/plot ntjack.$yxt%x ! ! "nsta red fcirclemarker7 same"
+
+# la pdf : histo en 1/log10(Jy)/angsol
+disp dndls "nsta"
+
+# la pdf en flux: dn/dlog10(S)*S en microJy/log10(Jy)/sr
+n/plot dndls.val*pow(10.,x)*1e6%x ! ! "nsta connectpoints"
+
+# la fonction de tirage en 1/Jy/(angsol sr)
+disp tirls "nsta"
+
+# Check tirages
+disp dndls "nsta"
+disp hlflux "nsta same red"
+
+# Resultat: nombre d'objets (poisson) par pixel
+disp nobj
+
+# Resultat: distribution du flux par pixel
+disp hlfang
+
+ */
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtstblack.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtstblack.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtstblack.cc	(revision 3445)
@@ -0,0 +1,362 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "constcosmo.h"
+#include "geneutils.h"
+#include "planckspectra.h"
+
+void compute_xroot(void);
+
+// cmvtstblack [T,nutest(Hz)] [deriv 0/1]
+
+int main(int narg,char *arg[])
+{
+  //{compute_xroot(); return -41;}
+ double T = 2.718, nutest=-1.;
+ unsigned short funcderiv = 0;
+ double x0;
+
+ if(narg>1) sscanf(arg[1],"%lf,%lf",&T,&nutest);
+ if(T<=0.) T = 2.718;
+ if(narg>2) sscanf(arg[2],"%hu",&funcderiv);
+ PlanckSpectra::SpectraFunc deriv = (funcderiv==0) ? PlanckSpectra::VALUE : PlanckSpectra::DERIV;
+
+ cout<<"Temperature "<<T<<" K , deriv="<<(int)deriv<<endl;
+
+ //--------------------------------- Radiance Frequence
+ // frequence planck radiance W/..
+ PlanckSpectra pradf(T);
+ pradf.SetSpectraFunc(deriv);
+ pradf.SetSpectraVar(PlanckSpectra::NU);
+ pradf.SetSpectraApprox(PlanckSpectra::PLANCK);
+ pradf.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ pradf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phpradf(pradf);
+ phpradf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // frequence rayleigh radiance W/..
+ PlanckSpectra rradf(T);
+ rradf.SetSpectraFunc(deriv);
+ rradf.SetSpectraVar(PlanckSpectra::NU);
+ rradf.SetSpectraApprox(PlanckSpectra::RAYLEIGH);
+ rradf.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ rradf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phrradf(rradf);
+ phrradf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // frequence wien radiance W/..
+ PlanckSpectra wradf(T);
+ wradf.SetSpectraFunc(deriv);
+ wradf.SetSpectraVar(PlanckSpectra::NU);
+ wradf.SetSpectraApprox(PlanckSpectra::WIEN);
+ wradf.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ wradf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phwradf(wradf);
+ phwradf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // Check
+ if(nutest<=0.) nutest = k_Boltzman_Cst*T/h_Planck_Cst;
+ cout<<"Test for t="<<T<<" K,  nu="<<nutest<<" Hz"<<endl
+     <<"    planck = "<<pradf(nutest)<<endl
+     <<"      wien = "<<wradf(nutest)<<endl
+     <<"  rayleigh = "<<rradf(nutest)<<endl;
+
+ //--------------------------------- Densite Frequence
+ // frequence planck density W/..
+ PlanckSpectra pdensf(T);
+ pdensf.SetSpectraFunc(deriv);
+ pdensf.SetSpectraVar(PlanckSpectra::NU);
+ pdensf.SetSpectraApprox(PlanckSpectra::PLANCK);
+ pdensf.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ pdensf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phpdensf(pdensf);
+ phpdensf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // frequence rayleigh density W/..
+ PlanckSpectra rdensf(T);
+ rdensf.SetSpectraFunc(deriv);
+ rdensf.SetSpectraVar(PlanckSpectra::NU);
+ rdensf.SetSpectraApprox(PlanckSpectra::RAYLEIGH);
+ rdensf.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ rdensf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phrdensf(rdensf);
+ phrdensf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // frequence wien density W/..
+ PlanckSpectra wdensf(T);
+ wdensf.SetSpectraFunc(deriv);
+ wdensf.SetSpectraVar(PlanckSpectra::NU);
+ wdensf.SetSpectraApprox(PlanckSpectra::WIEN);
+ wdensf.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ wdensf.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phwdensf(wdensf);
+ phwdensf.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ //--------------------------------- Radiance Longeur d'onde
+ // longueur d'onde planck radiance W/..
+ PlanckSpectra pradl(T);
+ pradl.SetSpectraFunc(deriv);
+ pradl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ pradl.SetSpectraApprox(PlanckSpectra::PLANCK);
+ pradl.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ pradl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phpradl(pradl);
+ phpradl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // longueur d'onde rayleigh radiance W/..
+ PlanckSpectra rradl(T);
+ rradl.SetSpectraFunc(deriv);
+ rradl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ rradl.SetSpectraApprox(PlanckSpectra::RAYLEIGH);
+ rradl.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ rradl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phrradl(rradl);
+ phrradl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // longueur d'onde wien radiance W/..
+ PlanckSpectra wradl(T);
+ wradl.SetSpectraFunc(deriv);
+ wradl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ wradl.SetSpectraApprox(PlanckSpectra::WIEN);
+ wradl.SetSpectraUnit(PlanckSpectra::ANGSFLUX);
+ wradl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phwradl(wradl);
+ phwradl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ //--------------------------------- Densite Longeur d'onde
+ // longueur d'onde planck density W/..
+ PlanckSpectra pdensl(T);
+ pdensl.SetSpectraFunc(deriv);
+ pdensl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ pdensl.SetSpectraApprox(PlanckSpectra::PLANCK);
+ pdensl.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ pdensl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phpdensl(pdensl);
+ phpdensl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // longueur d'onde rayleigh density W/..
+ PlanckSpectra rdensl(T);
+ rdensl.SetSpectraFunc(deriv);
+ rdensl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ rdensl.SetSpectraApprox(PlanckSpectra::RAYLEIGH);
+ rdensl.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ rdensl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phrdensl(rdensl);
+ phrdensl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ // longueur d'onde wien density W/..
+ PlanckSpectra wdensl(T);
+ wdensl.SetSpectraFunc(deriv);
+ wdensl.SetSpectraVar(PlanckSpectra::LAMBDA);
+ wdensl.SetSpectraApprox(PlanckSpectra::WIEN);
+ wdensl.SetSpectraUnit(PlanckSpectra::DENSENERG);
+ wdensl.SetSpectraPower(PlanckSpectra::POWER);
+ PlanckSpectra phwdensl(wdensl);
+ phwdensl.SetSpectraPower(PlanckSpectra::PHOTON);
+
+ //--------------------------------- Le maximum des spectres de planck
+ cout<<endl;
+ double eps = 0.001;
+ x0 = pradf.WienLaw();
+ printf("Planck maximum for radiance energy: f = %e Hz  -> %e W/m^2/sr/Hz\n",x0,pradf(x0));
+ printf("                             check:   = %e\n",pradf.FindMaximum(eps));
+ x0 = phpradf.WienLaw();
+ printf("Planck maximum for radiance photon: f = %e Hz  -> %e ph/s/m^2/sr/Hz\n",x0,phpradf(x0));
+ printf("                             check:   = %e\n",phpradf.FindMaximum(eps));
+
+ x0 = pdensf.WienLaw();
+ printf("Planck maximum for density energy:  f = %e Hz  -> %e J/m^3/Hz\n",x0,pdensf(x0));
+ printf("                             check:   = %e\n",pdensf.FindMaximum(eps));
+ x0 = phpdensf.WienLaw();
+ printf("Planck maximum for density photon:  f = %e Hz  -> %e ph/m^3/Hz\n",x0,phpdensf(x0));
+ printf("                             check:   = %e\n",phpdensf.FindMaximum(eps));
+
+ x0 = pradl.WienLaw();
+ printf("Planck maximum for radiance energy: l = %e m  -> %e W/m^2/sr/m\n",x0,pradl(x0));
+ printf("                             check:   = %e\n",pradl.FindMaximum(eps));
+ x0 = phpradl.WienLaw();
+ printf("Planck maximum for radiance photon: l = %e m  -> %e ph/s/m^2/sr/m\n",x0,phpradl(x0));
+ printf("                             check:   = %e\n",phpradl.FindMaximum(eps));
+
+ x0 = pdensl.WienLaw();
+ printf("Planck maximum for density energy:  l = %e m  -> %e J/m^3/m\n",x0,pdensl(x0));
+ printf("                             check:   = %e\n",pdensl.FindMaximum(eps));
+ x0 = phpdensl.WienLaw();
+ printf("Planck maximum for density photon:  l = %e m  -> %e ph/m^3/m\n",x0,phpdensl(x0));
+ printf("                             check:   = %e\n",phpdensl.FindMaximum(eps));
+
+ //--------------------------------- La loi de Wien
+ cout<<endl;
+ x0 = wradf.WienLaw();
+ printf("Wien law for radiance energy: f = %e Hz  -> %e W/m^2/sr/Hz\n",x0,wradf(x0));
+ printf("                       check:   = %e\n",wradf.FindMaximum(eps));
+ x0 = phwradf.WienLaw();
+ printf("Wien law for radiance photon: f = %e Hz  -> %e ph/s/m^2/sr/Hz\n",x0,phwradf(x0));
+ printf("                       check:   = %e\n",phwradf.FindMaximum(eps));
+
+ x0 = wdensf.WienLaw();
+ printf("Wien law for density energy:  f = %e Hz  -> %e J/m^3/Hz\n",x0,wdensf(x0));
+ printf("                      check:    = %e\n",wdensf.FindMaximum(eps));
+ x0 = phwdensf.WienLaw();
+ printf("Wien law for density photon:  f = %e Hz  -> %e  ph/m^3/Hz\n",x0,phwdensf(x0));
+ printf("                      check:    = %e\n",phwdensf.FindMaximum(eps));
+
+ x0 = wradl.WienLaw();
+ printf("Wien law for radiance energy: l = %e m  -> %e W/m^2/sr/m\n",x0,wradl(x0));
+ printf("                       check:   = %e\n",wradl.FindMaximum(eps));
+ x0 = phwradl.WienLaw();
+ printf("Wien law for radiance photon: l = %e m  -> %e ph/s/m^2/sr/m\n",x0,phwradl(x0));
+ printf("                       check:   = %e\n",phwradl.FindMaximum(eps));
+
+ x0 = wdensl.WienLaw();
+ printf("Wien law for density energy:  l = %e m  -> %e J/m^3/m\n",x0,wdensl(x0));
+ printf("                      check:    = %e\n",wdensl.FindMaximum(eps));
+ x0 = phwdensl.WienLaw();
+ printf("Wien law for density photon:  l = %e m  -> %e ph/m^3/m\n",x0,phwdensl(x0));
+ printf("                      check:    = %e\n",phwdensl.FindMaximum(eps));
+
+ //--------------------------------- Densite totale d'energie
+ cout<<endl;
+ cout<<"Densite totale d'energie: "<<pdensf.PlanckEnergie()<<" J/m^3"<<endl;
+ if(! deriv) {
+   double x1,x2,perc,dxinc;
+   x0 = pdensf.WienLaw(); x1=x0/100.; x2=x0*100.; perc=0.1; dxinc=x0/1000.;
+   cout<<"   check by integration: "<<IntegrateFunc(pdensf,x1,x2,perc,dxinc)<<" J/m^3"<<endl;
+   x1=log10(x0/100.); x2=log10(x0*100.); perc=0.1; dxinc=(x2-x1)/100.;
+   cout<<"   check by integration: "<<IntegrateFuncLog(pdensf,x1,x2,perc,dxinc)<<" J/m^3"<<endl;
+
+   x0 = pdensl.WienLaw(); x1=x0/100.; x2=x0*100.; perc=0.1; dxinc=x0/1000.;
+   cout<<"   check by integration: "<<IntegrateFunc(pdensl,x1,x2,perc,dxinc)<<" J/m^3"<<endl;
+   x1=log10(x0/100.); x2=log10(x0*100.); perc=0.1; dxinc=(x2-x1)/100.;
+   cout<<"   check by integration: "<<IntegrateFuncLog(pdensl,x1,x2,perc,dxinc)<<" J/m^3"<<endl;
+ }
+
+ //--------------------------------- Densite totale de photons
+ cout<<endl;
+ cout<<"Densite totale de photons: "<<pdensf.PlanckPhoton()<<" ph/m^3"<<endl;
+ if(! deriv) {
+   double x1,x2,perc,dxinc;
+   x0 = phpdensf.WienLaw(); x1=x0/100.; x2=x0*100.; perc=0.1; dxinc=x0/1000.;
+   cout<<"   check by integration: "<<IntegrateFunc(phpdensf,x1,x2,perc,dxinc)<<" ph/m^3"<<endl;
+   x1=log10(x0/100.); x2=log10(x0*100.); perc=0.1; dxinc=(x2-x1)/100.;
+   cout<<"   check by integration: "<<IntegrateFuncLog(phpdensf,x1,x2,perc,dxinc)<<" ph/m^3"<<endl;
+
+   x0 = phpdensl.WienLaw(); x1=x0/100.; x2=x0*100.; perc=0.1; dxinc=x0/1000.;
+   cout<<"   check by integration: "<<IntegrateFunc(phpdensl,x1,x2,perc,dxinc)<<" ph/m^3"<<endl;
+   x1=log10(x0/100.); x2=log10(x0*100.); perc=0.1; dxinc=(x2-x1)/100.;
+   cout<<"   check by integration: "<<IntegrateFuncLog(phpdensl,x1,x2,perc,dxinc)<<" ph/m^3"<<endl;
+ }
+
+ //--------------------------------- NTuple
+ cout<<endl;
+ int npt = 1000;
+ double frac = 10000.;
+ x0 = wradf.WienLaw();
+ double xmin = x0/frac, xmax = x0*frac;
+ cout<<"xmin="<<xmin<<" Hz,  xmax="<<xmax<<" Hz"<<endl;
+ double lnx1 = log10(xmin), lnx2 = log10(xmax), dlnx = (lnx2-lnx1)/npt;
+ cout<<"lnx1="<<lnx1<<",  lnx2="<<lnx2<<", dlnx="<<dlnx<<endl;
+
+ const int n = 14;
+ char *vname[n] = {"f","l","prf","prl","pdf","pdl","rrf","rrl","rdf","rdl","wrf","wrl","wdf","wdl"};
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(double lx=lnx1;lx<lnx2+dlnx/2.;lx+=dlnx) {
+   double f = pow(10.,lx);
+   double l = wradf.F2L(f);
+   xnt[0] = f;
+   xnt[1] = l;
+   xnt[2] = pradf(f);
+   xnt[3] = pradl(l);
+   xnt[4] = pdensf(f);
+   xnt[5] = pdensl(l);
+   xnt[6] = rradf(f);
+   xnt[7] = rradl(l);
+   xnt[8] = rdensf(f);
+   xnt[9] = rdensl(l);
+   xnt[10] = wradf(f);
+   xnt[11] = wradl(l);
+   xnt[12] = wdensf(f);
+   xnt[13] = wdensl(l);
+   nt.Fill(xnt);
+ }
+
+ cout<<"\n>>>> Ecriture"<<endl;
+ string tag = "cmvtstblack.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+
+ return 0;
+}
+
+//---------------------------------------
+void compute_xroot(void)
+// Pour calculer les x qui donnent le maximum de f(x) pour:
+// f(x) = x^n * exp(-x)
+// ou
+// f(x) = x^n / (exp(x)-1)
+// ou
+// f(x) = x^n * exp(x) / (exp(x)-1)^2
+{
+  double n = 3.;
+  cout<<"n="<<n<<endl;
+  int npt=10;
+  double xmin=0.1,xmax=10., dx=(xmax-xmin)/npt;
+  for(int itry=0;itry<100;itry++) {
+    double x0=xmin, v0=-1e10;
+    for(double x=xmin;x<xmax+dx/2.; x+=dx) {
+      double f = pow(x,n) * exp(-x);  // Wien ou dWein/dT
+      //double f = pow(x,n) / (exp(x)-1);  // Planck
+      //double f = pow(x,n)  * exp(x) / ((exp(x)-1)*(exp(x)-1));  // dPlanck/dT
+      if(f>v0) {v0=f; x0=x;}
+    }
+    printf("x0 = %.18f , v0=%.18f , dx=%e\n",x0,v0,dx);
+    xmin = x0-dx; xmax = x0+dx; dx=(xmax-xmin)/npt;
+    if(dx<1e-15) break;
+  }
+}
+
+
+/*
+openppf cmvtstblack.ppf
+
+# Energie
+set fac 1.
+# Photon
+set fac (6.6260693e-34*f)
+
+n/plot nt.log10(f)%log10(l)
+
+# radiance frequence
+n/plot nt.prf/${fac}%log10(f) ! ! "nsta connectpoints"
+n/plot nt.rrf/${fac}%log10(f) ! ! "nsta connectpoints red same"
+n/plot nt.wrf/${fac}%log10(f) ! ! "nsta connectpoints blue same"
+
+# radiance longeur d'onde
+n/plot nt.prl/${fac}%log10(l) ! ! "nsta connectpoints"
+n/plot nt.rrl/${fac}%log10(l) ! ! "nsta connectpoints red same"
+n/plot nt.wrl/${fac}%log10(l) ! ! "nsta connectpoints blue same"
+
+# densite frequence
+n/plot nt.pdf/${fac}%log10(f) ! ! "nsta connectpoints"
+n/plot nt.rdf/${fac}%log10(f) ! ! "nsta connectpoints red same"
+n/plot nt.wdf/${fac}%log10(f) ! ! "nsta connectpoints blue same"
+
+# densite longeur d'onde
+n/plot nt.pdl/${fac}%log10(l) ! ! "nsta connectpoints"
+n/plot nt.rdl/${fac}%log10(l) ! ! "nsta connectpoints red same"
+n/plot nt.wdl/${fac}%log10(l) ! ! "nsta connectpoints blue same"
+
+# Check:  p(l)dl = p(f)df avec dl = c/f^2 df = l^2/c df
+n/plot nt.prf%log10(f) ! ! "nsta connectpoints"
+n/plot nt.prl*2.998e8/(f*f)%log10(f) ! ! "nsta connectpoints red same"
+
+ */
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtstpk.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtstpk.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtstpk.cc	(revision 3445)
@@ -0,0 +1,248 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "histos.h"
+#include "tvector.h"
+#include "ntuple.h"
+#include "perandom.h"
+
+#include "constcosmo.h"
+#include "pkspectrum.h"
+#include "geneutils.h"
+
+void usage(void);
+void usage(void) {
+ cout<<"cmvtstpk [options] z_redshift"<<endl
+     <<" -H h100 -B Ob0 -M Om0 -L Ol0,w0"<<endl
+     <<" -k npt,lkmin,lkmax : les valeurs sont en log10"<<endl
+     <<" -s scale : on multiplie pkz par scale"<<endl
+     <<" -w : write spectra on ASCII file"<<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ // -- WMAP
+ double h100=0.71, Om0=0.267804, Ob0 = 0.0444356, Ol0=0.73,w0=-1.;
+
+ double ns = 1., as = 1.;
+ int npt = 10000;
+ double lkmin = -3., lkmax=2.;
+ double scale = 1.;
+ bool wrascii = false;
+
+ char c;
+  while((c = getopt(narg,arg,"hwk:s:H:M:B:L:")) != -1) {
+  switch (c) {
+  case 'H' :
+    sscanf(optarg,"%lf",&h100);
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf",&Om0);
+    break;
+  case 'B' :
+    sscanf(optarg,"%lf",&Ob0);
+    break;
+  case 'L' :
+    sscanf(optarg,"%lf,%lf",&Ol0,&w0);
+    break;
+  case 'k' :
+    sscanf(optarg,"%d,%lf,%lf",&npt,&lkmin,&lkmax);
+    if(npt<=0) npt=1000;
+    if(lkmax<lkmin) {lkmin=-4.; lkmax=2.;}
+    break;
+  case 's' :
+    sscanf(optarg,"%lf",&scale);
+    break;
+  case 'w' :
+    wrascii = true;
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+ double dlk=(lkmax-lkmin)/npt;
+
+ // Fill z value into list
+ double zval = 0.;
+ if(optind<narg) zval = atof(arg[optind]);
+
+ cout<<"h100="<<h100<<" Om0="<<Om0<<" Ob0="<<Ob0<<" Ol0="<<Ol0<<" w0="<<w0<<endl;
+ cout<<"lkmin="<<lkmin<<" lkmax="<<lkmax<<" npt="<<npt<<" dlk="<<dlk<<endl;
+ cout<<"scale="<<scale<<endl;
+ cout<<"zval="<<zval<<endl;
+
+ //--------------------------
+ InitialSpectrum pkini(ns,as);
+
+ TransfertEisenstein tf(h100,Om0-Ob0,Ob0,T_CMB_Par,false);
+ cout<<"kpeak="<<tf.KPeak()<<endl;
+ TransfertEisenstein tfnosc2(tf); tfnosc2.SetNoOscEnv(2);
+ TransfertEisenstein tfnosc1(tf); tfnosc1.SetNoOscEnv(1);
+ TransfertEisenstein tfnob(h100,Om0,0.,T_CMB_Par,true);
+
+ GrowthFactor d1(Om0,Ol0);
+ cout<<"GrowthFactor: "<<d1(zval)<<endl;
+
+ PkSpectrum0 pk0(pkini,tf);
+ PkSpectrum0 pk0nosc2(pkini,tfnosc2);
+ PkSpectrum0 pk0nosc1(pkini,tfnosc1);
+ PkSpectrum0 pk0nob(pkini,tfnob);
+
+ PkSpectrumZ pkz(pk0,d1,zval);
+ PkSpectrumZ pkznosc2(pk0nosc2,d1,zval);
+ PkSpectrumZ pkznosc1(pk0nosc1,d1,zval);
+ PkSpectrumZ pkznob(pk0nob,d1,zval);
+
+ //--------------------------
+ Histo hd1(0.,20.,10000); hd1.ReCenterBin();
+ FuncToHisto(d1,hd1,false);
+
+ Histo hpkz(lkmin,lkmax,npt); hpkz.ReCenterBin();
+ FuncToHisto(pkz,hpkz,true);
+ TVector<r_8> vpkz(npt);
+ FuncToVec(pkz,vpkz,lkmin,lkmax,true);
+
+ FunRan talea(hpkz,true);
+ Histo halea(hpkz); halea.Zero();
+ int nalea = 100000;
+ for(int i=0;i<nalea;i++) halea.Add(talea.Random());
+ halea *= hpkz.Sum()/halea.Sum();
+
+ //--------------------------
+ const int n = 14;
+ char *vname[n] = {
+   "k","pkini",
+   "tf","pk0","pk",
+   "tfnosc2","pk0nosc2","pknosc2",
+   "tfnosc1","pk0nosc1","pknosc1",
+   "tfnob","pk0nob","pknob"
+ };
+ NTuple nt(n,vname);
+ double xnt[n];
+
+ for(double lk=lkmin;lk<lkmax+dlk/2.;lk+=dlk) {
+   double k = pow(10.,lk);
+   xnt[0] = k;
+   xnt[1] = pkini(k);
+   xnt[2] = tf(k);
+   xnt[3] = pk0(k);
+   xnt[4] = pkz(k,zval);
+   xnt[5] = tfnosc2(k);
+   xnt[6] = pk0nosc2(k);
+   xnt[7] = pkznosc2(k,zval);
+   xnt[8] = tfnosc1(k);
+   xnt[9] = pk0nosc1(k);
+   xnt[10] = pkznosc1(k,zval);
+   xnt[11] = tfnob(k);
+   xnt[12] = pk0nob(k);
+   xnt[13] = pkznob(k,zval);
+   nt.Fill(xnt);
+ }
+
+ //--------------------------
+ if(wrascii) {
+   cout<<">>>> ASCII"<<endl;
+   FILE * fdata = fopen("cmvtstpk.data","w");
+   fprintf(fdata,"# z= %g : k(Mpc^-1) pkini, tf pk0 pkz, tfnosc2 pk0nosc2 pkznosc2, ",zval);
+   fprintf(fdata,"tfnosc1 pk0nosc1 pkznosc1, tfnob pk0nob pkznob\n");
+   for(double lk=lkmin;lk<lkmax+dlk/2.;lk+=dlk) {
+     double k = pow(10.,lk);
+     fprintf(fdata,"%e %e %e %e %e %e %e %e %e %e %e %e %e %e\n",
+	     k,pkini(k),
+	     tf(k),pk0(k),scale*pkz(k,zval),
+	     tfnosc2(k),pk0nosc2(k),scale*pkznosc2(k,zval),
+	     tfnosc1(k),pk0nosc1(k),scale*pkznosc1(k,zval),
+	     tfnob(k),pk0nob(k),scale*pkznob(k,zval));
+   }
+   fclose(fdata);
+ }
+
+ //--------------------------
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtstpk.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+ tag = "hd1"; pos.PutObject(hd1,tag);
+ tag = "hpkz"; pos.PutObject(hpkz,tag);
+ tag = "vpkz"; pos.PutObject(vpkz,tag);
+ tag = "halea"; pos.PutObject(halea,tag);
+ return 0;
+}
+
+/*
+openppf cmvtstpk.ppf
+
+#### growth-factor
+zone
+n/plot hd1.val%x ! ! "nsta connectpoints"
+
+#### Spectre initial
+zone
+n/plot nt.log10(pkini)%log10(k) pkini>0. ! "nsta connectpoints"
+
+#### Gestion des abscisses
+set xk log10(k)
+set xk k
+
+#### fct de transfert
+zone
+n/plot nt.tf%$xk ! ! "nsta connectpoints"
+n/plot nt.tfnosc2%$xk ! ! "nsta connectpoints same red"
+n/plot nt.tfnosc1%$xk ! ! "nsta connectpoints same blue"
+n/plot nt.tfnob%$xk ! ! "nsta connectpoints same green"
+
+n/plot nt.tf/tfnosc2%$xk ! ! "nsta connectpoints red"
+n/plot nt.tf/tfnosc1%$xk ! ! "nsta connectpoints same blue"
+n/plot nt.tf/tfnob%$xk ! ! "nsta connectpoints same green"
+addline -10 1 10 1
+
+#### Spectre a z=0
+zone
+n/plot nt.pk0%$xk ! ! "nsta connectpoints"
+n/plot nt.pk0nosc2%$xk ! ! "nsta connectpoints same red"
+n/plot nt.pk0nosc1%$xk ! ! "nsta connectpoints same blue"
+n/plot nt.pk0nob%$xk ! ! "nsta connectpoints same green"
+
+# Check
+zone 2 2
+n/plot nt.pk0/pkini-tf*tf%$xk pkini>0 ! "nsta crossmarker3"
+n/plot nt.pk0nosc2/pkini-tfnosc2*tfnosc2%$xk pkini>0 ! "nsta crossmarker3"
+n/plot nt.pk0nosc1/pkini-tfnosc1*tfnosc1%$xk pkini>0 ! "nsta crossmarker3"
+n/plot nt.pk0nob/pkini-tfnob*tfnob%$xk pkini>0 ! "nsta crossmarker3"
+
+#### Spectre a z
+zone
+n/plot nt.pk%$xk ! ! "nsta connectpoints"
+n/plot nt.pknosc2%$xk ! ! "nsta connectpoints same red"
+n/plot nt.pknosc1%$xk ! ! "nsta connectpoints same blue"
+n/plot nt.pknob%$xk ! ! "nsta connectpoints same green"
+
+n/plot nt.pk/pknosc2%$xk ! ! "nsta connectpoints red"
+n/plot nt.pk/pknosc1%$xk ! ! "nsta connectpoints same blue"
+n/plot nt.pk/pknob%$xk ! ! "nsta connectpoints same green"
+addline -10 1 10 1
+
+#### Le spectre version Delta^2
+set D2 k*k*k*pk/(2*M_PI*M_PI)
+n/plot nt.$D2%$xk  !  ! "nsta crossmarker3 connectpoints"
+
+#### Test des transferts dans Histo et TVector
+zone 1 2
+n/plot nt.pk%log10(k) ! ! "nsta crossmarker3"
+disp hpkz "same red"
+
+disp vpkz
+c++exec cout<<hpkz(0)<<" =?= "<<vpkz(0)<<endl;
+
+zone
+disp hpkz
+disp halea "same red"
+
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtstsch.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtstsch.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtstsch.cc	(revision 3445)
@@ -0,0 +1,241 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "histos.h"
+#include "ntuple.h"
+#include "srandgen.h"
+#include "perandom.h"
+
+#include "geneutils.h"
+#include "cosmocalc.h"
+#include "schechter.h"
+
+void usage(void);
+void usage(void)
+{
+ cout<<"cmvtstsch -m xmin,xmax -a -i perc,dlxinc,dlxmax,glorder -n nbin -N nalea"<<endl
+     <<"  xmin,xmax : limites en masse"<<endl
+     <<"  perc : see IntegrateFunc"<<endl
+     <<"  dlnx : see IntegrateFunc"<<endl
+     <<"         si <0 nombre de point dlx = (log10(xmax)-log10(xmin))/(-dlx)"<<endl
+     <<"  dlxmax : see IntegrateFunc, si <0 -dlxmax*dlx, si ==0 no check"<<endl
+     <<"  glorder : odre gauss-legendre"<<endl
+     <<"  nbin : nombre de bins"<<endl
+     <<"  nalea : nombre de tirages aleatoires"<<endl
+     <<"  -a : init auto de l\'aleatoire"<<endl;
+}
+
+
+int main(int narg,char *arg[])
+{
+ double h75 = 0.71 / 0.75;
+ double nstar = 0.006*pow(h75,3.);  //  
+ double mstar = pow(10.,9.8);  // MSol
+ double alpha = -1.37;
+ cout<<"h75= "<<h75<<" nstar= "<<nstar<<"  mstar="<<mstar<<"  alpha="<<alpha<<endl;
+
+ double xmin=1e6, xmax=1e12;
+ double perc=0.01,dlxinc=-1000.,dlxmax=0.; unsigned short glorder=4;
+ int npt = 1000;
+ int nalea = 100000;
+
+ char c;
+ while((c = getopt(narg,arg,"ham:i:n:N:")) != -1) {
+   switch (c) {
+   case 'm' :
+     sscanf(optarg,"%lf,%lf",&xmin,&xmax);
+     break;
+   case 'i' :
+     int ig;
+     sscanf(optarg,"%lf,%lf,%lf,%u",&perc,&dlxinc,&dlxmax,&ig);
+     if(perc<=0.) perc = 0.01;
+     glorder = (ig<=0) ? 4: ig;
+     break;
+   case 'n' :
+     sscanf(optarg,"%d",&npt);
+     if(npt<=0) npt = 1000;
+     break;
+   case 'N' :
+     sscanf(optarg,"%d",&nalea);
+     break;
+   case 'a' :
+     Auto_Ini_Ranf(5);
+     break;
+   case 'h' :
+   default :
+     usage(); return -1;
+   }
+ }
+
+ double lnx1=log10(xmin), lnx2=log10(xmax), dlnx = (lnx2-lnx1)/npt;
+ cout<<"xmin="<<xmin<<" ("<<lnx1<<") xmax="<<xmax<<" ("<<lnx2<<"), dlnx="<<dlnx<<endl;
+
+ if(dlxinc<0.) dlxinc=(lnx2-lnx1)/(-dlxinc);
+ if(dlxmax<0.) dlxmax *= -dlxinc; else if(dlxmax==0.) dlxmax=-1.;
+ cout<<"perc="<<perc<<" dlxinc="<<dlxinc<<" dlxmax="<<dlxmax<<" glorder="<<glorder<<endl;
+
+ cout<<"npt="<<npt<<",  nalea="<<nalea<<endl;
+
+ Schechter sch(nstar,mstar,alpha);
+
+ InitTim();
+
+ //-------dn/dm
+ cout<<endl;
+ cout<<"sch(mstar) = "<<sch(mstar)<<" /Mpc^3/Msol"<<endl;
+ sch.SetOutValue(0);
+ cout<<"......"<<endl;
+ for(double lnx=lnx1-3.;lnx<=lnx2-1.;lnx+=1.) {
+   double num = sch.Integrate(pow(10.,lnx),pow(10.,lnx2),npt);
+   double numc = IntegrateFuncLog(sch,lnx,lnx2,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx<<","<<lnx2<<"] integrated number = "<<num<<" Mpc^-3 , check: "<<numc<<endl;
+ }
+ cout<<"......"<<endl;
+ for(double lnx=lnx1+1.;lnx<=lnx2+3.;lnx+=1.) {
+   double num = sch.Integrate(pow(10.,lnx1),pow(10.,lnx),npt);
+   double numc = IntegrateFuncLog(sch,lnx1,lnx,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx1<<","<<lnx<<"] integrated number = "<<num<<" Mpc^-3 , check: "<<numc<<endl;
+ }
+ cout<<"......"<<endl;
+ for(double lnx=lnx1-3.;lnx<=lnx2+3.;lnx+=1.) {
+   double num = sch.Integrate(pow(10.,lnx),pow(10.,lnx+1.),npt);
+   double numc = IntegrateFuncLog(sch,lnx,lnx+1.,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx<<","<<lnx+1.<<"] integrated number = "<<num<<" Mpc^-3 , check: "<<numc<<endl;
+ }
+ Histo hdndm(lnx1,lnx2,npt); hdndm.ReCenterBin();
+ FuncToHisto(sch,hdndm,true);
+
+ //-------m*dn/dm
+ cout<<endl;
+ sch.SetOutValue(1);
+ cout<<"mstar*sch(mstar) = "<<sch(mstar)<<" Msol/Mpc^3/Msol"<<endl;
+ cout<<"......"<<endl;
+ for(double lnx=lnx1-3.;lnx<=lnx2-1.;lnx+=1.) {
+   double sum = sch.Integrate(pow(10.,lnx),pow(10.,lnx2),npt);
+   double sumc = IntegrateFuncLog(sch,lnx,lnx2,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx<<","<<lnx2<<"] integrated mass = "<<sum<<" Msol.Mpc^-3 , check: "<<sumc<<endl;
+ }
+ cout<<"......"<<endl;
+ for(double lnx=lnx1+1.;lnx<=lnx2+3.;lnx+=1.) {
+   double sum = sch.Integrate(pow(10.,lnx1),pow(10.,lnx),npt);
+   double sumc = IntegrateFuncLog(sch,lnx1,lnx,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx1<<","<<lnx<<"] integrated mass = "<<sum<<" Msol.Mpc^-3 , check: "<<sumc<<endl;
+ }
+ cout<<"......"<<endl;
+ for(double lnx=lnx1-3.;lnx<=lnx2+3.;lnx+=1.) {
+   double sum = sch.Integrate(pow(10.,lnx),pow(10.,lnx+1.),npt);
+   double sumc = IntegrateFuncLog(sch,lnx,lnx+1.,perc,dlxinc,dlxmax,glorder);
+   cout<<"["<<lnx<<","<<lnx+1.<<"] integrated mass = "<<sum<<" Msol.Mpc^-3 , check: "<<sumc<<endl;
+ }
+ Histo hmdndm(lnx1,lnx2,npt); hmdndm.ReCenterBin();
+ FuncToHisto(sch,hmdndm,true);
+
+ //------- Le flux HI pour M=mstar a 1 Gpc
+ cout<<endl;
+ double d = 1000.;
+ double f = Msol2FluxHI(mstar,d);
+ cout<<"FluxHI: d="<<d<<" Mpc:"<<"  M= "<<mstar<<" Msol  "
+     <<"-> Flux= "<<f<<" W/m^2"<<endl;
+ cout<<"Check... MassHI: d="<<d<<" Mpc:"<<"  f= "<<f<<" W/m^2  "
+     <<"-> Mass= "<<FluxHI2Msol(f,d)<<" Msol"<<endl;
+
+ //------- Random
+ Histo hdna(hdndm); hdna.Zero();
+ Histo hmdna(hmdndm); hmdna.Zero();
+ FunRan tirhdndm = FunRan(hdndm,true);
+ FunRan tirhmdndm = FunRan(hmdndm,true);
+ if(nalea>0) {
+   double summ=0.;
+   PrtTim("--- avant tirage aleatoire");
+   for(int i=0;i<nalea;i++) {
+     double a = tirhdndm.RandomInterp();
+     hdna.Add(a);
+     a = tirhmdndm.RandomInterp();
+     summ += pow(10.,a);
+     hmdna.Add(a);
+   }
+   cout<<"Tirgae aleatoire: <m>="<<summ/(double)nalea<<endl;
+   hdna *= hdndm.Sum()/hdna.Sum();
+   hmdna *= hmdndm.Sum()/hmdna.Sum();
+   PrtTim("--- apres tirage aleatoire");
+ }
+
+ //-------
+ const int n = 3;
+ char *vname[n] = {"m","f","mf"};
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(double lx=lnx1;lx<lnx2+dlnx/2.;lx+=dlnx) {
+   double x = pow(10.,lx);
+   xnt[0]  = x;
+   sch.SetOutValue(0);
+   xnt[1]  = sch(x);
+   sch.SetOutValue(1);
+   xnt[2]  = sch(x);
+   nt.Fill(xnt);
+ }
+
+ cout<<"Ecriture"<<endl;
+ string tag = "cmvtstsch.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+ tag = "hdndm"; pos.PutObject(hdndm,tag);
+ tag = "hmdndm"; pos.PutObject(hmdndm,tag);
+ tag = "hdna"; pos.PutObject(hdna,tag);
+ tag = "hmdna"; pos.PutObject(hmdna,tag);
+ Histo hdum1(tirhdndm);
+ tag = "tirhdndm"; pos.PutObject(hdum1,tag);
+ Histo hdum2(tirhmdndm);
+ tag = "tirhmdndm"; pos.PutObject(hdum2,tag);
+
+ return 0;
+}
+
+/*
+openppf cmvtstsch.ppf
+
+#--- la fonction de masse numerique
+zone 2 2
+n/plot nt.f%m ! ! "nsta crossmarker3"
+n/plot nt.f%log10(m) ! ! "nsta crossmarker3"
+n/plot nt.log10(f)%log10(m) f>0. ! "nsta crossmarker3"
+
+# ce qu'on integre (en log10)
+n/plot nt.m*f%log10(m) ! ! "nsta crossmarker3"
+
+#--- la fonction de masse
+zone 2 2
+n/plot nt.mf%m ! ! "nsta crossmarker3"
+n/plot nt.mf%log10(m) f>0. ! "nsta crossmarker3"
+n/plot nt.log10(mf)%log10(m) mf>0. ! "nsta crossmarker3"
+
+# ce qu'on integre (en log10)
+n/plot nt.m*mf%log10(m) ! ! "nsta crossmarker3"
+
+#--- Check histos
+zone 2 1
+disp hdndm "red"
+n/plot nt.f%log10(m) ! ! "nsta crossmarker3 same"
+
+disp hmdndm "red"
+n/plot nt.m*f%log10(m) ! ! "nsta crossmarker3 same"
+
+#--- Check tirage aleatoire
+zone 2 1
+disp hdndm
+disp hdna "same red"
+
+disp hmdndm
+disp hmdna "same red"
+
+zone
+disp tirhdndm
+disp tirhmdndm "same red"
+
+ */
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtuniv.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtuniv.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtuniv.cc	(revision 3445)
@@ -0,0 +1,307 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "cosmocalc.h"
+#include "geneutils.h"
+
+void tstprint(CosmoCalc& univ,double z1,double z2,double dz);
+void tstprint(CosmoCalc& univ1,CosmoCalc& univ2,double z1,double z2,double dz);
+void tstspeed(CosmoCalc& univ,double z1,double z2,double dz);
+void tstntuple(CosmoCalc& univ,double z1,double z2,double dz);
+void tstinterp(CosmoCalc& univ,double z1,double z2,double dz);
+
+const double deg2rad = M_PI/180.;
+
+void usage(void);
+void usage(void) {
+ cout
+ <<"cmvtuniv [options] z1,z2"<<endl
+ <<"  -D dz"<<endl
+ <<"  -U h100,om0,or0,ol0,w0"<<endl
+ <<"  -F flat(0,1,2)"<<endl
+ <<"  -I perc,dzinc,dzmax,glorder"<<endl
+ <<" --- What has to be done:"<<endl
+ <<"  -W 1/2/3/4/5"<<endl
+ <<"     1 : print info from z1 to z2 by step dz"<<endl
+ <<"     2 : compare with/without spline from z1 to z2 by step dz"<<endl
+ <<"     3 : test speed from z1 to z2 by step dz"<<endl
+ <<"     4 : fill ntuple with infos from z1 to z2 by step dz"<<endl
+ <<"     5 : test interpolation loscom from z1 to z2 by step dz"<<endl
+ <<endl;
+}
+
+int main(int narg,char *arg[])
+{
+ unsigned short flat = 0;
+ // -- WMAP
+ double h100=0.71, om0=0.267804, or0=7.9e-05, ol0=0.73,w0=-1.;
+ // -- ouvert matter only
+ //double h100=0.71, om0=0.3, or0=0., ol0=0.,w0=-1.;
+ // -- plat matter only
+ //double h100=0.71, om0=1., or0=0., ol0=0.,w0=-1.; flat = 1;
+ // -- plat lambda only
+ //double h100=0.71, om0=0., or0=0., ol0=1.,w0=-1.; flat = 2;
+
+ // -- parametre d'integration
+ double perc=0.01,dzinc=-1.,dzmax=-1.;
+ unsigned short glorder=4;
+ // -- redshift
+ double z1=0., z2=-1., dz=-1.;
+ // -- Work to be done
+ int todo = 1;
+
+ InitTim();
+
+ // Read arguments
+ char c;
+ while ((c = getopt(narg, arg, "hD:U:F:I:W:")) != -1) {
+  switch (c) {
+  case 'D' :
+    sscanf(optarg,"%lf",&dz);
+    break;
+  case 'U' :
+    sscanf(optarg,"%lf,%lf,%lf,%lf,%lf",&h100,&om0,&or0,&ol0,&w0);
+    break;
+  case 'F' :
+    sscanf(optarg,"%hu",&flat);
+    break;
+  case 'I' :
+    sscanf(optarg,"%lf,%lf,%lf,%hu",&perc,&dzinc,&dzmax,&glorder);
+    break;
+  case 'W' :
+    sscanf(optarg,"%d",&todo);
+    break;
+  case 'h' :
+  default:
+    usage();
+    return -1;
+  }
+}
+ if(optind<narg) sscanf(arg[optind],"%lf,%lf",&z1,&z2);
+
+ if(z1<0.) z1 = 0.;
+ if(z2<=z1) z2 = z1+1.;
+ if(dz<=0.) dz = 10.*(z2-z1);
+ cout<<"z1="<<z1<<"  z2="<<z2<<"  dz="<<dz<<endl;
+ cout<<"perc="<<perc<<" dzinc="<<dzinc<<" dzmax="<<dzmax<<" glorder="<<glorder<<endl;
+ cout<<"h100="<<h100<<" om0="<<om0<<" or0="<<or0<<" ol0="<<ol0<<" w0="<<w0<<" flat="<<flat<<endl;
+ cout<<"todo ="<<todo<<endl;
+
+ CosmoCalc univ1(flat,true,z2);
+ univ1.SetInteg(perc,dzinc,dzmax,glorder);
+ univ1.SetDynParam(h100,om0,or0,ol0,w0);
+ univ1.PrtInteg();
+ univ1.Print();
+ cout<<endl;
+
+ if(todo==1)  tstprint(univ1,z1,z2,dz);
+ else if(todo==2) {
+   CosmoCalc univ2(flat,false,z2);
+   univ2.SetInteg(perc,dzinc,dzmax,glorder);
+   univ2.SetDynParam(h100,om0,or0,ol0,w0);
+   univ2.PrtInteg();
+   univ2.Print();
+   tstprint(univ1,univ2,z1,z2,dz);
+ }
+ else if(todo==3) tstspeed(univ1,z1,z2,dz);
+ else if(todo==4) tstntuple(univ1,z1,z2,dz);
+ else if(todo==5)tstinterp(univ1,z1,z2,dz);
+ else cout<<"Unknown job to be done !!!!!  todo="<<todo<<endl;
+
+ return 0;
+}
+
+/* ----------------------------------------------------- */
+void tstprint(CosmoCalc& univ,double z1,double z2,double dz)
+{
+ if(dz>z2-z1) dz = z2-z1;
+ cout<<"\nTSTPRINT(): z1="<<z1<<" z2="<<z2<<" dz="<<dz<<endl;
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   cout<<"-- z = "<<z<<endl;
+   univ.Print(z);
+   cout<<"Volume comoving in [z,z+"<<dz<<"] for 4Pi sr: "
+       <<univ.Vol4Pi(z,z+dz)<<" Mpc^3"<<endl;
+   double dang = univ.Dang(z);
+   double a = deg2rad/3600.;
+   cout<<"1\" -> "<<dang*a<<" Mpc = "<<dang*a*(1.+z)<<" Mpc com"<<endl;
+   a = deg2rad/60.;
+   cout<<"1\' -> "<<dang*a<<" Mpc = "<<dang*a*(1.+z)<<" Mpc com"<<endl;
+   a = deg2rad;
+   cout<<"1d -> "<<dang*a<<" Mpc = "<<dang*a*(1.+z)<<" Mpc com"<<endl;
+   double dloscom = univ.Dhubble() / univ.E(z);
+   cout<<"dz=1 -> "<<dloscom<<" Mpc com"<<endl;
+ }
+
+}
+
+/* ----------------------------------------------------- */
+void tstprint(CosmoCalc& univ1,CosmoCalc& univ2,double z1,double z2,double dz)
+{
+ if(dz>z2-z1) dz = z2-z1;
+ cout<<"\nTSTPRINT(): z1="<<z1<<" z2="<<z2<<" dz="<<dz<<endl;
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   cout<<endl<<"--spline: z = "<<z<<endl;
+   univ1.Print(z);
+   cout<<"Volume comoving in [z,z+dz] for 4Pi sr: "
+       <<univ1.Vol4Pi(z,z+dz)<<" Mpc^3"<<endl;
+   cout<<"--integ: z = "<<z<<endl;
+   univ2.Print(z);
+   cout<<"Volume comoving in [z,z+dz] for 4Pi sr: "
+       <<univ2.Vol4Pi(z,z+dz)<<" Mpc^3"<<endl;
+ }
+}
+
+/* ----------------------------------------------------- */
+void tstspeed(CosmoCalc& univ,double z1,double z2,double dz)
+{
+ if(dz>z2-z1) dz = z2-z1;
+ cout<<"\nTSTSPEED(): z1="<<z1<<" z2="<<z2<<" dz="<<dz<<endl;
+ double sum = 0.;
+ int_4 n=0;
+ PrtTim("-- Beginning");
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   sum += univ.Dang(z);
+   n++;
+ }
+ if(n>0) cout<<"n="<<n<<" ...dum="<<sum/n<<endl;
+ PrtTim("-- Ending");
+}
+
+/* ----------------------------------------------------- */
+void tstntuple(CosmoCalc& univ,double z1,double z2,double dz)
+{
+ if(dz>z2-z1) dz = z2-z1;
+ cout<<"\nTSTNTUPLE(): z1="<<z1<<" z2="<<z2<<" dz="<<dz<<endl;
+ double norm =  univ.Dhubble();  // 1.
+ double norm3 = pow(norm,3.);
+ const int n = 15;
+ char *vname[n] = {
+   "z","hz","om","or","ol","ok","ot","ob",
+   "dtc","dlc","da","dl",
+   "dvc","vc0","vcdz"
+ };
+ NTuple nt(n,vname);
+ double xnt[n];
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   xnt[0]  = z;
+   xnt[1]  = univ.H(z);
+   xnt[2]  = univ.Omatter(z);
+   xnt[3]  = univ.Orelat(z);
+   xnt[4]  = univ.Olambda(z);
+   xnt[5]  = univ.Ocurv(z);
+   xnt[6]  = univ.Otot(z);
+   xnt[7]  = univ.Obaryon(z);
+   xnt[8]  = univ.Dtrcom(z)/norm;
+   xnt[9]  = univ.Dloscom(z)/norm;
+   xnt[10] = univ.Dang(z)/norm;
+   xnt[11] = univ.Dlum(z)/norm;
+   xnt[12] = univ.dVol(z)/norm3;
+   xnt[13] = univ.Vol4Pi(z)/norm3;
+   xnt[14] = univ.Vol4Pi(z,z+dz)/norm3;
+   nt.Fill(xnt);
+ }
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtuniv_nt.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+}
+
+
+/*
+openppf cmvtuniv_nt.ppf
+
+set cut 1
+set cut z<100.
+set cut z<10.
+
+zone
+n/plot nt.hz%z $cut ! "nsta connectpoints"
+
+zone
+n/plot nt.dl%z $cut ! "nsta connectpoints"
+n/plot nt.da%z $cut ! "nsta connectpoints same red"
+n/plot nt.dtc%z $cut ! "nsta connectpoints same blue"
+n/plot nt.dlc%z $cut ! "nsta connectpoints same green"
+
+zone 2 2
+n/plot nt.dvc%z $cut ! "nsta connectpoints"
+n/plot nt.vc0%z $cut ! "nsta connectpoints"
+n/plot nt.vcdz%z $cut ! "nsta connectpoints"
+
+zone
+n/plot nt.ot%z $cut ! "nsta connectpoints"
+n/plot nt.om%z $cut ! "nsta connectpoints same blue"
+n/plot nt.or%z $cut ! "nsta connectpoints same red"
+n/plot nt.ol%z $cut ! "nsta connectpoints same green"
+n/plot nt.ok%z $cut ! "nsta connectpoints same orange"
+
+ */
+
+/* ----------------------------------------------------- */
+void tstinterp(CosmoCalc& univ,double z1,double z2,double dz)
+{
+ if(dz>z2-z1) dz = z2-z1;
+ cout<<"\nTSTINTERP(): z1="<<z1<<" z2="<<z2<<" dz="<<dz<<endl;
+ // On remplit les donnes completes
+ vector<double> Z,D;
+ for(double z=z1;z<z2+dz/2.;z+=dz) {
+   Z.push_back(z);
+   D.push_back(univ.Dloscom(z));
+ }
+ // On remplit un sous tableau
+ int ninc = 5;
+ vector<double> Dinterp;
+ double zmin = Z[0], zmax = Z[0];
+ for(unsigned int i=0;i<Z.size();i+=ninc) {
+   Dinterp.push_back(D[i]);
+   zmax = Z[i];
+ }
+ InterpFunc interp(zmin,zmax,Dinterp);
+ unsigned short ok;
+
+ const int n = 8;
+ char *vname[n] = {"z","d","di","dl","dp","zi","zl","zp"};
+ NTuple nt(n,vname);
+ double xnt[n];
+   
+ for(unsigned int i=0;i<Z.size();i++) {
+   if(Z[i]>zmax) break;
+   xnt[0] = Z[i];
+   xnt[1] = D[i];
+   xnt[2] = interp(Z[i]);
+   xnt[3] = interp.Linear(Z[i],ok);
+   xnt[4] = interp.Parab(Z[i],ok);
+   xnt[5] = xnt[6] = xnt[7] = 0.;
+   nt.Fill(xnt);
+ }
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtuniv_int.ppf";
+ POutPersist pos(tag);
+ tag = "nt"; pos.PutObject(nt,tag);
+}
+
+/*
+openppf cmvtuniv_int.ppf
+
+n/plot nt.d%z ! ! "nsta connectpoints"
+n/plot nt.di%z ! ! "nsta connectpoints same green"
+n/plot nt.dl%z ! ! "nsta connectpoints same red"
+n/plot nt.dp%z ! ! "nsta connectpoints same blue"
+
+n/plot nt.di-d%z ! ! "nsta connectpoints green"
+n/plot nt.dl-d%z ! ! "nsta connectpoints same red"
+n/plot nt.dp-d%z ! ! "nsta connectpoints same blue"
+
+n/plot nt.(di-d)/d%z d>0 ! "nsta connectpoints green"
+n/plot nt.(dl-d)/d%z d>0 ! "nsta connectpoints same red"
+n/plot nt.(dp-d)/d%z d>0 ! "nsta connectpoints same blue"
+
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/cmvtvarspec.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cmvtvarspec.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cmvtvarspec.cc	(revision 3445)
@@ -0,0 +1,197 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntuple.h"
+
+#include "constcosmo.h"
+#include "pkspectrum.h"
+
+void usage(void);
+void usage(void)
+{
+  cout<<"cmvtvarspec -z zref -R R -n as,ns -k kmin,kmax -i eps,npt,fracmax"<<endl;
+}
+
+
+int main(int narg,char *arg[])
+{
+ double ob0 = 0.0444356;
+ // -- WMAP
+ double h100=0.71, om0=0.267804, ol0=0.73;
+ // -- ouvert matter only
+ //double h100=0.71, om0=0.3, ol0=0.;
+ // -- plat matter only
+ //double h100=0.71, om0=1., ol0=0.;
+
+ double ns = 1., as = 1.;
+
+ double zref = 0.5;
+ double R=8./h100;
+
+ double kmin=1e-5,kmax=1000.;
+ int npt = 10000;
+ double eps=1.e-3, fracmax=1e-4;
+
+ char c;
+ while((c = getopt(narg,arg,"hz:R:n:k:i:")) != -1) {
+  switch (c) {
+  case 'z' :
+    sscanf(optarg,"%lf",&zref);
+    break;
+  case 'R' :
+    sscanf(optarg,"%lf",&R);
+    if(R<0.) R = -R/h100;
+    break;
+  case 'n' :
+    sscanf(optarg,"%lf,%lf",&as,&ns);
+    break;
+  case 'k' :
+    sscanf(optarg,"%lf,%lf",&kmin,&kmax);
+    break;
+  case 'i' :
+    sscanf(optarg,"%lf,%d,%lf",&eps,&npt,&fracmax);
+    break;
+  case 'h' :
+  default :
+    usage(); return -1;
+  }
+ }
+
+ double Rg=R/sqrt(5.);
+ double lkmin=log10(kmin), lkmax=log10(kmax), dlk=(lkmax-lkmin)/npt;
+
+ cout<<"zref="<<zref<<endl;
+ cout<<"as="<<as<<" ns="<<ns<<endl;
+ cout<<"R="<<R<<", Rg="<<Rg<<endl;
+ cout<<"kmin="<<kmin<<" ("<<lkmin<<"), kmax="<<kmax<<" ("<<lkmax<<")"
+     <<", dlk="<<dlk<<" npt="<<npt<<endl;
+ cout<<"eps="<<eps<<"  fracmax="<<fracmax<<endl;
+
+ //-----------------------------------------------------------------
+ InitialSpectrum pkini(ns,as);
+
+ TransfertEisenstein tf(h100,om0-ob0,ob0,T_CMB_Par,false);
+ //tf.SetNoOscEnv(2);
+
+ GrowthFactor d1(om0,ol0);
+
+ PkSpectrum0 pk0(pkini,tf);
+
+ PkSpectrumZ pkz(pk0,d1,zref);
+
+ //-----------------------------------------------------------------
+ double k1,k2;
+ int rc = 0;
+ //----
+ cout<<endl<<"Filtrage top_hat"<<endl;
+ VarianceSpectrum varpk_th(pkz,R,VarianceSpectrum::TOPHAT);
+ double kfind_th = varpk_th.FindMaximum(kmin,kmax,eps);
+ double pkmax_th = varpk_th(kfind_th);
+ cout<<"kfind_th = "<<kfind_th<<" ("<<log10(kfind_th)<<"), integrand="<<pkmax_th<<endl;
+ k1=kmin, k2=kmax;
+ rc = varpk_th.FindLimits(pkmax_th*fracmax,k1,k2,eps);
+ cout<<"limit_th: rc="<<rc<<" : "<<k1<<" ("<<log10(k1)<<") , "<<k2<<" ("<<log10(k2)<<")"<<endl;
+
+ varpk_th.SetInteg(0.01,dlk,-1.,4);
+ cout<<"varpk_th="<<varpk_th.Variance(k1,k2)<<endl;
+
+ //----
+ cout<<endl<<"Filtrage gaussien"<<endl;
+ VarianceSpectrum varpk_ga(pkz,Rg,VarianceSpectrum::GAUSSIAN);
+ double kfind_ga = varpk_ga.FindMaximum(kmin,kmax,eps);
+ double pkmax_ga = varpk_ga(kfind_ga);
+ cout<<"kfind_ga = "<<kfind_ga<<" -> "<<log10(kfind_ga)<<", integrand="<<pkmax_ga<<endl;
+ k1=kmin, k2=kmax;
+ rc = varpk_ga.FindLimits(pkmax_ga*fracmax,k1,k2,eps);
+ cout<<"limit_ga: rc="<<rc<<" : "<<k1<<" ("<<log10(k1)<<") , "<<k2<<" ("<<log10(k2)<<")"<<endl;
+
+ varpk_ga.SetInteg(0.01,dlk,-1.,4);
+ cout<<"varpk_ga="<<varpk_ga.Variance(k1,k2)<<endl;
+ 
+ //----
+  cout<<endl<<"Filtrage 1 (integrale du spectre)"<<endl;
+ VarianceSpectrum varpk_int(pkz,Rg,VarianceSpectrum::NOFILTER);
+ double kfind_int = varpk_int.FindMaximum(kmin,kmax,eps);
+ double pkmax_int = varpk_int(kfind_int);
+ cout<<"kfind_int = "<<kfind_int<<" -> "<<log10(kfind_int)<<", integrand="<<pkmax_int<<endl;
+ k1=kmin, k2=kmax;
+ rc = varpk_int.FindLimits(pkmax_int*fracmax,k1,k2,eps);
+ cout<<"limit_int: rc="<<rc<<" : "<<k1<<" ("<<log10(k1)<<") , "<<k2<<" ("<<log10(k2)<<")"<<endl;
+
+ varpk_int.SetInteg(0.01,dlk,-1.,4);
+ cout<<"varpk_int="<<varpk_int.Variance(k1,k2)<<endl;
+ 
+//-----------------------------------------------------------------
+ const int n = 2;
+ char *vname[n] = {"k","pk"};
+ NTuple nt(n,vname);
+ double xnt[n];
+
+ for(double lk=lkmin;lk<lkmax+dlk/2.;lk+=dlk) {
+   double k = pow(10.,lk);
+   xnt[0] = k;
+   xnt[1] = pkz(k);
+   nt.Fill(xnt);
+ }
+
+ cout<<">>>> Ecriture"<<endl;
+ string tag = "cmvtvarspec.ppf"; POutPersist pos(tag); tag = "nt"; pos.PutObject(nt,tag);
+
+ return 0;
+}
+
+/*
+openppf cmvtvarspec.ppf
+
+#### Spectre a z
+n/plot nt.pk%log10(k) ! ! "nsta crossmarker3"
+
+# L'approximation pour j1(x) (top-hat) et la gaussienne equivalente
+set l1 1e-6
+set l2 10
+set j1sx pow(3*(sin(x)-x*cos(x))/(x*x*x),2.)
+set j1sxa3 (1.-x*x/5.)
+set j1sxa5 (1.-x*x/5.*(1.-3.*x*x/35.))
+set j1sxa7 (1.-x*x/5.*(1.-3.*x*x/35.*(1.-4.*x*x/81.)))
+func $j1sx    $l1 $l2 1000
+func $j1sxa3  $l1 $l2 1000 "red same"
+func $j1sxa5  $l1 $l2 1000 "blue same"
+func $j1sxa7  $l1 $l2 1000 "orange same"
+set gauss  pow(exp(-(x/sqrt(5.))*(x/sqrt(5.))/2.),2.)
+func $gauss  $l1 $l2 1000 "green same"
+
+func $j1sx-$j1sxa3  $l1 $l2 1000 "red"
+func $j1sx-$j1sxa5  $l1 $l2 1000 "blue same"
+func $j1sx-$j1sxa7  $l1 $l2 1000 "orange same"
+func $j1sx-$gauss  $l1 $l2 1000 "green same"
+addline $l1 0 $l2 0
+
+# la fonction "Pk" a integrer
+zone
+set D (k*k*pk/(2.*M_PI*M_PI))
+n/plot nt.$D%log10(k) ! ! "nsta crossmarker3"
+
+# La fonction a integrer en dk lineaire (top-hat et gaussien)
+set R 10
+set RG ($R/sqrt(5.))
+set x (k*$R)
+set j1sx pow(3*(sin($x)-$x*cos($x))/($x*$x*$x),2.)
+set y (k*$RG)
+set gauss  pow(exp(-$y*$y/2.),2.)
+
+n/plot nt.$D*$j1sx%log10(k) ! ! "nsta crossmarker3"
+n/plot nt.$D*$gauss%log10(k) ! ! "nsta crossmarker3 same red"
+
+# La fonction a integrer en d(log(x)) (top-hat et gaussien)
+# c'est ce que fait Variance()
+n/plot nt.k*$D*$j1sx%log10(k) ! ! "nsta crossmarker3"
+n/plot nt.k*$D*$gauss%log10(k) ! ! "nsta crossmarker3 same red"
+n/plot nt.k*$D%log10(k) ! ! "nsta crossmarker3 same blue"
+
+*/
Index: /tags/V_Nov2007/Cosmo/SimLSS/constcosmo.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/constcosmo.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/constcosmo.h	(revision 3445)
@@ -0,0 +1,26 @@
+#ifndef CONSTCOSMO_SEEN
+#define CONSTCOSMO_SEEN
+
+static const double SpeedOfLight_Cst = 299792.458; // speed of light "km/sec"
+static const double G_Newton_Cst = 6.6742e-11; // G_N in SI units "m^3 / kg /s^2"
+static const double h_Planck_Cst = 6.6260693e-34;   // Planck constant SI units "J s"
+static const double k_Boltzman_Cst = 1.3806503e-23;  // Boltzman constant SI "J / K"
+//            Sigma = 2*PI^5*K^4/(15.*C^2*H^3) = PI^2*K^4/(60.*Hbar^3*C2)
+static const double StefBoltz_Cst = 5.670400e-8; // constante de Stefan-Boltzman in "W/m^2/K^4"
+static const double Zeta_3_Cst = 1.2020569031595942854; // Zeta(3)
+
+static const double YeartoSec_Cst = 31556925.2; // 1 year into seconds
+static const double MpctoMeters_Cst = 3.0856e+22; // 1 Mpc into meters
+static const double LightYear_Cst = 9.46073042e+15; // 1 Light-Year into "m"
+static const double Jansky2Watt_cst = 1.e-26;  // 1 Jansky into "Watt/m^2/Hz == J/m^2"
+static const double SolarMass_Cst = 1.98844e+33; // 1 Solar mass into "g"
+//                  GCm3toMsolMpc3_Cst = (MpctoMeters_Cst*100)^3 / SolarMass_Cst
+static const double GCm3toMsolMpc3_Cst = 1.477428208143872e+40; // 1 g/cm^3 into 1 Msol/Mpc^3
+static const double ProtonMass_Cst = 1.67262171e-24; // 1 "proton mass" in "g"
+static const double Deg2Rad_Cst = (M_PI/180.); // 1 deg into rad
+
+static const double T_CMB_Par = 2.725;  // temperature du CMB en "K"
+static const double T_NU_Par = 1.9;  // temperature des neutrinos en "K"
+static const double Fr_HyperFin_Par = 1.420405751786;  // frequence de la raie hyperfine HI en "GHz"
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.cc	(revision 3445)
@@ -0,0 +1,459 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "pexceptions.h"
+#include "cspline.h"
+
+#include "constcosmo.h"
+#include "cosmocalc.h"
+#include "geneutils.h"
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////
+//*********************** CosmoCalc *********************//
+///////////////////////////////////////////////////////////
+
+//----------------------------------------------------------
+// flat = 0 : no compute Otot from other
+//      = 1 : change Omatter to get Otot=1
+//      = 2 : change Olambda to get Otot=1
+//      = 3 : change Orelat to get Otot=1
+// usespline = "true" : compute integrale then use spline to extrapolate
+//           = "false" : compute integrale everytime
+// zmax : maximum redshift(only if usespline=true)
+         
+CosmoCalc::CosmoCalc(unsigned short flat,bool usespline,double zmax)
+  : _flat(flat),
+    _zold(-1.) , _integval(0.),
+    _usespline(usespline), _computespl(true), _zmax(zmax), _spline(NULL),
+    _nspl(0), _xspl(NULL), _yspl(NULL)
+{
+  if(_usespline && _zmax<=0.) {
+    cout<<"CosmoCalc::CosmoCalc: Error bad _zmax value    zmax="<< _zmax<<endl;
+    throw ParmError("CosmoCalc::UseSpline: Error bad _zmax value");
+  }
+  DefaultParam();
+  SetInteg();
+}
+
+CosmoCalc::CosmoCalc(CosmoCalc& univ)
+  : _spline(NULL), _xspl(NULL), _yspl(NULL)
+{
+  Clone(univ);
+  if(_usespline && _zmax<=0.) {
+    cout<<"CosmoCalc::CosmoCalc: Error bad _zmax value    zmax="<< _zmax<<endl;
+    throw ParmError("CosmoCalc::UseSpline: Error bad _zmax value");
+  }
+}
+
+CosmoCalc::~CosmoCalc(void)
+{
+  if(_spline != NULL) delete _spline; _spline = NULL;
+  if(_xspl != NULL) delete [] _xspl; _xspl = NULL;
+  if(_yspl != NULL) delete [] _yspl; _yspl = NULL;
+}
+
+void CosmoCalc::Clone(CosmoCalc& univ)
+{
+ _flat = univ._flat;
+ _h100 = univ._h100;
+ _H0 = univ._H0;
+ _Olambda0 = univ._Olambda0;
+ _W0 = univ._W0;
+ _Omatter0 = univ._Omatter0;
+ _Obaryon0 = univ._Obaryon0;
+ _Orelat0 = univ._Orelat0;
+ _Otot0 = univ._Otot0;
+ _Ocurv0 = univ._Ocurv0;
+ _Dhubble = univ._Dhubble;
+
+ _dperc = univ._dperc;
+ _dzinc = univ._dzinc;
+ _dzmax = univ._dzmax;
+ _glorder = univ._glorder;
+ if(_xgausl.size()>0) {
+   _xgausl.resize(0); _wgausl.resize(0);
+   for(int i=0;i<(int)_xgausl.size();i++) {
+     _xgausl.push_back(univ._xgausl[i]);
+     _wgausl.push_back(univ._wgausl[i]);
+   }
+ }
+
+ _zold = -1.;
+ _integval = -1.;
+
+ _usespline = univ._usespline;
+ _computespl = true;
+ _zmax = univ._zmax;
+ _nspl = 0;
+ if(_spline) delete _spline; _spline = NULL;
+ if(_xspl) delete [] _xspl; _xspl = NULL;
+ if(_yspl) delete [] _yspl; _yspl = NULL;
+}
+
+//----------------------------------------------------------
+// On va couper l'intervalle entre [0,zmax]:
+// On parcourt [0,zmax] par pas de dzinc
+// et on cree un intervalle
+//     - si la fonction varie de plus de "dperc"
+//     - ou si l'increment en z est superieur a "dzmax"
+void CosmoCalc::SetInteg(double dperc,double dzinc,double dzmax,unsigned short order)
+{
+  _dperc = dperc; _dzinc = dzinc; _dzmax = dzmax;
+
+  if(_dperc<=0.) _dperc = 0.01;
+
+  if(_dzinc<=0.) _dzinc = _zmax/100.;
+  if(_dzinc>=_zmax/2.) _dzinc = _zmax/2.; // Protection against big dzinc
+
+  if(_dzmax<=0.) _dzmax = _zmax;
+  if(_dzmax<_dzinc) _dzmax = _dzinc;
+
+  _glorder = order;
+  if(_glorder<=1) _glorder = 4;
+  Compute_GaussLeg(_glorder,_xgausl,_wgausl,0.,1.);
+
+  _computespl=true;
+}
+
+
+void CosmoCalc::PrtInteg(void)
+{
+ printf("CosmoCalc::PrtInteg: dperc=%g dzinc=%g dzmax=%g glorder=%hu\n",_dperc,_dzinc,_dzmax,_glorder);
+}
+
+void CosmoCalc::SetObaryon0(double v)
+{
+  _Obaryon0 = v;
+  if(_Obaryon0<0.) {
+    cout<<"CosmoCalc::SetObaryon0: Error bad _Obaryon0 value: "<<_Obaryon0<<endl;
+    throw ParmError("CosmoCalc::SetObaryon0: Error bad _Obaryon0 value");
+  }
+}
+
+void CosmoCalc::SetDynParam(double h100,double om0,double or0,double ol0,double w0)
+{
+  _computespl=true;
+
+  _h100 = h100;
+  _H0 = 100. * _h100 ;
+  _Dhubble = SpeedOfLight_Cst / _H0;
+
+  _Omatter0 = om0;
+  _Orelat0 = or0;
+  _Olambda0 = ol0;
+  _W0 = w0;
+  _Otot0 = _Olambda0 + _Omatter0 + _Orelat0;
+  _Ocurv0 = 1. - _Otot0;
+  if( _h100<0. || _Omatter0<0. || _Orelat0<0. || _Olambda0<0. ) {
+    cout<<"CosmoCalc::SetDynParam: Error bad parameter value"<<endl;
+    throw ParmError("CosmoCalc::SetDynParam: Error bad parameter value");
+  }
+  if(_flat==0) return;
+
+  _Otot0 = 1.; _Ocurv0 = 0.;
+  if(_flat==1) {
+    _Omatter0 = _Otot0 - _Olambda0 - _Orelat0;
+    if( _Omatter0<0. ) {
+      cout<<"CosmoCalc::SetDynParam: Error bad _Omatter0 value: "<<_Omatter0<<endl;
+      throw ParmError("CosmoCalc::SetDynParam: Error bad _Omatter0 value");
+    }
+    return;
+  }
+
+  //--
+  if(_flat==2) {
+    _Olambda0 = _Otot0 - _Omatter0 - _Orelat0;
+    if( _Olambda0<0. ) {
+      cout<<"CosmoCalc::SetDynParam: Error bad _Olambda0 value: "<<_Olambda0<<endl;
+      throw ParmError("CosmoCalc::SetDynParam: Error bad _Olambda0 value");
+    }
+    return;
+  }
+
+  //--
+  if(_flat==3) {
+    _Orelat0 = _Otot0 - _Omatter0 - _Olambda0;
+    if( _Orelat0<0. ) {
+      cout<<"CosmoCalc::SetDynParam: Error bad _Orelat0 value: "<<_Orelat0<<endl;
+      throw ParmError("CosmoCalc::SetDynParam: Error bad _Orelat0 value");
+    }
+    return;
+  }
+
+  cout<<"CosmoCalc::SetDynParam: Error bad _flat value: "<<_flat<<endl;
+  throw ParmError("CosmoCalc::SetDynParam: Error bad _flat value");
+
+}
+
+void CosmoCalc::DefaultParam(void)
+{
+  _computespl=true;
+
+  double h100 = 0.71;
+  double ol0 = 0.73, w0 = -1.;
+  double om0 = 0.135/(h100*h100);
+  // Relat = photons (2.725 K) + neutrinos (1.9 K)
+  double or0 = 2.47e-5 * (1. + 21./8.*pow(T_NU_Par/T_CMB_Par,4.)) / (h100*h100);
+  SetDynParam(h100,om0,or0,ol0,w0);
+  _Obaryon0 = 0.0224/(h100*h100);
+
+  return;
+}
+
+//----------------------------------------------------------
+void CosmoCalc::Print(double z)
+{
+  if(z<0.) z = 0.;
+
+  printf("CosmoCalc::Print(spl=%d,zmax=%g,flat=%u)  for z=%g\n",int(_usespline),ZMax(),Flat(),z);
+  printf("h100=%g H0=%g Dhub=%g  H(z)=%g  Rhoc=%g g/cm^3 =%g Msol/Mpc^3\n"
+        ,h100(),H0(),Dhubble(),H(z),Rhoc(z),Rhoc(z)*GCm3toMsolMpc3_Cst);
+  printf("Olambda=%g  W0=%g\n",Olambda(z),_W0);
+  printf("Omatter=%g  Obaryon=%g\n",Omatter(z),Obaryon(z));
+  printf("Orelat=%g\n",Orelat(z));
+  printf("Otot=%g  Ocurv=%g\n",Otot(z),Ocurv(z));
+  if(z <= 0.) return;
+  printf("Distance comoving: los=%g Mpc, transv=%g Mpc\n",Dloscom(z),Dtrcom(z));
+  printf("Distance: angular=%g Mpc, lum=%g Mpc\n",Dang(z),Dlum(z));
+  printf("Volume comoving element: %g Mpc^3/sr/dz=1\n",dVol(z));
+  printf("Volume comoving in [0,z] for 4Pi sr: %g Mpc^3\n",Vol4Pi(z));
+
+}
+//----------------------------------------------------------
+double CosmoCalc::Olambda(double z)
+{
+  double v = _Olambda0;
+  if(_W0 != -1.) v *= pow((1.+z),3.*(1+_W0));
+  return v / E2(z);
+}
+
+double CosmoCalc::Omatter(double z)
+{
+  return _Omatter0 * (1.+z)*(1.+z)*(1.+z) /E2(z);
+}
+
+double CosmoCalc::Obaryon(double z)
+{
+  return _Obaryon0 * (1.+z)*(1.+z)*(1.+z) /E2(z);
+}
+
+double CosmoCalc::Orelat(double z)
+{
+  double z2 = (1.+z)*(1.+z);
+  return _Orelat0 * z2*z2 /E2(z);
+}
+
+double CosmoCalc::Ocurv(double z)
+{
+  return _Ocurv0 * (1.+z)*(1.+z) /E2(z);
+}
+
+double CosmoCalc::Otot(double z)
+{
+  return Olambda(z)+Omatter(z)+Orelat(z);
+}
+
+double CosmoCalc::Rhoc(double z)
+// Densite critique au redshift "z"  en "g/cm^3"
+{
+  double h2 = H(z) / MpctoMeters_Cst;  h2 *= h2;
+  return 3.* h2 / (8.*M_PI*G_Newton_Cst) * 1000.;
+}
+
+//----------------------------------------------------------
+double CosmoCalc::Dloscom(double z)     /* Mpc comobile */
+{
+  return _Dhubble * NInteg(z);
+}
+
+double CosmoCalc::Dtrcom(double z)     /* Mpc comobile */
+{
+  double v = NInteg(z);  // Zero curvature
+
+  if(_flat) return _Dhubble * v;
+
+  if(_Ocurv0>0.) {  // hyperbolique
+    double s = sqrt(_Ocurv0);
+    v = sinh(s*v)/s;
+  } else if(_Ocurv0<0.) {  // spherique
+    double s = sqrt(-_Ocurv0);
+    v = sin(s*v)/s;
+  }
+
+  return _Dhubble * v;
+
+}
+
+double CosmoCalc::Dang(double z)     /* Mpc */
+{
+  return Dtrcom(z) / (1.+z);
+}
+
+double CosmoCalc::Dlum(double z)     /* Mpc */
+{
+  return (1.+z) * Dtrcom(z);
+}
+
+double CosmoCalc::dVol(double z)     /* Mpc^3/ sr / unite z */
+{
+  double d = Dtrcom(z);
+  return _Dhubble * d*d / E(z);
+}
+
+//----------------------------------------------------------
+double CosmoCalc::Vol4Pi(double z)  /* Mpc^3 pour 4Pi sr entre [0,z] */
+  // --- on pose x = dm/dh = (1+z)*da/dh, s = sqrt(|Ok|)
+  // Ok=0 : V(z)/dh^3 = (4*Pi/3) * x^3
+  // Ok>0 : V(z)/dh^3 = (4*Pi/(2*Ok)) * (x*sqrt(1+Ok*x^2) - 1/s * asinh(s*x))
+  // Ok<0 : V(z)/dh^3 = (4*Pi/(2*Ok)) * (x*sqrt(1+Ok*x^2) - 1/s * asin(s*x) )
+  // --- on pose y = s*x  (y>0)
+  // Ok>0 : V(z)/dh^3 = (4*Pi/(2*Ok*s)) * (y*sqrt(1+y^2) - asinh(y))
+  // Ok<0 : V(z)/dh^3 = (4*Pi/(2*Ok*s)) * (y*sqrt(1-y^2) - asin(y) )
+  // --- a petit "z" on a pour "y -> 0+" en faisant le DL
+  // Ok>0 : V(z)/dh^3 =  4*Pi*y^3 / (3*Ok*s) * (1 - 3*y^2/10) + O(y^7)
+  // Ok<0 : V(z)/dh^3 = -4*Pi*y^3 / (3*Ok*s) * (1 + 3*y^2/10) + O(y^7)
+  //                          (remarque: Ok^(3/2) = s*Ok)
+{
+  double v,x = Dtrcom(z)/_Dhubble;
+
+  if(_flat) {
+    v = 4.*M_PI/3. * x*x*x;
+  } else if(_Ocurv0>0.) {
+    double s = sqrt(_Ocurv0), y = s*x, y2 = y*y;
+    if(y<1e-6) {
+      v = 1. - 3.*y2/10.;
+      v *= 4.*M_PI*y*y2 / (3.*_Ocurv0*s);
+    } else {
+      v = y*sqrt(1.+y2) - asinh(y);
+      v *= 4.*M_PI/(2.*_Ocurv0*s);
+    }
+  } else if (_Ocurv0<0.) {
+    double s = sqrt(-_Ocurv0), y = s*x, y2 = y*y;
+    if(y<1e-6) {
+      v = 1. + 3.*y2/10.;
+      v *= -4.*M_PI*y*y2 / (3.*_Ocurv0*s);
+    } else {
+      v = y*sqrt(1.-y2) - asin(y);
+      v *= 4.*M_PI/(2.*_Ocurv0*s);
+    }
+  } else {
+    v = 4.*M_PI/3. * x*x*x;
+  }
+
+  return v * _Dhubble*_Dhubble*_Dhubble;
+}
+
+double CosmoCalc::Vol4Pi(double z1,double z2)  /* Mpc^3 pour 4Pi sr entre [z1,z2] */
+{
+  return Vol4Pi(z2) - Vol4Pi(z1);
+}
+
+double CosmoCalc::E2(double z) const
+{
+  z += 1.;
+  double oldum = _Olambda0;
+
+  if(oldum>0. && _W0!=-1.) oldum *= pow(z,3.*(1.+_W0));
+
+  return oldum + z*z*(_Ocurv0 + z*(_Omatter0+z*_Orelat0));
+}
+
+//----------------------------------------------------------
+double CosmoCalc::NInteg(double z)
+{
+  if(z<0.) {
+    cout<<"CosmoCalc::NInteg: Error bad z value  z="<<z<<endl;
+    throw ParmError("CosmoCalc::NInteg: Error bad z value");
+  }
+
+  // On utilise le spline
+  if(_usespline) {
+    if( (!_computespl) && (z==_zold) ) return _integval;
+    if(z>_zmax) {_zmax = z+_dzmax; _computespl = true;}
+    if(_computespl) Init_Spline();
+    _integval = _spline->CSplineInt(z);
+    _zold = z;
+    return _integval;
+  }
+
+  // On calcule l'integrale
+  if(z != _zold) {
+    _integval = IntegrateFunc(*this,0.,z,_dperc,_dzinc,_dzmax,_glorder);
+    _zold = z;
+  }
+  return _integval;
+
+}
+
+int_4 CosmoCalc::Init_Spline(void)
+{
+  if(_spline!=NULL)
+    {delete _spline; delete [] _xspl; delete [] _yspl;}
+
+  //-- Look for intervalles and integrate
+  vector<double> x,y;
+  x.push_back(0.); y.push_back(0.);
+  double zbas=0., fbas = Integrand(zbas);
+  for(double z=_dzinc;;z+=_dzinc) {
+    double f = Integrand(z);
+    //cout<<fbas<<","<<f<<"  :  "<<fabs(f-fbas)<<" >? "<<_dperc*fabs(fbas)<<endl;
+    if( z>_zmax || z-zbas>_dzmax || fabs(f-fbas)>_dperc*fabs(fbas) ) {
+      double sum=0.,  dz=z-zbas;
+      for(unsigned short i=0;i<_glorder;i++) sum += _wgausl[i]*Integrand(zbas+_xgausl[i]*dz);
+      x.push_back(z); y.push_back(sum*dz);
+      //cout<<"...set... "<<zbas<<","<<z<<"  ,  "<<fbas<<","<<f<<endl;
+      zbas = z;  fbas = f;
+      if( z>_zmax ) break;
+    }
+  }
+
+  //-- Protection car il faut au moins 4 points pour un spline cubique
+  if(x.size()<4) {
+    x.resize(0); y.resize(0);
+    x.push_back(0.); y.push_back(0.);
+    for(int i=1;i<4;i++) {
+      x.push_back(i*_zmax/3.);
+      double sum=0., dz=x[i]-x[i-1];
+      for(unsigned short i=0;i<_glorder;i++) sum += _wgausl[i]*Integrand(x[i-1]+_xgausl[i]*dz);
+      y.push_back(sum*dz);
+    }
+  }
+
+  //-- Fill spline
+  _nspl = x.size();
+  _xspl = new double[_nspl];
+  _yspl = new double[_nspl];
+  for(int i=0;i<_nspl;i++) {
+    _xspl[i] = x[i];
+    _yspl[i] = y[i];
+    if(i!=0) _yspl[i] += _yspl[i-1];
+  }
+
+#if 1
+  cout<<"CosmoCalc::Init_Spline called: (zmax="<<_zmax<<") _nspl="<<_nspl<<endl;
+  int n = (_nspl>5)? 5: _nspl;
+  cout<<_nspl<<"...";
+  for(int i=0;i<n;i++) cout<<_xspl[i]<<" ("<<_yspl[i]<<") ";
+  cout<<"\n... ";
+  n = (_nspl<5)? 0: _nspl-5;
+  for(int i=n;i<_nspl;i++) cout<<_xspl[i]<<" ("<<_yspl[i]<<") ";
+  cout<<endl;
+#endif
+
+  double yp1 = Integrand(_xspl[0]);
+  double ypn = Integrand(_xspl[_nspl-1]);
+  _spline = new CSpline(_nspl,_xspl,_yspl,yp1,ypn,CSpline::NoNatural,false);
+  _spline->ComputeCSpline();
+  _computespl = false;
+
+  return _nspl;
+}
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/cosmocalc.h	(revision 3445)
@@ -0,0 +1,100 @@
+#ifndef COSMOCALC_SEEN
+#define COSMOCALC_SEEN
+
+#include "machdefs.h"
+#include <vector>
+
+#include "genericfunc.h"
+
+namespace SOPHYA {
+
+  class CSpline;
+
+//-----------------------------------------------------------------------------------
+class CosmoCalc : public GenericFunc {
+public:
+  CosmoCalc(unsigned short flat=0,bool usespline=false,double zmax=0.);
+  CosmoCalc(CosmoCalc& univ);
+  virtual ~CosmoCalc(void);
+
+  unsigned short Flat(void) { return _flat;}
+
+  double ZMax(void) { return _zmax;}
+  void SetInteg(double dperc=-1.,double dzinc=-1.,double dzmax=-1.,unsigned short order=4);
+  void PrtInteg(void);
+
+  void SetDynParam(double h100,double om0,double or0,double ol0,double w0=-1.);
+  void SetObaryon0(double v);
+  void DefaultParam(void);
+
+  inline double h100(void) {return _h100;}
+  inline double H0(void) {return _H0;}
+  inline double Dhubble(void) {return _Dhubble;}
+  inline double Olambda0(void) {return _Olambda0;}
+  inline double W0(void) {return _W0;}
+  inline double Omatter0(void) {return _Omatter0;}
+  inline double Obaryon0(void) {return _Obaryon0;}
+  inline double Orelat0(void) {return _Orelat0;}
+  inline double Ocurv0(void) {return _Ocurv0;}
+  inline double Otot0(void) {return _Otot0;}
+  double Rhoc(double z);
+
+  inline double H(double z) {return _H0 * E(z);}
+  double Olambda(double z);
+  double Omatter(double z);
+  double Obaryon(double z);
+  double Orelat(double z);
+  double Ocurv(double z);
+  double Otot(double z);
+
+  double Dtrcom(double z);
+  double Dloscom(double z);
+  double Dang(double z);
+  double Dlum(double z);
+
+  double dVol(double z);
+  double Vol4Pi(double z);
+  double Vol4Pi(double z1,double z2);
+
+  void Print(double z=0.);
+
+  double E2(double z) const;
+  inline double E(double z) const {return sqrt(E2(z));}
+
+  double NInteg(double z);
+  inline double Integrand(double z) const {return 1./E(z);}
+
+  virtual double operator() (double z) {return Integrand(z);}
+protected:
+  int_4 Init_Spline(void);
+  void Clone(CosmoCalc& univ);
+
+  // La cosmology
+  unsigned short _flat;
+  double _h100, _H0;  /* km/s/Mpc */
+  double _Olambda0,_W0;
+  double _Omatter0,_Obaryon0;
+  double _Orelat0;
+  double _Otot0,_Ocurv0;
+  double _Dhubble;  /* Mpc */
+
+  // Parametres d'integration
+  double _dperc,_dzinc,_dzmax;
+  unsigned short _glorder;
+  vector<double> _xgausl, _wgausl;
+
+  // Pour le calcul direct
+  double _zold,_integval;
+
+  // Pour les splines
+  bool _usespline,_computespl;
+  double _zmax;
+  CSpline * _spline;
+  int_4 _nspl;
+  double *_xspl, *_yspl;
+
+};
+
+} // Fin du namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.cc	(revision 3445)
@@ -0,0 +1,1516 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "tarray.h"
+#include "pexceptions.h"
+#include "perandom.h"
+#include "srandgen.h"
+
+#include "fabtcolread.h"
+#include "fabtwriter.h"
+#include "fioarr.h"
+
+#include "arrctcast.h"
+
+#include "constcosmo.h"
+#include "geneutils.h"
+#include "schechter.h"
+
+#include "genefluct3d.h"
+
+#define WITH_FFTW_THREAD
+
+#define MODULE2(_x_) ((double)((_x_).real()*(_x_).real() + (_x_).imag()*(_x_).imag()))
+
+namespace SOPHYA {
+
+//-------------------------------------------------------
+GeneFluct3D::GeneFluct3D(long nx,long ny,long nz,double dx,double dy,double dz
+                        ,unsigned short nthread,int lp)
+{
+ init_default();
+
+ lp_ = lp;
+ nthread_ = nthread;
+
+ setsize(nx,ny,nz,dx,dy,dz);
+ setalloc();
+ setpointers(false);
+ init_fftw();
+}
+
+GeneFluct3D::GeneFluct3D(unsigned short nthread)
+{
+ init_default();
+ setsize(2,2,2,1.,1.,1.);
+ nthread_ = nthread;
+ setalloc();
+ setpointers(false);
+ init_fftw();
+}
+
+GeneFluct3D::~GeneFluct3D(void)
+{
+ delete_fftw();
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::init_default(void)
+{
+ Nx_ = Ny_ = Nz_ = 0;
+ is_set_fftw_plan = false;
+ nthread_ = 0;
+ lp_ = 0;
+ array_allocated_ = false;
+ cosmo_ = NULL;
+ growth_ = NULL;
+ redsh_ref_ = -999.;
+ kredsh_ref_ = 0.;
+ dred_ref_ = -999.;
+ loscom_ref_ = -999.;
+ dtrc_ref_ = dlum_ref_ = dang_ref_ = -999.;
+ nu_ref_ = dnu_ref_ = -999.;
+ loscom_min_ = loscom_max_ = -999.;
+ loscom2zred_min_ = loscom2zred_max_ = 0.;
+ xobs_[0] = xobs_[1] = xobs_[2] = 0.;
+ zred_.resize(0);
+ loscom_.resize(0);
+ loscom2zred_.resize(0);
+}
+
+void GeneFluct3D::setsize(long nx,long ny,long nz,double dx,double dy,double dz)
+{
+ if(lp_>1) cout<<"--- GeneFluct3D::setsize: N="<<nx<<","<<ny<<","<<nz
+                <<" D="<<dx<<","<<dy<<","<<dz<<endl;
+ if(nx<=0 || dx<=0.) {
+   char *bla = "GeneFluct3D::setsize_Error: bad value(s) for nn/dx";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+
+ // Les tailles des tableaux
+ Nx_ = nx;
+ Ny_ = ny;  if(Ny_ <= 0) Ny_ = Nx_;
+ Nz_ = nz;  if(Nz_ <= 0) Nz_ = Nx_;
+ N_.resize(0); N_.push_back(Nx_); N_.push_back(Ny_); N_.push_back(Nz_);
+ NRtot_ = Nx_*Ny_*Nz_; // nombre de pixels dans le survey
+ NCz_ =  Nz_/2 +1;
+ NTz_ = 2*NCz_;
+
+ // le pas dans l'espace (Mpc)
+ Dx_ = dx;
+ Dy_ = dy; if(Dy_ <= 0.) Dy_ = Dx_;
+ Dz_ = dz; if(Dz_ <= 0.) Dz_ = Dx_;
+ D_.resize(0); D_.push_back(Dx_); D_.push_back(Dy_); D_.push_back(Dz_);
+ dVol_ = Dx_*Dy_*Dz_;
+ Vol_ = (Nx_*Dx_)*(Ny_*Dy_)*(Nz_*Dz_);
+
+ // Le pas dans l'espace de Fourier (Mpc^-1)
+ Dkx_ = 2.*M_PI/(Nx_*Dx_);
+ Dky_ = 2.*M_PI/(Ny_*Dy_);
+ Dkz_ = 2.*M_PI/(Nz_*Dz_);
+ Dk_.resize(0); Dk_.push_back(Dkx_); Dk_.push_back(Dky_); Dk_.push_back(Dkz_);
+ Dk3_ = Dkx_*Dky_*Dkz_;
+ 
+ // La frequence de Nyquist en k (Mpc^-1)
+ Knyqx_ = M_PI/Dx_;
+ Knyqy_ = M_PI/Dy_;
+ Knyqz_ = M_PI/Dz_;
+ Knyq_.resize(0); Knyq_.push_back(Knyqx_); Knyq_.push_back(Knyqy_); Knyq_.push_back(Knyqz_);
+}
+
+void GeneFluct3D::setalloc(void)
+{
+ if(lp_>1) cout<<"--- GeneFluct3D::setalloc ---"<<endl;
+ // Dimensionnement du tableau complex<r_8>
+ // ATTENTION: TArray adresse en memoire a l'envers du C
+ //            Tarray(n1,n2,n3) == Carray[n3][n2][n1]
+ sa_size_t SzK_[3] = {NCz_,Ny_,Nx_}; // a l'envers
+ try {
+   T_.ReSize(3,SzK_);
+   array_allocated_ = true;
+   if(lp_>1) cout<<"  allocating: "<<T_.Size()*sizeof(complex<r_8>)/1.e6<<" Mo"<<endl;
+ } catch (...) {
+   cout<<"GeneFluct3D::setalloc_Error: Problem allocating T_"<<endl;
+ }
+ T_.SetMemoryMapping(BaseArray::CMemoryMapping);
+}
+
+void GeneFluct3D::setpointers(bool from_real)
+{
+ if(lp_>1) cout<<"--- GeneFluct3D::setpointers ---"<<endl;
+ if(from_real) T_ = ArrCastR2C(R_);
+   else        R_ = ArrCastC2R(T_);
+ // On remplit les pointeurs
+ fdata_ = (fftw_complex *) (&T_(0,0,0));
+ data_ = (double *) (&R_(0,0,0));
+}
+
+void GeneFluct3D::init_fftw(void)
+{
+ if( is_set_fftw_plan ) delete_fftw();
+
+ // --- Initialisation de fftw3 (attention data est sur-ecrit a l'init)
+ if(lp_>1) cout<<"--- GeneFluct3D::init_fftw ---"<<endl;
+#ifdef WITH_FFTW_THREAD
+ if(nthread_>0) {
+   cout<<"...Computing with "<<nthread_<<" threads"<<endl;
+   fftw_init_threads();
+   fftw_plan_with_nthreads(nthread_);
+ }
+#endif
+ if(lp_>1) cout<<"...forward plan"<<endl;
+ pf_ = fftw_plan_dft_r2c_3d(Nx_,Ny_,Nz_,data_,fdata_,FFTW_ESTIMATE);
+ if(lp_>1) cout<<"...backward plan"<<endl;
+ pb_ = fftw_plan_dft_c2r_3d(Nx_,Ny_,Nz_,fdata_,data_,FFTW_ESTIMATE);
+ is_set_fftw_plan = true;
+}
+
+void GeneFluct3D::delete_fftw(void)
+{
+ if( !is_set_fftw_plan ) return;
+ fftw_destroy_plan(pf_);
+ fftw_destroy_plan(pb_);
+#ifdef WITH_FFTW_THREAD
+ if(nthread_>0) fftw_cleanup_threads();
+#endif
+ is_set_fftw_plan = false;
+}
+
+void GeneFluct3D::check_array_alloc(void)
+// Pour tester si le tableau T_ est alloue
+{
+ if(array_allocated_) return;
+ char bla[90];
+ sprintf(bla,"GeneFluct3D::check_array_alloc_Error: array is not allocated");
+ cout<<bla<<endl; throw ParmError(bla);
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::SetObservator(double redshref,double kredshref)
+// L'observateur est au redshift z=0
+//               est situe sur la "perpendiculaire" a la face x,y
+//                         issue du centre de cette face
+// Il faut positionner le cube sur l'axe des z cad des redshifts:
+//     redshref  = redshift de reference
+//                 Si redshref<0 alors redshref=0
+//     kredshref = indice (en double) correspondant a ce redshift
+//                 Si kredshref<0 alors kredshref=nz/2 (milieu du cube)
+// Exemple: redshref=1.5 kredshref=250.75
+//    -> Le pixel i=nx/2 j=ny/2 k=250.75 est au redshift 1.5
+{
+ if(redshref<0.) redshref = 0.;
+ if(kredshref<0.) {
+   if(Nz_<=0) {
+     char *bla = "GeneFluct3D::SetObservator_Error: for kredsh_ref<0 define cube geometry first";
+     cout<<bla<<endl; throw ParmError(bla);
+   }
+   kredshref = Nz_/2.;
+ }
+ redsh_ref_  = redshref;
+ kredsh_ref_ = kredshref;
+ if(lp_>0)
+   cout<<"--- GeneFluct3D::SetObservator zref="<<redsh_ref_<<" kref="<<kredsh_ref_<<endl;
+}
+
+void GeneFluct3D::SetCosmology(CosmoCalc& cosmo)
+{
+ cosmo_ = &cosmo;
+ if(lp_>1) cosmo_->Print();
+}
+
+void GeneFluct3D::SetGrowthFactor(GrowthFactor& growth)
+{
+ growth_ = &growth;
+}
+
+long GeneFluct3D::LosComRedshift(double zinc,long npoints)
+// Given a position of the cube relative to the observer
+// and a cosmology
+// (SetObservator() and SetCosmology() should have been called !)
+// This routine filled:
+//   the vector "zred_" of scanned redshift (by zinc increments)
+//   the vector "loscom_" of corresponding los comoving distance
+// -- Input:
+// zinc : redshift increment for computation
+// npoints : number of points required for inverting loscom -> zred
+// 
+{
+ if(lp_>0) cout<<"--- LosComRedshift: zinc="<<zinc<<" , npoints="<<npoints<<endl;
+
+ if(cosmo_ == NULL || redsh_ref_<0.) {
+   char *bla = "GeneFluct3D::LosComRedshift_Error: set Observator and Cosmology first";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+
+ // La distance angulaire/luminosite/Dnu au pixel de reference
+ dred_ref_ = Dz_/(cosmo_->Dhubble()/cosmo_->E(redsh_ref_));
+ loscom_ref_ = cosmo_->Dloscom(redsh_ref_);
+ dtrc_ref_ = cosmo_->Dtrcom(redsh_ref_);
+ dlum_ref_ = cosmo_->Dlum(redsh_ref_);
+ dang_ref_ = cosmo_->Dang(redsh_ref_);
+ nu_ref_   = Fr_HyperFin_Par/(1.+redsh_ref_); // GHz
+ dnu_ref_  = Fr_HyperFin_Par *dred_ref_/pow(1.+redsh_ref_,2.); // GHz
+ if(lp_>0) {
+   cout<<"...reference pixel redshref="<<redsh_ref_
+       <<", dredref="<<dred_ref_
+       <<", nuref="<<nu_ref_ <<" GHz"
+       <<", dnuref="<<dnu_ref_ <<" GHz"<<endl
+       <<"   dlosc="<<loscom_ref_<<" Mpc com"
+       <<", dtrc="<<dtrc_ref_<<" Mpc com"
+       <<", dlum="<<dlum_ref_<<" Mpc"
+       <<", dang="<<dang_ref_<<" Mpc"<<endl;
+ }
+
+ // On calcule les coordonnees de l'observateur dans le repere du cube
+ // cad dans le repere ou l'origine est au centre du pixel i=j=l=0.
+ // L'observateur est sur un axe centre sur le milieu de la face Oxy
+ xobs_[0] = Nx_/2.*Dx_;
+ xobs_[1] = Ny_/2.*Dy_;
+ xobs_[2] = kredsh_ref_*Dz_ - loscom_ref_;
+
+ // L'observateur est-il dans le cube?
+ bool obs_in_cube = false;
+ if(xobs_[2]>=0. && xobs_[2]<=Nz_*Dz_) obs_in_cube = true;
+
+ // Find MINIMUM los com distance to the observer:
+ // c'est le centre de la face a k=0
+ // (ou zero si l'observateur est dans le cube)
+ loscom_min_ = 0.;
+ if(!obs_in_cube) loscom_min_ = -xobs_[2];
+
+ // TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED
+ if(loscom_min_<=1.e-50)
+   for(int i=0;i<50;i++)
+     cout<<"ATTENTION TOUTES LES PARTIES DU CODE NE MARCHENT PAS POUR UN OBSERVATEUR DANS LE CUBE"<<endl;
+ // TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED TO BE FIXED
+
+
+ // Find MAXIMUM los com distance to the observer:
+ // ou que soit positionne l'observateur, la distance
+ // maximal est sur un des coins du cube
+ loscom_max_ = 0.;
+ for(long i=0;i<=1;i++) {
+   double dx2 = DXcom(i*(Nx_-1)); dx2 *= dx2;
+   for(long j=0;j<=1;j++) {
+     double dy2 = DYcom(j*(Ny_-1)); dy2 *= dy2;
+     for(long k=0;k<=1;k++) {
+       double dz2 = DZcom(k*(Nz_-1)); dz2 *= dz2;
+       dz2 = sqrt(dx2+dy2+dz2);
+       if(dz2>loscom_max_) loscom_max_ = dz2;
+     }
+   }
+ }
+ if(lp_>0) {
+   cout<<"...zref="<<redsh_ref_<<" kzref="<<kredsh_ref_<<" losref="<<loscom_ref_<<" Mpc\n"
+       <<"   xobs="<<xobs_[0]<<" , "<<xobs_[1]<<" , "<<xobs_[2]<<" Mpc "
+       <<" in_cube="<<obs_in_cube
+       <<" loscom_min="<<loscom_min_<<" loscom_max="<<loscom_max_<<" Mpc (com)"<<endl;
+ }
+
+ // Fill the corresponding vectors for loscom and zred
+ // Be shure to have one dlc <loscom_min and one >loscom_max
+ if(zinc<=0.) zinc = 0.01;
+ for(double z=0.; ; z+=zinc) {
+   double dlc = cosmo_->Dloscom(z);
+   if(dlc<loscom_min_) {zred_.resize(0); loscom_.resize(0);}
+   zred_.push_back(z);
+   loscom_.push_back(dlc);
+   z += zinc;
+   if(dlc>loscom_max_) break; // on sort apres avoir stoque un dlc>dlcmax
+ }
+
+ if(lp_>0) {
+   long n = zred_.size();
+   cout<<"...zred/loscom tables[zinc="<<zinc<<"]: n="<<n;
+   if(n>0) cout<<" z="<<zred_[0]<<" -> d="<<loscom_[0];
+   if(n>1) cout<<" , z="<<zred_[n-1]<<" -> d="<<loscom_[n-1];
+   cout<<endl;
+ }
+
+ // Compute the parameters and tables needed for inversion loscom->zred
+ if(npoints<3) npoints = zred_.size();
+ InverseFunc invfun(zred_,loscom_);
+ invfun.ComputeParab(npoints,loscom2zred_);
+ loscom2zred_min_ = invfun.YMin();
+ loscom2zred_max_ = invfun.YMax();
+
+ if(lp_>0) {
+   long n = loscom2zred_.size();
+   cout<<"...loscom -> zred[npoints="<<npoints<<"]: n="<<n
+       <<" los_min="<<loscom2zred_min_
+       <<" los_max="<<loscom2zred_max_
+       <<" -> zred=[";
+   if(n>0) cout<<loscom2zred_[0];
+   cout<<",";
+   if(n>1) cout<<loscom2zred_[n-1];
+   cout<<"]"<<endl;
+   if(lp_>1 && n>0)
+     for(int i=0;i<n;i++)
+       if(i<2 || abs(i-n/2)<2 || i>=n-2)
+         cout<<"    i="<<i
+             <<"  d="<<loscom2zred_min_+i*(loscom2zred_max_-loscom2zred_min_)/(n-1.)
+             <<" Mpc   z="<<loscom2zred_[i]<<endl;
+ }
+
+ return zred_.size();
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::WriteFits(string cfname,int bitpix)
+{
+ cout<<"--- GeneFluct3D::WriteFits: Writing Cube to "<<cfname<<endl;
+ try {
+   FitsImg3DWriter fwrt(cfname.c_str(),bitpix,5);
+   fwrt.WriteKey("NX",Nx_," axe transverse 1");
+   fwrt.WriteKey("NY",Ny_," axe transverse 2");
+   fwrt.WriteKey("NZ",Nz_," axe longitudinal (redshift)");
+   fwrt.WriteKey("DX",Dx_," Mpc");
+   fwrt.WriteKey("DY",Dy_," Mpc");
+   fwrt.WriteKey("DZ",Dz_," Mpc");
+   fwrt.WriteKey("DKX",Dkx_," Mpc^-1");
+   fwrt.WriteKey("DKY",Dky_," Mpc^-1");
+   fwrt.WriteKey("DKZ",Dkz_," Mpc^-1");
+   fwrt.WriteKey("ZREF",redsh_ref_," reference redshift");
+   fwrt.WriteKey("KZREF",kredsh_ref_," reference redshift on z axe");
+   fwrt.Write(R_);
+ } catch (PThrowable & exc) {
+   cout<<"Exception : "<<(string)typeid(exc).name()
+       <<" - Msg= "<<exc.Msg()<<endl;
+   return;
+ } catch (...) {
+   cout<<" some other exception was caught !"<<endl;
+   return;
+ }
+}
+
+void GeneFluct3D::ReadFits(string cfname)
+{
+ cout<<"--- GeneFluct3D::ReadFits: Reading Cube from "<<cfname<<endl;
+ try {
+   FitsImg3DRead fimg(cfname.c_str(),0,5);
+   fimg.Read(R_);
+   long nx = fimg.ReadKeyL("NX");
+   long ny = fimg.ReadKeyL("NY");
+   long nz = fimg.ReadKeyL("NZ");
+   double dx = fimg.ReadKey("DX");
+   double dy = fimg.ReadKey("DY");
+   double dz = fimg.ReadKey("DZ");
+   double zref = fimg.ReadKey("ZREF");
+   double kzref = fimg.ReadKey("KZREF");
+   setsize(nx,ny,nz,dx,dy,dz);
+   setpointers(true);
+   init_fftw();
+   SetObservator(zref,kzref);
+   array_allocated_ = true;
+ } catch (PThrowable & exc) {
+   cout<<"Exception : "<<(string)typeid(exc).name()
+       <<" - Msg= "<<exc.Msg()<<endl;
+   return;
+ } catch (...) {
+   cout<<" some other exception was caught !"<<endl;
+   return;
+ }
+}
+
+void GeneFluct3D::WritePPF(string cfname,bool write_real)
+// On ecrit soit le TArray<r_8> ou le TArray<complex <r_8> >
+{
+ cout<<"--- GeneFluct3D::WritePPF: Writing Cube (real="<<write_real<<") to "<<cfname<<endl;
+ try {
+   R_.Info()["NX"] = (int_8)Nx_;
+   R_.Info()["NY"] = (int_8)Ny_;
+   R_.Info()["NZ"] = (int_8)Nz_;
+   R_.Info()["DX"] = (r_8)Dx_;
+   R_.Info()["DY"] = (r_8)Dy_;
+   R_.Info()["DZ"] = (r_8)Dz_;
+   R_.Info()["ZREF"] = (r_8)redsh_ref_;
+   R_.Info()["KZREF"] = (r_8)kredsh_ref_;
+   POutPersist pos(cfname.c_str());
+   if(write_real) pos << PPFNameTag("rgen")  << R_;
+     else         pos << PPFNameTag("pkgen") << T_;
+ } catch (PThrowable & exc) {
+   cout<<"Exception : "<<(string)typeid(exc).name()
+       <<" - Msg= "<<exc.Msg()<<endl;
+   return;
+ } catch (...) {
+   cout<<" some other exception was caught !"<<endl;
+   return;
+ }
+}
+
+void GeneFluct3D::ReadPPF(string cfname)
+{
+ cout<<"--- GeneFluct3D::ReadPPF: Reading Cube from "<<cfname<<endl;
+ try {
+   bool from_real = true;
+   PInPersist pis(cfname.c_str());
+   string name_tag_k = "pkgen";
+   bool found_tag_k = pis.GotoNameTag("pkgen");
+   if(found_tag_k) {
+     cout<<"           ...reading spectrum into TArray<complex <r_8> >"<<endl;
+     pis >> PPFNameTag("pkgen")  >> T_;
+     from_real = false;
+   } else {
+     cout<<"           ...reading space into TArray<r_8>"<<endl;
+     pis >> PPFNameTag("rgen")  >> R_;
+   }
+   setpointers(from_real);  // a mettre ici pour relire les DVInfo
+   int_8 nx = R_.Info()["NX"];
+   int_8 ny = R_.Info()["NY"];
+   int_8 nz = R_.Info()["NZ"];
+   r_8 dx = R_.Info()["DX"];
+   r_8 dy = R_.Info()["DY"];
+   r_8 dz = R_.Info()["DZ"];
+   r_8 zref = R_.Info()["ZREF"];
+   r_8 kzref = R_.Info()["KZREF"];
+   setsize(nx,ny,nz,dx,dy,dz);
+   init_fftw();
+   SetObservator(zref,kzref);
+   array_allocated_ = true;
+ } catch (PThrowable & exc) {
+   cout<<"Exception : "<<(string)typeid(exc).name()
+       <<" - Msg= "<<exc.Msg()<<endl;
+   return;
+ } catch (...) {
+   cout<<" some other exception was caught !"<<endl;
+   return;
+ }
+}
+
+void GeneFluct3D::WriteSlicePPF(string cfname)
+// On ecrit 3 tranches du cube selon chaque axe
+{
+ cout<<"--- GeneFluct3D::WriteSlicePPF: Writing Cube Slices "<<cfname<<endl;
+ try {
+
+   POutPersist pos(cfname.c_str());
+   TMatrix<r_4> S;
+   char str[16];
+   long i,j,l;
+
+   // Tranches en Z
+   for(int s=0;s<3;s++) {
+     S.ReSize(Nx_,Ny_);
+     if(s==0) l=0; else if(s==1) l=(Nz_+1)/2; else  l=Nz_-1;
+     sprintf(str,"z%ld",l);
+     for(i=0;i<Nx_;i++) for(j=0;j<Ny_;j++) S(i,j)=data_[IndexR(i,j,l)];
+     pos<<PPFNameTag(str)<<S; S.RenewObjId();
+   }
+
+   // Tranches en Y
+   for(int s=0;s<3;s++) {
+     S.ReSize(Nz_,Nx_);
+     if(s==0) j=0; else if(s==1) j=(Ny_+1)/2; else  j=Ny_-1;
+     sprintf(str,"y%ld",j);
+     for(i=0;i<Nx_;i++) for(l=0;l<Nz_;l++) S(l,i)=data_[IndexR(i,j,l)];
+     pos<<PPFNameTag(str)<<S; S.RenewObjId();
+   }
+
+   // Tranches en X
+   for(int s=0;s<3;s++) {
+     S.ReSize(Nz_,Ny_);
+     if(s==0) i=0; else if(s==1) i=(Nx_+1)/2; else  i=Nx_-1;
+     sprintf(str,"x%ld",i);
+     for(j=0;j<Ny_;j++) for(l=0;l<Nz_;l++) S(l,j)=data_[IndexR(i,j,l)];
+     pos<<PPFNameTag(str)<<S; S.RenewObjId();
+   }
+
+ } catch (PThrowable & exc) {
+   cout<<"Exception : "<<(string)typeid(exc).name()
+       <<" - Msg= "<<exc.Msg()<<endl;
+   return;
+ } catch (...) {
+   cout<<" some other exception was caught !"<<endl;
+   return;
+ }
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::Print(void)
+{
+ cout<<"GeneFluct3D(T_alloc="<<array_allocated_<<"):"<<endl;
+ cout<<"Space Size : nx="<<Nx_<<" ny="<<Ny_<<" nz="<<Nz_<<" ("<<NTz_<<")  size="
+     <<NRtot_<<endl;
+ cout<<"      Resol: dx="<<Dx_<<" dy="<<Dy_<<" dz="<<Dz_<<" Mpc"
+     <<", dVol="<<dVol_<<", Vol="<<Vol_<<" Mpc^3"<<endl;
+ cout<<"Fourier Size : nx="<<Nx_<<" ny="<<Ny_<<" nz="<<NCz_<<endl;
+ cout<<"        Resol: dkx="<<Dkx_<<" dky="<<Dky_<<" dkz="<<Dkz_<<" Mpc^-1"
+     <<", Dk3="<<Dk3_<<" Mpc^-3"<<endl;
+ cout<<"          (2Pi/k: "<<2.*M_PI/Dkx_<<" "<<2.*M_PI/Dky_<<" "<<2.*M_PI/Dkz_<<" Mpc)"<<endl;
+ cout<<"      Nyquist: kx="<<Knyqx_<<" ky="<<Knyqy_<<" kz="<<Knyqz_<<" Mpc^-1"
+     <<", Kmax="<<GetKmax()<<" Mpc^-1"<<endl;
+ cout<<"          (2Pi/k: "<<2.*M_PI/Knyqx_<<" "<<2.*M_PI/Knyqy_<<" "<<2.*M_PI/Knyqz_<<" Mpc)"<<endl;
+ cout<<"Redshift "<<redsh_ref_<<" for z axe at k="<<kredsh_ref_<<endl;
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::ComputeFourier0(GenericFunc& pk_at_z)
+// cf ComputeFourier() mais avec autre methode de realisation du spectre
+//    (attention on fait une fft pour realiser le spectre)
+{
+
+ // --- realisation d'un tableau de tirage gaussiens
+ if(lp_>0) cout<<"--- ComputeFourier0: before gaussian filling ---"<<endl;
+ // On tient compte du pb de normalisation de FFTW3
+ double sntot = sqrt((double)NRtot_);
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   data_[ip] = NorRand()/sntot;
+ }
+
+ // --- realisation d'un tableau de tirage gaussiens
+ if(lp_>0) cout<<"...before fft real ---"<<endl;
+ fftw_execute(pf_);
+
+ // --- On remplit avec une realisation
+ if(lp_>0) cout<<"...before Fourier realization filling"<<endl;
+ T_(0,0,0) = complex<r_8>(0.);  // on coupe le continue et on l'initialise
+ long lmod = Nx_/10; if(lmod<1) lmod=1;
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;  kx *= kx;
+   if(lp_>0 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;  ky *= ky;
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;  kz *= kz;
+       if(i==0 && j==0 && l==0) continue; // Suppression du continu
+       double k = sqrt(kx+ky+kz);
+       // cf normalisation: Peacock, Cosmology, formule 16.38 p504
+       double pk = pk_at_z(k)/Vol_;
+       // ici pas de "/2" a cause de la remarque ci-dessus
+       T_(l,j,i) *= sqrt(pk);
+     }
+   }
+ }
+
+ if(lp_>0) cout<<"...computing power"<<endl;
+ double p = compute_power_carte();
+ if(lp_>0) cout<<"Puissance dans la realisation: "<<p<<endl;
+
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::ComputeFourier(GenericFunc& pk_at_z)
+// Calcule une realisation du spectre "pk_at_z"
+// Attention: dans TArray le premier indice varie le + vite
+// Explication normalisation: see Coles & Lucchin, Cosmology, p264-265
+// FFTW3: on note N=Nx*Ny*Nz
+// f  --(FFT)-->  F = TF(f)  --(FFT^-1)-->  fb = TF^-1(F) = TF^-1(TF(f))
+// sum(f(x_i)^2) = S
+//                sum(F(nu_i)^2) = S*N
+//                                          sum(fb(x_i)^2) = S*N^2
+{
+ // --- RaZ du tableau
+ T_ = complex<r_8>(0.);
+
+ // --- On remplit avec une realisation
+ if(lp_>0) cout<<"--- ComputeFourier ---"<<endl;
+ long lmod = Nx_/10; if(lmod<1) lmod=1;
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;  kx *= kx;
+   if(lp_>0 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;  ky *= ky;
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;  kz *= kz;
+       if(i==0 && j==0 && l==0) continue; // Suppression du continu
+       double k = sqrt(kx+ky+kz);
+       // cf normalisation: Peacock, Cosmology, formule 16.38 p504
+       double pk = pk_at_z(k)/Vol_;
+       // Explication de la division par 2: voir perandom.cc
+       // ou egalement Coles & Lucchin, Cosmology formula 13.7.2 p279
+       T_(l,j,i) = ComplexGaussRan(sqrt(pk/2.));
+     }
+   }
+ }
+
+ manage_coefficients();   // gros effet pour les spectres que l'on utilise !
+
+ if(lp_>0) cout<<"...computing power"<<endl;
+ double p = compute_power_carte();
+ if(lp_>0) cout<<"Puissance dans la realisation: "<<p<<endl;
+
+}
+
+long GeneFluct3D::manage_coefficients(void)
+// Take into account the real and complexe conjugate coefficients
+// because we want a realization of a real data in real space
+{
+ if(lp_>1) cout<<"...managing coefficients"<<endl;
+ check_array_alloc();
+
+ // 1./ Le Continu et Nyquist sont reels
+ long nreal = 0;
+ for(long kk=0;kk<2;kk++) {
+   long k=0;  // continu
+   if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;}  // Nyquist
+   for(long jj=0;jj<2;jj++) {
+     long j=0;
+     if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
+     for(long ii=0;ii<2;ii++) {
+       long i=0;
+       if(ii==1) {if( Nx_%2!=0) continue; else i = Nx_/2;}
+       int_8 ip = IndexC(i,j,k);
+       //cout<<"i="<<i<<" j="<<j<<" k="<<k<<" = ("<<fdata_[ip][0]<<","<<fdata_[ip][1]<<")"<<endl;
+       fdata_[ip][1] = 0.; fdata_[ip][0] *= M_SQRT2;
+       nreal++;
+     }
+   }
+ }
+ if(lp_>1) cout<<"Number of forced real number ="<<nreal<<endl;
+
+ // 2./ Les elements complexe conjugues (tous dans le plan k=0,Nyquist)
+
+ // a./ les lignes et colonnes du continu et de nyquist
+ long nconj1 = 0;
+ for(long kk=0;kk<2;kk++) {
+   long k=0;  // continu
+   if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;}  // Nyquist
+   for(long jj=0;jj<2;jj++) { // selon j
+     long j=0;
+     if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
+     for(long i=1;i<(Nx_+1)/2;i++) {
+       int_8 ip = IndexC(i,j,k);
+       int_8 ip1 = IndexC(Nx_-i,j,k);
+       fdata_[ip1][0] = fdata_[ip][0]; fdata_[ip1][1] = -fdata_[ip][1];
+       nconj1++;
+     }
+   }
+   for(long ii=0;ii<2;ii++) {
+     long i=0;
+     if(ii==1) {if( Nx_%2!=0) continue; else i = Nx_/2;}
+     for(long j=1;j<(Ny_+1)/2;j++) {
+       int_8 ip = IndexC(i,j,k);
+       int_8 ip1 = IndexC(i,Ny_-j,k);
+       fdata_[ip1][0] = fdata_[ip][0]; fdata_[ip1][1] = -fdata_[ip][1];
+       nconj1++;
+     }
+   }
+ }
+ if(lp_>1) cout<<"Number of forced conjugate on cont+nyq ="<<nconj1<<endl;
+
+ // b./ les lignes et colonnes hors continu et de nyquist
+ long nconj2 = 0;
+ for(long kk=0;kk<2;kk++) {
+   long k=0;  // continu
+   if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;}  // Nyquist
+   for(long j=1;j<(Ny_+1)/2;j++) {
+     if(Ny_%2==0 && j==Ny_/2) continue; // on ne retraite pas nyquist en j
+     for(long i=1;i<Nx_;i++) {
+       if(Nx_%2==0 && i==Nx_/2) continue; // on ne retraite pas nyquist en i
+       int_8 ip = IndexC(i,j,k);
+       int_8 ip1 = IndexC(Nx_-i,Ny_-j,k);
+       fdata_[ip1][0] = fdata_[ip][0]; fdata_[ip1][1] = -fdata_[ip][1];
+       nconj2++;
+     }
+   }
+ }
+ if(lp_>1) cout<<"Number of forced conjugate hors cont+nyq ="<<nconj2<<endl;
+
+ if(lp_>1) cout<<"Check: ddl= "<<NRtot_<<" =?= "<<2*(Nx_*Ny_*NCz_-nconj1-nconj2)-8<<endl;
+
+ return nreal+nconj1+nconj2;
+}
+
+double GeneFluct3D::compute_power_carte(void)
+// Calcul la puissance de la realisation du spectre Pk
+{
+ check_array_alloc();
+
+ double s2 = 0.;
+ for(long l=0;l<NCz_;l++)
+   for(long j=0;j<Ny_;j++)
+     for(long i=0;i<Nx_;i++) s2 += MODULE2(T_(l,j,i));
+
+ double s20 = 0.;
+ for(long j=0;j<Ny_;j++)
+   for(long i=0;i<Nx_;i++) s20 += MODULE2(T_(0,j,i));
+
+ double s2n = 0.;
+ if(Nz_%2==0)
+   for(long j=0;j<Ny_;j++)
+     for(long i=0;i<Nx_;i++) s2n += MODULE2(T_(NCz_-1,j,i));
+
+ return 2.*s2 -s20 -s2n;
+}
+
+//-------------------------------------------------------------------
+void GeneFluct3D::FilterByPixel(void)
+// Filtrage par la fonction fenetre du pixel (parallelepipede)
+// TF = 1/(dx*dy*dz)*Int[{-dx/2,dx/2},{-dy/2,dy/2},{-dz/2,dz/2}]
+//                   e^(ik_x*x) e^(ik_y*y) e^(ik_z*z) dxdydz
+//    = 2/(k_x*dx) * sin(k_x*dx/2)  * (idem y) * (idem z)
+// Gestion divergence en 0: sin(y)/y = 1 - y^2/6*(1-y^2/20)
+//                          avec y = k_x*dx/2
+{
+ if(lp_>0) cout<<"--- FilterByPixel ---"<<endl;
+ check_array_alloc();
+
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_ *Dx_/2;
+   double pk_x = pixelfilter(kx);
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_ *Dy_/2;
+     double pk_y = pixelfilter(ky);
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_ *Dz_/2;
+       double pk_z =  pixelfilter(kz);
+       T_(l,j,i) *= pk_x*pk_y*pk_z;
+     }
+   }
+ }
+
+}
+
+//-------------------------------------------------------------------
+void GeneFluct3D::ApplyGrowthFactor(int type_evol)
+// Apply Growth to real space
+// Using the correspondance between redshift and los comoving distance
+// describe in vector "zred_" "loscom_"
+// type_evol = 1 : evolution de la puissance du bruit avec la distance a l'observateur
+//             2 : evolution de la puissance du bruit avec la distance du plan Z
+//             (tous les pixels d'un plan Z sont mis au meme redshift z que celui du milieu)
+{
+ if(lp_>0) cout<<"--- ApplyGrowthFactor: evol="<<type_evol<<endl;
+ check_array_alloc();
+
+ if(growth_ == NULL) {
+   char *bla = "GeneFluct3D::ApplyGrowthFactor_Error: set GrowthFactor first";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+ if(type_evol<1 || type_evol>2) {
+   char *bla = "GeneFluct3D::ApplyGrowthFactor_Error: bad type_evol value";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+
+ InterpFunc interpinv(loscom2zred_min_,loscom2zred_max_,loscom2zred_);
+ unsigned short ok;
+
+ //CHECK: Histo hgr(0.9*zred_[0],1.1*zred_[n-1],1000);
+ for(long i=0;i<Nx_;i++) {
+   double dx2 = DXcom(i); dx2 *= dx2;
+   for(long j=0;j<Ny_;j++) {
+     double dy2 = DYcom(j); dy2 *= dy2;
+     for(long l=0;l<Nz_;l++) {
+       double dz = DZcom(l);
+       if(type_evol==1) dz = sqrt(dx2+dy2+dz*dz);
+         else dz = fabs(dz); // tous les plans Z au meme redshift
+       double z = interpinv(dz);
+       //CHECK: hgr.Add(z);
+       double dzgr = (*growth_)(z);   // interpolation par morceau
+       //double dzgr = growth_->Linear(z,ok);  // interpolation lineaire
+       //double dzgr = growth_->Parab(z,ok);  // interpolation parabolique
+       int_8 ip = IndexR(i,j,l);
+       data_[ip] *= dzgr;
+     }
+   }
+ }
+
+ //CHECK: {POutPersist pos("applygrowth.ppf"); string tag="hgr"; pos.PutObject(hgr,tag);}
+
+}
+
+//-------------------------------------------------------------------
+void GeneFluct3D::ComputeReal(void)
+// Calcule une realisation dans l'espace reel
+{
+ if(lp_>0) cout<<"--- ComputeReal ---"<<endl;
+ check_array_alloc();
+
+ // On fait la FFT
+ fftw_execute(pb_);
+}
+
+//-------------------------------------------------------------------
+void GeneFluct3D::ReComputeFourier(void)
+{
+ if(lp_>0) cout<<"--- ReComputeFourier ---"<<endl;
+ check_array_alloc();
+
+ // On fait la FFT
+ fftw_execute(pf_);
+ // On corrige du pb de la normalisation de FFTW3
+ double v = (double)NRtot_;
+ for(long i=0;i<Nx_;i++)
+   for(long j=0;j<Ny_;j++)
+     for(long l=0;l<NCz_;l++) T_(l,j,i) /= complex<r_8>(v);
+
+}
+
+//-------------------------------------------------------------------
+int GeneFluct3D::ComputeSpectrum(HistoErr& herr)
+// Compute spectrum from "T" and fill HistoErr "herr"
+// T : dans le format standard de GeneFuct3D: T(nz,ny,nx)
+// cad T(kz,ky,kx) avec  0<kz<kz_nyq  -ky_nyq<ky<ky_nyq  -kx_nyq<kx<kx_nyq
+{
+ if(lp_>0) cout<<"--- ComputeSpectrum ---"<<endl;
+ check_array_alloc();
+
+ if(herr.NBins()<0) return -1;
+ herr.Zero();
+
+ // Attention a l'ordre
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;  kx *= kx;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;  ky *= ky;
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;
+       double k = sqrt(kx+ky+kz*kz);
+       double pk = MODULE2(T_(l,j,i));
+       herr.Add(k,pk);
+     }
+   }
+ }
+ herr.ToVariance();
+
+ // renormalize to directly compare to original spectrum
+ double norm = Vol_;
+ herr *= norm;
+
+ return 0;
+}
+
+int GeneFluct3D::ComputeSpectrum2D(Histo2DErr& herr)
+{
+ if(lp_>0) cout<<"--- ComputeSpectrum2D ---"<<endl;
+ check_array_alloc();
+
+ if(herr.NBinX()<0 || herr.NBinY()<0) return -1;
+ herr.Zero();
+
+ // Attention a l'ordre
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;  kx *= kx;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;  ky *= ky;
+     double kt = sqrt(kx+ky);
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;
+       double pk = MODULE2(T_(l,j,i));
+       herr.Add(kt,kz,pk);
+     }
+   }
+ }
+ herr.ToVariance();
+
+ // renormalize to directly compare to original spectrum
+ double norm = Vol_;
+ herr *= norm;
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
+int GeneFluct3D::ComputeSpectrum(HistoErr& herr,double sigma,bool pixcor)
+// Compute spectrum from "T" and fill HistoErr "herr"
+// AVEC la soustraction du niveau de bruit et la correction par filterpixel()
+// Si on ne fait pas ca, alors on obtient un spectre non-isotrope!
+//
+// T : dans le format standard de GeneFuct3D: T(nz,ny,nx)
+// cad T(kz,ky,kx) avec  0<kz<kz_nyq  -ky_nyq<ky<ky_nyq  -kx_nyq<kx<kx_nyq
+{
+  if(lp_>0) cout<<"--- ComputeSpectrum: sigma="<<sigma<<endl;
+ check_array_alloc();
+
+ if(sigma<=0.) sigma = 0.;
+ double sigma2 = sigma*sigma / (double)NRtot_;
+
+ if(herr.NBins()<0) return -1;
+ herr.Zero();
+
+ TVector<r_8> vfz(NCz_);
+ if(pixcor)  // kz = l*Dkz_
+   for(long l=0;l<NCz_;l++) {vfz(l)=pixelfilter(l*Dkz_ *Dz_/2); vfz(l)*=vfz(l);}
+
+ // Attention a l'ordre
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;
+   double fx = (pixcor) ? pixelfilter(kx*Dx_/2): 1.;
+   kx *= kx; fx *= fx;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;
+     double fy = (pixcor) ? pixelfilter(ky*Dy_/2): 1.;
+     ky *= ky; fy *= fy;
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;
+       double k = sqrt(kx+ky+kz*kz);
+       double pk = MODULE2(T_(l,j,i)) - sigma2;
+       double fz = (pixcor) ? vfz(l): 1.;
+       double f = fx*fy*fz;
+       if(f>0.) herr.Add(k,pk/f);
+     }
+   }
+ }
+ herr.ToVariance();
+ for(int i=0;i<herr.NBins();i++) herr(i) += sigma2;
+
+ // renormalize to directly compare to original spectrum
+ double norm = Vol_;
+ herr *= norm;
+
+ return 0;
+}
+
+int GeneFluct3D::ComputeSpectrum2D(Histo2DErr& herr,double sigma,bool pixcor)
+// AVEC la soustraction du niveau de bruit et la correction par filterpixel()
+{
+ if(lp_>0) cout<<"--- ComputeSpectrum2D: sigma="<<sigma<<endl;
+ check_array_alloc();
+
+ if(sigma<=0.) sigma = 0.;
+ double sigma2 = sigma*sigma / (double)NRtot_;
+
+ if(herr.NBinX()<0 || herr.NBinY()<0) return -1;
+ herr.Zero();
+
+ TVector<r_8> vfz(NCz_);
+ if(pixcor)  // kz = l*Dkz_
+   for(long l=0;l<NCz_;l++) {vfz(l)=pixelfilter(l*Dkz_ *Dz_/2); vfz(l)*=vfz(l);}
+
+ // Attention a l'ordre
+ for(long i=0;i<Nx_;i++) {
+   long ii = (i>Nx_/2) ? Nx_-i : i;
+   double kx = ii*Dkx_;
+   double fx = (pixcor) ? pixelfilter(kx*Dx_/2) : 1.;
+   kx *= kx; fx *= fx;
+   for(long j=0;j<Ny_;j++) {
+     long jj = (j>Ny_/2) ? Ny_-j : j;
+     double ky = jj*Dky_;
+     double fy = (pixcor) ? pixelfilter(ky*Dy_/2) : 1.;
+     ky *= ky; fy *= fy;
+     double kt = sqrt(kx+ky);
+     for(long l=0;l<NCz_;l++) {
+       double kz = l*Dkz_;
+       double pk = MODULE2(T_(l,j,i)) - sigma2;
+       double fz = (pixcor) ? vfz(l): 1.;
+       double f = fx*fy*fz;
+       if(f>0.) herr.Add(kt,kz,pk/f);
+     }
+   }
+ }
+ herr.ToVariance();
+ for(int i=0;i<herr.NBinX();i++)
+    for(int j=0;j<herr.NBinY();j++) herr(i,j) += sigma2;
+
+ // renormalize to directly compare to original spectrum
+ double norm = Vol_;
+ herr *= norm;
+
+ return 0;
+}
+
+//-------------------------------------------------------
+int_8 GeneFluct3D::VarianceFrReal(double R,double& var)
+// Recompute MASS variance in spherical top-hat (rayon=R)
+// Par definition: SigmaR^2 = <(M-<M>)^2>/<M>^2
+//                 ou M = masse dans sphere de rayon R
+// --- ATTENTION: la variance calculee a une tres grande dispersion
+//  (surtout si le volume du cube est petit). Pour verifier
+//  que le sigmaR calcule par cette methode est en accord avec
+//  le sigmaR en input, il faut faire plusieurs simulations (~100)
+//  et regarder la moyenne des sigmaR reconstruits
+{
+  if(lp_>0) cout<<"--- VarianceFrReal R="<<R<<endl;
+ check_array_alloc();
+
+ long dnx = long(R/Dx_)+1; if(dnx<=0) dnx = 1;
+ long dny = long(R/Dy_)+1; if(dny<=0) dny = 1;
+ long dnz = long(R/Dz_)+1; if(dnz<=0) dnz = 1;
+ if(lp_>0) cout<<"dnx="<<dnx<<" dny="<<dny<<" dnz="<<dnz<<endl;
+
+ double sum=0., sum2=0., sn=0., r2 = R*R;
+ int_8 nsum=0;
+
+ for(long i=dnx;i<Nx_-dnx;i+=2*dnx) {
+   for(long j=dny;j<Ny_-dny;j+=2*dny) {
+     for(long l=dnz;l<Nz_-dnz;l+=2*dnz) {
+       double m=0.; int_8 n=0;
+       for(long ii=i-dnx;ii<=i+dnx;ii++) {
+         double x = (ii-i)*Dx_; x *= x;
+         for(long jj=j-dny;jj<=j+dny;jj++) {
+           double y = (jj-j)*Dy_; y *= y;
+           for(long ll=l-dnz;ll<=l+dnz;ll++) {
+             double z = (ll-l)*Dz_; z *= z;
+             if(x+y+z>r2) continue;
+             int_8 ip = IndexR(ii,jj,ll);
+             m += 1.+data_[ip];  // 1+drho/rho
+             n++;
+	   }
+	 }
+       }
+       if(n>0) {sum += m; sum2 += m*m; nsum++; sn += n;}
+       //cout<<i<<","<<j<<","<<l<<" n="<<n<<" m="<<m<<" sum="<<sum<<" sum2="<<sum2<<endl;
+     }
+   }
+ }
+
+ if(nsum<=1) {var=0.; return nsum;}
+ sum /= nsum;
+ sum2 = sum2/nsum - sum*sum;
+ sn /= nsum;
+ if(lp_>0) cout<<"...<n>="<<sn<<", nsum="<<nsum<<" <M>="<<sum<<" <(M-<M>)^2>="<<sum2<<endl;
+ var = sum2/(sum*sum);  // <dM^2>/<M>^2
+ if(lp_>0) cout<<"...sigmaR^2 = <(M-<M>)^2>/<M>^2 = "<<var
+               <<" -> sigmaR = "<<sqrt(var)<<endl;
+
+ return nsum;
+}
+
+//-------------------------------------------------------
+int_8 GeneFluct3D::NumberOfBad(double vmin,double vmax)
+// number of pixels outside of ]vmin,vmax[ extremites exclues
+//     ->  vmin and vmax are considered as bad
+{
+ check_array_alloc();
+
+ int_8 nbad = 0;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(v<=vmin || v>=vmax) nbad++;
+ }
+
+ if(lp_>0) cout<<"--- NumberOfBad "<<nbad<<" px out of ]"<<vmin<<","<<vmax
+               <<"[ i.e. frac="<<nbad/(double)NRtot_<<endl;
+ return nbad;
+}
+
+int_8 GeneFluct3D::MinMax(double& xmin,double& xmax,double vmin,double vmax)
+// Calcul des valeurs xmin et xmax dans le cube reel avec valeurs ]vmin,vmax[ extremites exclues
+{
+ bool tstval = (vmax>vmin)? true: false;
+ if(lp_>0) {
+   cout<<"--- MinMax";
+   if(tstval) cout<<"  range=]"<<vmin<<","<<vmax<<"[";
+   cout<<endl;
+ }
+ check_array_alloc();
+
+ int_8 n = 0;
+ xmin = xmax = data_[0];
+
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double x = data_[ip];
+   if(tstval && (x<=vmin || x>=vmax)) continue;
+   if(x<xmin) xmin = x;
+   if(x>xmax) xmax = x;
+   n++;
+ }
+
+ if(lp_>0) cout<<"  n="<<n<<" min="<<xmin<<" max="<<xmax<<endl;
+
+ return n;
+}
+
+int_8 GeneFluct3D::MeanSigma2(double& rm,double& rs2,double vmin,double vmax
+                             ,bool useout,double vout)
+// Calcul de mean,sigma2 dans le cube reel avec valeurs ]vmin,vmax[ extremites exclues
+// useout = false: ne pas utiliser les pixels hors limites pour calculer mean,sigma2
+//          true : utiliser les pixels hors limites pour calculer mean,sigma2
+//                 en remplacant leurs valeurs par "vout"
+{
+ bool tstval = (vmax>vmin)? true: false;
+ if(lp_>0) {
+   cout<<"--- MeanSigma2";
+   if(tstval) cout<<"  range=]"<<vmin<<","<<vmax<<"[";
+   if(useout) cout<<", useout="<<useout<<" vout="<<vout;
+   cout<<endl;
+ }
+ check_array_alloc();
+
+ int_8 n = 0;
+ rm = rs2 = 0.;
+
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(tstval) {
+     if(v<=vmin || v>=vmax) {if(useout) v=vout; else continue;}
+   }
+   rm += v;
+   rs2 += v*v;
+   n++;
+ }
+
+ if(n>1) {
+   rm /= (double)n;
+   rs2 = rs2/(double)n - rm*rm;
+ }
+
+ if(lp_>0) cout<<"  n="<<n<<" m="<<rm<<" s2="<<rs2<<" s="<<sqrt(fabs(rs2))<<endl;
+
+ return n;
+}
+
+int_8 GeneFluct3D::SetToVal(double vmin, double vmax,double val0)
+// set to "val0" if out of range ]vmin,vmax[ extremites exclues
+// cad set to "val0" if in [vmin,vmax] -> vmin and vmax are set to val0
+{
+ check_array_alloc();
+
+ int_8 nbad = 0;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(v<=vmin || v>=vmax) {data_[ip] = val0; nbad++;}
+ }
+
+ if(lp_>0) cout<<"--- SetToVal "<<nbad<<" px set to="<<val0
+               <<" because out of range=]"<<vmin<<","<<vmax<<"["<<endl;
+ return nbad;
+}
+
+void GeneFluct3D::ScaleOffset(double scalecube,double offsetcube)
+// Replace  "V"  by  "scalecube * ( V + offsetcube )"
+{
+ if(lp_>0) cout<<"--- ScaleCube scale="<<scalecube<<" offset="<<offsetcube<<endl;
+
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   data_[ip] = scalecube * ( data_[ip] + offsetcube );
+ }
+
+ return;
+}
+
+//-------------------------------------------------------
+void GeneFluct3D::TurnFluct2Mass(void)
+// d_rho/rho -> Mass  (add one!)
+{
+ if(lp_>0) cout<<"--- TurnFluct2Mass ---"<<endl;
+ check_array_alloc();
+
+
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   data_[ip] += 1.;
+ }
+}
+
+double GeneFluct3D::TurnFluct2MeanNumber(double val_by_mpc3)
+// ATTENTION: la gestion des pixels<0 proposee ici induit une perte de variance
+// sur la carte, le spectre Pk reconstruit sera plus faible!
+// L'effet sera d'autant plus grand que le nombre de pixels<0 sera grand.
+{
+ if(lp_>0) cout<<"--- TurnFluct2MeanNumber : "<<val_by_mpc3<<" quantity (gal or mass)/Mpc^3"<<endl;
+
+ // First convert dRho/Rho into 1+dRho/Rho
+ int_8  nball = 0; double sumall = 0., sumall2 = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   data_[ip] += 1.;
+   nball++; sumall += data_[ip]; sumall2 += data_[ip]*data_[ip];
+ }
+ if(nball>2) {
+   sumall /= (double)nball;
+   sumall2 = sumall2/(double)nball - sumall*sumall;
+   if(lp_>0) cout<<"1+dRho/Rho: mean="<<sumall<<" variance="<<sumall2
+                 <<" -> "<<sqrt(fabs(sumall2))<<endl;
+ }
+
+ // Find contribution for positive pixels
+ int_8  nbpos = 0; double sumpos = 0. , sumpos2 = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(data_[ip]>0.) {nbpos++; sumpos += v; sumpos2 += v*v;}
+ }
+ if(nbpos<1) {
+   cout<<"TurnFluct2MeanNumber_Error: nbpos<1"<<endl;
+   throw RangeCheckError("TurnFluct2MeanNumber_Error: nbpos<1");
+ }
+ sumpos2 = sumpos2/nball - sumpos*sumpos/(nball*nball);
+ if(lp_>0)
+   cout<<"1+dRho/Rho with v<0 set to zero: mean="<<sumpos/nball
+       <<" variance="<<sumpos2<<" -> "<<sqrt(fabs(sumpos2))<<endl;
+   cout<<"Sum of positive values: sumpos="<<sumpos
+       <<" (n(v>0) = "<<nbpos<<" frac(v>0)="<<nbpos/(double)NRtot_<<")"<<endl;
+
+ // - Mettre exactement val_by_mpc3*Vol galaxies (ou Msol) dans notre survey
+ // - Uniquement dans les pixels de masse >0.
+ // - Mise a zero des pixels <0
+ double dn = val_by_mpc3 * Vol_ / sumpos;
+ if(lp_>0) cout<<"...density move from "
+               <<val_by_mpc3*dVol_<<" to "<<dn<<" / pixel"<<endl;
+
+ double sum = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   if(data_[ip]<=0.) data_[ip] = 0.;
+   else {
+     data_[ip] *= dn;
+     sum += data_[ip];
+   }
+ }
+
+ if(lp_>0) cout<<"...quantity put into survey "<<sum<<" / "<<val_by_mpc3*Vol_<<endl;
+
+ return sum;
+}
+
+double GeneFluct3D::ApplyPoisson(void)
+// do NOT treate negative or nul mass  -> let it as it is
+{
+ if(lp_>0) cout<<"--- ApplyPoisson ---"<<endl;
+ check_array_alloc();
+
+ double sum = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(v>0.) {
+     unsigned long dn = PoissRandLimit(v,10.);
+     data_[ip] = (double)dn;
+     sum += (double)dn;
+   }
+ }
+ if(lp_>0) cout<<sum<<" galaxies put into survey"<<endl;
+
+ return sum;
+}
+
+double GeneFluct3D::TurnNGal2Mass(FunRan& massdist,bool axeslog)
+// do NOT treate negative or nul mass  -> let it as it is
+// INPUT:
+//   massdist : distribution de masse (m*dn/dm)
+//   axeslog = false : retourne la masse
+//           = true  : retourne le log10(mass)
+// RETURN la masse totale
+{
+ if(lp_>0) cout<<"--- TurnNGal2Mass ---"<<endl;
+ check_array_alloc();
+
+ double sum = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(v>0.) {
+     long ngal = long(v+0.1);
+     data_[ip] = 0.;
+     for(long i=0;i<ngal;i++) {
+       double m = massdist.RandomInterp();  // massdist.Random();
+       if(axeslog) m = pow(10.,m);
+       data_[ip] += m;
+     }
+     sum += data_[ip];
+   }
+ }
+ if(lp_>0) cout<<sum<<" MSol HI mass put into survey"<<endl;
+
+ return sum;
+}
+
+double GeneFluct3D::TurnNGal2MassQuick(SchechterMassDist& schmdist)
+// idem TurnNGal2Mass mais beaucoup plus rapide
+{
+ if(lp_>0) cout<<"--- TurnNGal2MassQuick ---"<<endl;
+ check_array_alloc();
+
+ double sum = 0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
+   int_8 ip = IndexR(i,j,l);
+   double v = data_[ip];
+   if(v>0.) {
+     long ngal = long(v+0.1);
+     data_[ip] = schmdist.TirMass(ngal);
+     sum += data_[ip];
+   }
+ }
+ if(lp_>0) cout<<sum<<" MSol HI mass put into survey"<<endl;
+
+ return sum;
+}
+
+void GeneFluct3D::AddNoise2Real(double snoise,int type_evol)
+// add noise to every pixels (meme les <=0 !)
+// type_evol = 0 : pas d'evolution de la puissance du bruit
+//             1 : evolution de la puissance du bruit avec la distance a l'observateur
+//             2 : evolution de la puissance du bruit avec la distance du plan Z
+//                 (tous les plans Z sont mis au meme redshift z de leur milieu)
+{
+ if(lp_>0) cout<<"--- AddNoise2Real: snoise = "<<snoise<<" evol="<<type_evol<<endl;
+ check_array_alloc();
+
+ if(type_evol<0) type_evol = 0;
+ if(type_evol>2) {
+   char *bla = "GeneFluct3D::AddNoise2Real_Error: bad type_evol value";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+
+ vector<double> correction;
+ InterpFunc *intercor = NULL;
+
+ if(type_evol>0) {
+   // Sigma_Noise(en mass) :
+   //      Slim ~ 1/sqrt(DNu) * sqrt(nlobe)   en W/m^2Hz
+   //      Flim ~ sqrt(DNu) * sqrt(nlobe)   en W/m^2
+   //      Mlim ~ sqrt(DNu) * (Dlum)^2 * sqrt(nlobe)  en Msol
+   //                                    nlobe ~ 1/Dtrcom^2
+   //      Mlim ~ sqrt(DNu) * (Dlum)^2 / Dtrcom
+   if(cosmo_ == NULL || redsh_ref_<0.| loscom2zred_.size()<1) {
+     char *bla = "GeneFluct3D::AddNoise2Real_Error: set Observator and Cosmology first";
+     cout<<bla<<endl; throw ParmError(bla);
+   }
+   InterpFunc interpinv(loscom2zred_min_,loscom2zred_max_,loscom2zred_);
+   long nsz = loscom2zred_.size(), nszmod=((nsz>10)? nsz/10: 1);
+   for(long i=0;i<nsz;i++) {
+     double d = interpinv.X(i);
+     double zred = interpinv(d);
+     double dtrc = cosmo_->Dtrcom(zred);  // pour variation angle solide
+     double dlum = cosmo_->Dlum(zred);  // pour variation conversion mass HI
+     double dred = Dz_/(cosmo_->Dhubble()/cosmo_->E(zred));
+     double dnu  = Fr_HyperFin_Par *dred/pow(1.+zred,2.); // pour variation dNu
+     double corr = sqrt(dnu/dnu_ref_) * pow(dlum/dlum_ref_,2.) * dtrc_ref_/dtrc;
+     if(lp_>0 && (i==0 || i==nsz-1 || i%nszmod==0))
+       cout<<"i="<<i<<" d="<<d<<" red="<<zred<<" dred="<<dred<<" dnu="<<dnu
+           <<" dtrc="<<dtrc<<" dlum="<<dlum<<" -> cor="<<corr<<endl;
+     correction.push_back(corr);
+   }
+   intercor = new InterpFunc(loscom2zred_min_,loscom2zred_max_,correction);
+ } 
+
+ double corrlim[2] = {1.,1.};
+ for(long i=0;i<Nx_;i++) {
+   double dx2 = DXcom(i); dx2 *= dx2;
+   for(long j=0;j<Ny_;j++) {
+     double dy2 = DYcom(j); dy2 *= dy2;
+     for(long l=0;l<Nz_;l++) {
+       double corr = 1.;
+       if(type_evol>0) {
+         double dz = DZcom(l);
+         if(type_evol==1) dz = sqrt(dx2+dy2+dz*dz);
+           else dz = fabs(dz); // tous les plans Z au meme redshift
+         corr = (*intercor)(dz);
+         if(corr<corrlim[0]) corrlim[0]=corr; else if(corr>corrlim[1]) corrlim[1]=corr;
+       }
+       int_8 ip = IndexR(i,j,l);
+       data_[ip] += snoise*corr*NorRand();
+     }
+   }
+ }
+ if(type_evol>0)
+   cout<<"correction factor range: ["<<corrlim[0]<<","<<corrlim[1]<<"]"<<endl;
+
+ if(intercor!=NULL) delete intercor;
+}
+
+}  // Fin namespace SOPHYA
+
+
+
+
+/*********************************************************************
+void GeneFluct3D::AddAGN(double lfjy,double lsigma,double powlaw)
+// Add AGN flux into simulation:
+// --- Procedure:
+// 1. lancer "cmvdefsurv" avec les parametres du survey
+//        (au redshift de reference du survey)
+//    et recuperer l'angle solide "angsol sr" du pixel elementaire
+//    au centre du cube.
+// 2. lancer "cmvtstagn" pour cet angle solide -> cmvtstagn.ppf
+// 3. regarder l'histo "hlfang" et en deduire un equivalent gaussienne
+//    cad une moyenne <log10(S)> et un sigma "sig"
+//    Attention: la distribution n'est pas gaussienne les "mean,sigma"
+//               de l'histo ne sont pas vraiment ce que l'on veut
+// --- Limitations actuelle du code:
+// . les AGN sont supposes evoluer avec la meme loi de puissance pour tout theta,phi
+// . le flux des AGN est mis dans une colonne Oz (indice k) et pas sur la ligne de visee
+// . la distribution est approximee a une gaussienne
+// ... C'est une approximation pour un observateur loin du centre du cube
+//     et pour un cube peu epais / distance observateur 
+// --- Parametres de la routine:
+// llfy : c'est le <log10(S)> du flux depose par les AGN
+//        dans l'angle solide du pixel elementaire de reference du cube
+// lsigma : c'est le sigma de la distribution des log10(S)
+// powlaw : c'est la pente de la distribution cad que le flux "lmsol"
+//          et considere comme le flux a 1.4GHz et qu'on suppose une loi
+//             F(nu) = (1.4GHz/nu)^powlaw * F(1.4GHz)
+// - Comme on est en echelle log10():
+//   on tire log10(Msol) + X
+//   ou X est une realisation sur une gaussienne de variance "sig^2"
+//   La masse realisee est donc: Msol*10^X
+// - Pas de probleme de pixel negatif car on a une multiplication!
+{
+  if(lp_>0) cout<<"--- AddAGN: <log10(S Jy)> = "<<lfjy<<" , sigma = "<<lsigma<<endl;
+  check_array_alloc();
+
+ if(cosmo_ == NULL || redsh_ref_<0.| loscom2zred_.size()<1) {
+   char *bla = "GeneFluct3D::AddAGN_Error: set Observator and Cosmology first";
+   cout<<bla<<endl; throw ParmError(bla);
+ }
+
+ // Le flux des AGN en Jy et en mass solaire
+ double fagnref = pow(10.,lfjy)*(dnu_ref_*1.e9); // Jy.Hz = W/m^2
+ double magnref = FluxHI2Msol(fagnref*Jansky2Watt_cst,dlum_ref_); // Msol
+ if(lp_>0)
+   cout<<"Au pixel de ref: fagnref="<<fagnref
+       <<" Jy.Hz (a 1.4GHz), magnref="<<magnref<<" Msol"<<endl;
+
+ if(powlaw!=0.) {
+   // F(nu) = F(1.4GHz)*(nu GHz/1.4 Ghz)^p = F(1.4GHz)*(1/(1+z))^p , car nu = 1.4 GHz/(1+z)
+   magnref *= pow(1/(1.+redsh_ref_),powlaw);
+   if(lp_>0) cout<<" powlaw="<<powlaw<<"  -> change magnref to "<<magnref<<" Msol"<<endl;
+ }
+
+ // Les infos en fonction de l'indice "l" selon Oz
+ vector<double> correction;
+ InterpFunc interpinv(loscom2zred_min_,loscom2zred_max_,loscom2zred_);
+ long nzmod = ((Nz_>10)?Nz_/10:1);
+ for(long l=0;l<Nz_;l++) {
+   double z = fabs(DZcom(l));
+   double zred = interpinv(z);
+   double dtrc = cosmo_->Dtrcom(zred);  // pour variation angle solide
+   double dlum = cosmo_->Dlum(zred);  // pour variation conversion mass HI
+   double dred = Dz_/(cosmo_->Dhubble()/cosmo_->E(zred));
+   double dnu  = Fr_HyperFin_Par *dred/pow(1.+zred,2.); // pour variation dNu
+   // on a: Mass ~ DNu * Dlum^2 / Dtrcom^2
+   double corr = dnu/dnu_ref_*pow(dtrc_ref_/dtrc*dlum/dlum_ref_,2.);
+   // F(nu) = F(1.4GHz)*(nu GHz/1.4 Ghz)^p = F(1.4GHz)*(1/(1+z))^p , car nu = 1.4 GHz/(1+z)
+   if(powlaw!=0.) corr *= pow((1.+redsh_ref_)/(1.+zred),powlaw);
+   correction.push_back(corr);
+   if(lp_>0 && (l==0 || l==Nz_-1 || l%nzmod==0)) {
+     cout<<"l="<<l<<" z="<<z<<" red="<<zred<<" dred="<<dred<<" dnu="<<dnu
+         <<" dtrc="<<dtrc<<" dlum="<<dlum
+         <<" -> cor="<<corr<<endl;
+   }
+ }
+
+ double sum=0., sum2=0., nsum=0.;
+ for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) {
+   double a = lsigma*NorRand();
+   a = magnref*pow(10.,a);
+   // On met le meme tirage le long de Oz (indice k)
+   for(long l=0;l<Nz_;l++) {
+     int_8 ip = IndexR(i,j,l);
+     data_[ip] += a*correction[l];
+   }
+   sum += a; sum2 += a*a; nsum += 1.;
+ }
+
+ if(lp_>0 && nsum>1.) {
+   sum /= nsum;
+   sum2 = sum2/nsum - sum*sum;
+   cout<<"...Mean mass="<<sum<<" Msol , s^2="<<sum2<<" s="<<sqrt(fabs(sum2))<<endl;
+ }
+ 
+}
+*********************************************************************/
Index: /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/genefluct3d.h	(revision 3445)
@@ -0,0 +1,187 @@
+#ifndef GENEFLUCT3D_SEEN
+#define GENEFLUCT3D_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include "genericfunc.h"
+#include "tarray.h"
+#include "histerr.h"
+#include "hist2err.h"
+#include "perandom.h"
+
+#include "FFTW/fftw3.h"
+#include "FitsIO/fitsio.h"
+
+#include <vector>
+
+#include "cosmocalc.h"
+#include "pkspectrum.h"
+
+
+namespace SOPHYA {
+
+//-----------------------------------------------------------------------------------
+class GeneFluct3D {
+public:
+  GeneFluct3D(long nx,long ny,long nz,double dx,double dy,double dz,unsigned short nthread=0,int lp=0);  // Mpc
+  GeneFluct3D(unsigned short nthread=0);
+  virtual ~GeneFluct3D(void);
+
+  // Distance los comobile a l'observateur
+  void SetObservator(double redshref=0.,double kredshref=0.);
+    inline double DXcom(long i) {return i*Dx_ - xobs_[0];}
+    inline double DYcom(long j) {return j*Dy_ - xobs_[1];}
+    inline double DZcom(long k) {return k*Dz_ - xobs_[2];}
+    inline double Dcom(long i,long j,long k) {
+      double dx=DXcom(i), dy=DYcom(j), dz=DZcom(k); 
+      return sqrt(dx*dx+dy*dy+dz*dz);
+    }
+  void SetCosmology(CosmoCalc& cosmo);
+  void SetGrowthFactor(GrowthFactor& growth);
+  long LosComRedshift(double zinc=0.001,long npoints=-1);
+
+  TArray< complex<r_8> >& GetComplexArray(void) {return T_;}
+  fftw_complex* GetComplexPointer(void) {return fdata_;}
+  TArray<r_8>& GetRealArray(void) {return R_;}
+  r_8* GetRealPointer(void) {return data_;}
+
+  // Pour adressage data_[ip]
+  inline int_8 IndexR(long i,long j,long k) {return (int_8)(k+NTz_*(j+Ny_*i));}
+  // Pour adressage fdata_[ip][0-1]
+  inline int_8 IndexC(long i,long j,long k) {return (int_8)(k+NCz_*(j+Ny_*i));}
+  // On peut aussi adresser:
+  // TArray< complex<r_8> >& pk = gf3d.GetComplexArray();
+  //    pk(k,j,i) avec k=[0,NCz_[  j=[0,Ny_[   i=[0,Nx_[
+  //    pk[IndexC(i,j,k)]
+  // TArray<r_8>& rgen = gf3d.GetRealArray();
+  //    rgen(k,j,i) avec k=[0,NTz_[  j=[0,Ny_[   i=[0,Nx_[
+  //                mais seul k=[0,Nz_[ est utile
+  //    rgen[IndexR(i,j,k)]
+  // ATTENTION: TArray adresse en memoire a l'envers du C !
+  //            Tarray(n1,n2,n3) == Carray[n3][n2][n1]
+
+  vector<long> GetNpix(void) {return N_;}
+  int_8 NPix(void) {return NRtot_;}
+  long GetNx(void) {return Nx_;}
+  long GetNy(void) {return Ny_;}
+  long GetNz(void) {return Nz_;}
+
+  // Return |K_i| module relative to pixel indices
+  inline r_8 Kx(long i) {long ii=(i>Nx_/2)? Nx_-i :i; return ii*Dkx_;}
+  inline r_8 Ky(long j) {long jj=(j>Ny_/2)? Ny_-j :j; return jj*Dky_;}
+  inline r_8 Kz(long l) {return l*Dkz_;}
+
+  vector<r_8> GetDinc(void) {return D_;}
+  double GetDVol(void) {return dVol_;}
+  double GetVol(void) {return Vol_;}
+
+  vector<r_8> GetKinc(void) {return Dk_;}
+  vector<r_8> GetKnyq(void) {return Knyq_;}
+  double GetKmax(void) {return sqrt(Knyqx_*Knyqx_+Knyqy_*Knyqy_+Knyqz_*Knyqz_);}
+  double GetKTmax(void) {return sqrt(Knyqx_*Knyqx_+Knyqy_*Knyqy_);}
+  double GetKincMin(void)
+    {vector<r_8>::const_iterator it = min_element(Dk_.begin(), Dk_.end()); return *it;}
+  double GetKincMax(void)
+    {vector<r_8>::const_iterator it = max_element(Dk_.begin(), Dk_.end()); return *it;}
+  double GetKTincMin(void) {return min(Dk_[0],Dk_[1]);}
+  double GetKTincMax(void) {return max(Dk_[0],Dk_[1]);}
+
+  void ComputeFourier0(GenericFunc& pk_at_z);
+  void ComputeFourier(GenericFunc& pk_at_z);
+  void FilterByPixel(void);
+
+  void ComputeReal(void);
+  void ApplyGrowthFactor(int type_evol=1);
+
+  void ReComputeFourier(void);
+
+  int  ComputeSpectrum(HistoErr& herr);
+  int  ComputeSpectrum2D(Histo2DErr& herr);
+  int  ComputeSpectrum(HistoErr& herr,double sigma,bool pixcor);
+  int  ComputeSpectrum2D(Histo2DErr& herr,double sigma,bool pixcor);
+
+  int_8 VarianceFrReal(double R,double& var);
+  int_8 MeanSigma2(double& rm,double& rs2,double vmin=1.,double vmax=-1.
+                  ,bool useout=false,double vout=0.);
+  int_8 MinMax(double& xmin,double& xmax,double vmin=1.,double vmax=-1.);
+  int_8 NumberOfBad(double vmin=-1.e+150,double vmax=1.e+150);
+  int_8 SetToVal(double vmin, double vmax,double val0=0.);
+  void  ScaleOffset(double scalecube=1.,double offsetcube=0.);
+
+  void TurnFluct2Mass(void);
+  double TurnFluct2MeanNumber(double val_by_mpc3);
+  double ApplyPoisson(void);
+  double TurnNGal2Mass(FunRan& massdist,bool axeslog=false);
+  double TurnNGal2MassQuick(SchechterMassDist& schmdist);
+  double TurnMass2Flux(void);
+  //void AddAGN(double lfjy,double lsigma,double powlaw=0.);
+  void AddNoise2Real(double snoise,int type_evol=0);
+
+  void WriteFits(string cfname,int bitpix=FLOAT_IMG);
+  void ReadFits(string cfname);
+
+  void WritePPF(string cfname,bool write_real=true);
+  void ReadPPF(string cfname);
+  void WriteSlicePPF(string cfname);
+
+  void SetPrtLevel(int lp=0) {lp_ = lp;}
+  void Print(void);
+
+//-------------------------------------------------------------------
+
+protected:
+  void init_default(void);
+  void setsize(long nx,long ny,long nz,double dx,double dy,double dz);
+  void setalloc(void);
+  void setpointers(bool from_real);
+  void init_fftw(void);
+  void delete_fftw(void);
+  long manage_coefficients(void);
+  double compute_power_carte(void);
+  void check_array_alloc(void);
+  inline double pixelfilter(double x)
+    {return (x<0.025) ? 1.-x*x/6.*(1.-x*x/20.): sin(x)/x;}
+
+  // valeurs dans l'espace reel
+  long Nx_,Ny_,Nz_;  vector<long> N_;
+  long NCz_,NTz_;
+  int_8 NRtot_;
+
+  double Dx_,Dy_,Dz_;  vector<double> D_;
+
+  // valeurs dans l'espace des K
+  double Dkx_,Dky_,Dkz_;  vector<double> Dk_;
+  double Knyqx_,Knyqy_,Knyqz_;  vector<double> Knyq_;
+  double Dk3_;
+  double dVol_, Vol_;
+
+  // la gestion de la FFT
+  bool is_set_fftw_plan;
+  fftw_plan pf_,pb_;
+  unsigned short nthread_;
+  int lp_;
+
+  // le stockage du Cube de donnees et les pointeurs
+  bool array_allocated_;  // true if array has been allocated
+  TArray< complex<r_8> > T_;
+  fftw_complex *fdata_;
+  TArray<r_8> R_;
+  double *data_;
+
+  // l'observateur
+  CosmoCalc *cosmo_;
+  GrowthFactor *growth_;
+  double redsh_ref_,kredsh_ref_,dred_ref_;
+  double loscom_ref_,dtrc_ref_, dlum_ref_, dang_ref_;
+  double nu_ref_, dnu_ref_ ;
+  double xobs_[3];
+  double loscom_min_, loscom_max_;
+  vector<double> zred_, loscom_;
+  double loscom2zred_min_, loscom2zred_max_;
+  vector<double> loscom2zred_;
+
+};
+
+} // Fin du namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/geneutils.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/geneutils.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/geneutils.cc	(revision 3445)
@@ -0,0 +1,456 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <vector>
+
+#include "pexceptions.h"
+
+#include "histos.h"
+#include "hisprof.h"
+#include "srandgen.h"
+
+#include "geneutils.h"
+
+namespace SOPHYA {
+
+//-------------------------------------------------------------------
+// Classe d'interpolation lineaire:
+// Le vecteur y a n elements y_i tels que y_i = f(x_i)
+//   ou les x_i sont regulierement espaces
+//   et x_0=xmin et x_{n-1}=xmax   (xmax inclus!)
+InterpFunc::InterpFunc(double xmin,double xmax,vector<double>& y)
+  : _xmin(xmin), _xmax(xmax), _y(y)
+{
+  if(_xmin>=_xmax || _y.size()<=2) {  // au moins 3 points!
+   cout<<"InterpFunc::InterpFunc : bad arguments values"<<endl;
+   throw ParmError("InterpFunc::InterpFunc : bad arguments values");
+  }
+  _nm1   = _y.size()-1;
+  _dx    = (_xmax-_xmin)/(double)_nm1;
+}
+
+double InterpFunc::Linear(double x,unsigned short& ok)
+{
+  ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
+  x -= _xmin;
+  long i = long(x/_dx);  // On prend le "i" juste en dessous
+  if(i<0) i=0; else if(i>=_nm1) i=_nm1-1;
+  return _y[i] + (_y[i+1]-_y[i])/_dx*(x-i*_dx);
+}
+
+double InterpFunc::Parab(double x,unsigned short& ok)
+{
+  ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
+  x -= _xmin;
+  long i = long(x/_dx+0.5);  // On prend le "i" le + proche
+  if(i<1) i=1; else if(i>=_nm1-1) i=_nm1-2;
+  double a = (_y[i+1]-2.*_y[i]+_y[i-1])/(2.*_dx*_dx);
+  double b = (_y[i+1]-_y[i-1])/(2.*_dx);
+  return _y[i] + (x-i*_dx)*(a*(x-i*_dx)+b);
+}
+
+//-------------------------------------------------------------------
+// Classe d'inversion d'une fonction STRICTEMENT MONOTONE CROISSANTE
+//
+// - On part de deux vecteurs x,y de "Nin" elements tels que "y_i = f[x_i]"
+//   ou la fonction "f" est strictement monotone croissante:
+//          x(i) < x(i+1)   et   y(i) < y(i+1)
+// - Le but de la classe est de remplir un vecteur X de "Nout" elements
+//   tels que:    X_j = f^-1[Y_j]    avec   j=[0,Nout[
+//   avec les Y_j regulierement espaces entre ymin=y(0) , ymax=y(Nin -1)
+//   cad:     X_j = f^-1[ ymin+j*(ymax-ymin)/(Nout-1) ]
+// - La construction du vecteur X est realisee
+//   par interpolation lineaire (ComputeLinear) ou parabolique (ComputeParab)
+InverseFunc::InverseFunc(vector<double>& x,vector<double>& y)
+  : _ymin(0.) , _ymax(0.) , _x(x) , _y(y)
+{
+  uint_4 ns = _x.size();
+  if(ns<3 || _y.size()<=0 || ns!=_y.size())
+    throw ParmError("InverseFunc::InverseFunc_Error: bad array size");
+
+  // Check "x" strictement monotone croissant
+  for(uint_4 i=0;i<ns-1;i++)
+    if(_x[i+1]<=_x[i]) {
+      cout<<"InverseFunc::InverseFunc_Error: _x array not stricly growing"<<endl;
+      throw ParmError("InverseFunc::InverseFunc_Error: _x array not stricly growing");
+    }
+
+  // Check "y" monotone croissant
+  for(uint_4 i=0;i<ns-1;i++)
+    if(_y[i+1]<_y[i]) {
+      cout<<"InverseFunc::InverseFunc_Error: _y array not growing"<<endl;
+      throw ParmError("InverseFunc::InverseFunc_Error: _y array not growing");
+    }
+
+  // define limits
+  _ymin = _y[0];
+  _ymax = _y[ns-1];
+
+}
+
+InverseFunc::~InverseFunc(void)
+{
+}
+
+int InverseFunc::ComputeLinear(long nout,vector<double>& xfcty)
+// Compute table "xfcty" by linear interpolation of "x" versus "y"
+//   on "nout" points from "ymin" to "ymax":
+// xfcty[i] = interpolation of function "x" for "ymin+i*(ymax-ymin)/(nout-1)"
+{
+  if(nout<3) return -1;
+
+  xfcty.resize(nout);
+
+  long i1,i2;
+  double x;
+  for(int_4 i=0;i<nout;i++) {
+    double y = _ymin + i*(_ymax-_ymin)/(nout-1.);
+    find_in_y(y,i1,i2);
+    double dy = _y[i2]-_y[i1];
+    if(dy==0.) {
+      x = (_x[i2]+_x[i1])/2.; // la fct a inverser est plate!
+    } else {
+      x = _x[i1] + (_x[i2]-_x[i1])/dy * (y-_y[i1]);
+    }
+    xfcty[i] = x;
+  }
+
+  return 0;
+}
+
+int InverseFunc::ComputeParab(long nout,vector<double>& xfcty)
+{
+  if(nout<3) return -1;
+
+  xfcty.resize(nout);
+
+  long i1,i2,i3;
+  double x;
+  for(int_4 i=0;i<nout;i++) {
+    double y = _ymin + i*(_ymax-_ymin)/(nout-1.);
+    find_in_y(y,i1,i2);
+    // On cherche le 3ieme point selon la position de y / au 2 premiers
+    double my = (_y[i1]+_y[i2])/2.;
+    if(y<my) {i3=i2; i2=i1; i1--;} else {i3=i2+1;}
+    // Protection
+    if(i1<0) {i1++; i2++; i3++;}
+    if(i3==(long)_y.size()) {i1--; i2--; i3--;}
+    // Interpolation parabolique
+    double dy = _y[i3]-_y[i1];
+    if(dy==0.) {
+      x = (_x[i3]+_x[i1])/2.; // la fct a inverser est plate!
+    } else {
+      double X1=_x[i1]-_x[i2], X3=_x[i3]-_x[i2];
+      double Y1=_y[i1]-_y[i2], Y3=_y[i3]-_y[i2];
+      double den = Y1*Y3*dy;
+      double a = (X3*Y1-X1*Y3)/den;
+      double b = (X1*Y3*Y3-X3*Y1*Y1)/den;
+      y -= _y[i2];
+      x = (a*y+b)*y + _x[i2];
+    }
+    xfcty[i] = x;
+  }
+
+  return 0;
+}
+
+//----------------------------------------------------
+double InterpTab(double x0,vector<double>& X,vector<double>& Y,unsigned short typint)
+// Interpole in x0 the table Y = f(X)
+//           X doit etre ordonne par ordre croissant (strictement)
+// typint = 0 : nearest value
+//          1 : linear interpolation
+//          2 : parabolique interpolation
+{
+ long n = X.size();
+ if(n>(long)Y.size() || n<2)
+   throw ParmError("InterpTab_Error :  incompatible size between X and Y tables!");
+
+ if(x0<X[0] || x0>X[n-1]) return 0.;
+ if(typint>2) typint = 0;
+
+ // Recherche des indices encadrants par dichotomie
+ long k, klo=0, khi=n-1;
+ while (khi-klo > 1) {
+   k = (khi+klo) >> 1;
+   if (X[k] > x0) khi=k; else klo=k;
+ }
+
+ // Quel est le plus proche?
+ k = (x0-X[klo]<X[khi]-x0) ? klo: khi;
+
+ // On retourne le plus proche
+ if(typint==0) return Y[k];
+
+ // On retourne l'extrapolation lineaire
+ if(typint==1 || n<3)
+   return Y[klo] + (Y[khi]-Y[klo])/(X[khi]-X[klo])*(x0-X[klo]);
+
+ // On retourne l'extrapolation parabolique
+ if(k==0) k++; else if(k==n-1) k--;
+ klo = k-1; khi = k+1;
+ double x1 = X[klo]-X[k], x2 = X[khi]-X[k];
+ double y1 = Y[klo]-Y[k], y2 = Y[khi]-Y[k];
+ double den = x1*x2*(x1-x2);
+ double a = (y1*x2-y2*x1)/den;
+ double b = (y2*x1*x1-y1*x2*x2)/den;
+ x0 -= X[k];
+ return Y[k] + (a*x0+b)*x0;;
+
+}
+
+//-------------------------------------------------------------------
+int FuncToHisto(GenericFunc& func,Histo& h,bool logaxex)
+// Remplit l'histo 1D "h" avec la fonction "func"
+// INPUT:
+// logaxex = false : remplissage lineaire
+//        les abscisses "x" des bins sont remplis avec f(x)
+// logaxex = true : remplissage logarithmique (base 10)
+//        les abscisses "x" des bins sont remplis avec f(10^x)
+// RETURN:
+//       0 = OK
+//       1 = error
+{
+  if(h.NBins()<=0) return 1;
+
+  h.Zero();
+
+  for(int_4 i=0;i<h.NBins();i++) {
+    double x = h.BinCenter(i);
+    if(logaxex) x = pow(10.,x);
+    h.SetBin(i,func(x));
+  }
+
+  return 0;
+}
+
+int FuncToVec(GenericFunc& func,TVector<r_8>& v,double xmin,double xmax,bool logaxex)
+// Remplit le TVector avec la fonction "func"
+// INPUT:
+// logaxex = false : remplissage lineaire
+//        les abscisses "x" des bins sont remplis avec f(x)
+// logaxex = true : remplissage logarithmique (base 10)
+//        les abscisses "x" des bins sont remplis avec f(10^x)
+// RETURN:
+//       0 = OK
+//       1 = error
+// Remarque:
+//  v(i) = f(xmin+i*dx) avec dx = (xmax-xmin)/v.NElts()
+{
+  if(v.NElts()<=0 || xmax<=xmin) return 1;
+
+  v = 0.;
+  double dx = (xmax-xmin)/v.NElts();
+   
+  for(int_4 i=0;i<v.NElts();i++) {
+    double x = xmin + i * dx;;
+    if(logaxex) x = pow(10.,x);
+    v(i) = func(x);
+  }
+
+  return 0;
+}
+
+//-------------------------------------------------------------------
+double AngSol(double dtheta,double dphi,double theta0)
+// Retourne l'angle solide d'un "rectangle" et coordonnees spheriques
+// de DEMI-COTE "dtheta" x "dphi" et centre en "theta0"
+// Attention: Le "theta0" de l'equateur est Pi/2  (et non pas zero)
+//            Les unites des angles sont en radians
+//               theta0 in [0,Pi]
+//               dtheta in [0,Pi]
+//               dphi   in [0,2Pi]
+// Return: l'angle solide en steradian
+{
+  double theta1 = theta0-dtheta, theta2 = theta0+dtheta;
+  if(theta1<0.) theta1=0.;
+  if(theta2>M_PI) theta2=M_PI;
+
+  return   2.*dphi * (cos(theta1)-cos(theta2));
+}
+
+double AngSol(double dtheta)
+// Retourne l'angle solide d'une calotte spherique de demi-ouverture "dtheta"
+// Attention: Les unites des angles sont en radians
+//               dtheta in [0,Pi]
+// Return: l'angle solide en steradian
+// Approx pour theta petit: PI * theta^2
+{
+  return   2.*M_PI * (1.-cos(dtheta));
+}
+
+double FrAngSol(double angsol)
+// Retourne la demi-ouverture "dtheta" d'une calotte spherique d'angle solide "angsol"
+// Input: angle solide de la calotte spherique en steradians
+// Return: demi-ouverture de la calotte spherique en radians
+{
+  angsol = 1. - angsol/(2.*M_PI);
+  if(angsol<-1. || angsol>1.) return -1.;
+  return acos(angsol);
+}
+
+//-------------------------------------------------------------------
+
+static unsigned short IntegrateFunc_GlOrder = 0;
+static vector<double> IntegrateFunc_x;
+static vector<double> IntegrateFunc_w;
+
+///////////////////////////////////////////////////////////
+//************** Integration of Functions ***************//
+///////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////////////
+double IntegrateFunc(GenericFunc& func,double xmin,double xmax
+       ,double perc,double dxinc,double dxmax,unsigned short glorder)
+// --- Integration adaptative ---
+//     Integrate[func[x], {x,xmin,xmax}]
+// ..xmin,xmax are the integration limits
+// ..dxinc is the searching increment x = xmin+i*dxinc
+//         if <0  npt = int(|dxinc|)   (si<2 alors npt=100)
+//                et dxinc = (xmax-xmin)/npt
+// ..dxmax is the maximum possible increment (if dxmax<=0 no test)
+// ---
+// Partition de [xmin,xmax] en intervalles [x(i),x(i+1)]:
+// on parcourt [xmin,xmax] par pas de "dxinc" : x(i) = xmin + i*dxinc
+// on cree un intervalle [x(i),x(i+1)]
+//     - si |f[x(i+1)] - f[x(i)]| > perc*|f[[x(i)]|
+//     - si |x(i+1)-x(i)| >= dxmax  (si dxmax>0.)
+// Dans un intervalle [x(i),x(i+1)] la fonction est integree
+//   avec une methode de gauss-legendre d'ordre "glorder"
+{
+  double signe = 1.;
+  if(xmin>xmax) {double tmp=xmax; xmax=xmin; xmin=tmp; signe=-1.;}
+
+  if(glorder==0) glorder = 4;
+  if(perc<=0.) perc=0.1;
+  if(dxinc<=0.) {int n=int(-dxinc); if(n<2) n=100; dxinc=(xmax-xmin)/n;}
+  if(glorder != IntegrateFunc_GlOrder) {
+    IntegrateFunc_GlOrder = glorder;
+    Compute_GaussLeg(glorder,IntegrateFunc_x,IntegrateFunc_w,0.,1.);
+  }
+
+  // Recherche des intervalles [x(i),x(i+1)]
+  int_4 ninter = 0;
+  double sum = 0., xbas=xmin, fbas=func(xbas), fabsfbas=fabs(fbas);
+  for(double x=xmin+dxinc; x<xmax+dxinc/2.; x += dxinc) {
+    double f = func(x);
+    double dx = x-xbas;
+    bool doit = false;
+    if( x>xmax ) {doit = true; x=xmax;}
+    else if( dxmax>0. && dx>dxmax ) doit = true;
+    else if( fabs(f-fbas)>perc*fabsfbas ) doit = true;
+    if( ! doit ) continue;
+    double s = 0.;
+    for(unsigned short i=0;i<IntegrateFunc_GlOrder;i++)
+      s += IntegrateFunc_w[i]*func(xbas+IntegrateFunc_x[i]*dx);
+    sum += s*dx;
+    xbas = x; fbas = f; fabsfbas=fabs(fbas); ninter++;
+  }
+  //cout<<"Ninter="<<ninter<<endl;
+
+  return sum*signe;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+double IntegrateFuncLog(GenericFunc& func,double lxmin,double lxmax
+         ,double perc,double dlxinc,double dlxmax,unsigned short glorder)
+// --- Integration adaptative ---
+// Idem IntegrateFunc but integrate on logarithmic (base 10) intervals:
+//    Int[ f(x) dx ] = Int[ x*f(x) dlog10(x) ] * log(10)
+// ..lxmin,lxmax are the log10() of the integration limits
+// ..dlxinc is the searching logarithmic (base 10) increment lx = lxmin+i*dlxinc
+// ..dlxmax is the maximum possible logarithmic (base 10) increment (if dlxmax<=0 no test)
+// Remarque: to be use if "x*f(x) versus log10(x)" looks like a polynomial
+//            better than "f(x) versus x"
+// ATTENTION: la fonction func que l'on passe en argument
+//            est "func(x)" et non pas "func(log10(x))"
+{
+  double signe = 1.;
+  if(lxmin>lxmax) {double tmp=lxmax; lxmax=lxmin; lxmin=tmp; signe=-1.;}
+
+  if(glorder==0) glorder = 4;
+  if(perc<=0.) perc=0.1;
+  if(dlxinc<=0.) {int n=int(-dlxinc); if(n<2) n=100; dlxinc=(lxmax-lxmin)/n;}
+  if(glorder != IntegrateFunc_GlOrder) {
+    IntegrateFunc_GlOrder = glorder;
+    Compute_GaussLeg(glorder,IntegrateFunc_x,IntegrateFunc_w,0.,1.);
+  }
+
+  // Recherche des intervalles [lx(i),lx(i+1)]
+  int_4 ninter = 0;
+  double sum = 0., lxbas=lxmin, fbas=func(pow(10.,lxbas)), fabsfbas=fabs(fbas);
+  for(double lx=lxmin+dlxinc; lx<lxmax+dlxinc/2.; lx += dlxinc) {
+    double f = func(pow(10.,lx));
+    double dlx = lx-lxbas;
+    bool doit = false;
+    if( lx>lxmax ) {doit = true; lx=lxmax;}
+    else if( dlxmax>0. && dlx>dlxmax ) doit = true;
+    else if( fabs(f-fbas)>perc*fabsfbas ) doit = true;
+    if( ! doit ) continue;
+    double s = 0.;
+    for(unsigned short i=0;i<IntegrateFunc_GlOrder;i++) {
+      double y = pow(10.,lxbas+IntegrateFunc_x[i]*dlx);
+      s += IntegrateFunc_w[i]*y*func(y);
+    }
+    sum += s*dlx;
+    lxbas = lx; fbas = f; fabsfbas=fabs(fbas); ninter++;
+  }
+  //cout<<"Ninter="<<ninter<<endl;
+
+  return M_LN10*sum*signe;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+/*
+Integration des fonctions a une dimension y=f(x) par la Methode de Gauss-Legendre.
+  --> Calcul des coefficients du developpement pour [x1,x2]
+| INPUT:
+|  x1,x2 : bornes de l'intervalle (dans nbinteg.h -> x1=-0.5 x2=0.5)
+|  glorder = degre n du developpement de Gauss-Legendre
+| OUTPUT:
+|  x[] = valeur des abscisses ou l'on calcule (dim=n)
+|  w[] = valeur des coefficients associes
+| REMARQUES:
+|  - x et w seront dimensionnes 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) )
+*/
+void Compute_GaussLeg(unsigned short glorder,vector<double>& x,vector<double>& w,double x1,double x2)
+{
+  if(glorder==0) return;
+  int n = (int)glorder;
+  x.resize(n,0.); w.resize(n,0.);
+
+   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(M_PI*(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) > 3.0e-11);  // epsilon
+      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];
+   }
+}
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/geneutils.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/geneutils.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/geneutils.h	(revision 3445)
@@ -0,0 +1,101 @@
+#ifndef GENEUTILS_SEEN
+#define GENEUTILS_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include "genericfunc.h"
+#include "histos.h"
+#include "tvector.h"
+#include "cspline.h"
+
+#include <vector>
+
+namespace SOPHYA {
+
+//----------------------------------------------------
+class InterpFunc {
+public:
+  InterpFunc(double xmin,double xmax,vector<double>& y);
+  virtual ~InterpFunc(void) { }
+
+  double XMin(void) {return _xmin;}
+  double XMax(void) {return _xmax;}
+  inline double X(long i) {return _xmin + i*_dx;}
+
+  //! Retourne l'element le plus proche de f donnant y=f(x)
+  inline double operator()(double x)
+         {
+         x -= _xmin;
+         long i = long(x/_dx+0.5);  // On prend le "i" le plus proche
+         if(i<0) i=0; else if(i>=_nm1) i=_nm1-1;
+         return _y[i];
+         }
+
+  // idem operator(double) et retourne
+  // ok==0 si valeur trouvee, 1 si x<xmin, 2 si x>xmax
+  inline double operator()(double x,unsigned short& ok)
+    {ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2; return (*this)(x);}
+
+  //! Retourne l'interpolation lineaire de f donnant y=f(x)
+  // ok==0 si valeur trouvee, 1 si x<xmin, 2 si x>xmax
+  double Linear(double x,unsigned short& ok);
+
+  //! Retourne l'interpolation parabolique de f donnant y=f(x)
+  // ok==0 si valeur trouvee, 1 si x<xmin, 2 si x>xmax
+  double Parab(double x,unsigned short& ok);
+
+protected:
+  double _xmin,_xmax,_dx;
+  long _nm1;  // n-1
+  vector<double>& _y;
+};
+
+//----------------------------------------------------
+class InverseFunc {
+public:
+  InverseFunc(vector<double>& x,vector<double>& y);
+  virtual ~InverseFunc(void);
+  int ComputeLinear(long n,vector<double>& xfcty);
+  int ComputeParab(long n,vector<double>& xfcty);
+  double YMin(void) {return _ymin;}
+  double YMax(void) {return _ymax;}
+protected:
+  inline void find_in_y(double x,long& klo,long& khi)
+    {
+      long k;
+      klo=0, khi=_y.size()-1;
+      while (khi-klo > 1) {
+	k = (khi+klo) >> 1;
+	if (_y[k] > x) khi=k; else klo=k;
+      }
+    }
+
+  double _ymin,_ymax;
+  vector<double>& _x;
+  vector<double>& _y;
+};
+
+//----------------------------------------------------
+double InterpTab(double x0,vector<double>& X,vector<double>& Y,unsigned short typint=0);
+
+//----------------------------------------------------
+int FuncToHisto(GenericFunc& func,Histo& h,bool logaxex=false);
+int FuncToVec(GenericFunc& func,TVector<r_8>& h,double xmin,double xmax,bool logaxex=false);
+
+//----------------------------------------------------
+double AngSol(double dtheta,double dphi,double theta0=M_PI/2.);
+double AngSol(double dtheta);
+double FrAngSol(double angsol);
+
+//----------------------------------------------------
+double IntegrateFunc(GenericFunc& func,double xmin,double xmax
+         ,double perc=0.1,double dxinc=-1.,double dxmax=-1.,unsigned short glorder=4);
+
+double IntegrateFuncLog(GenericFunc& func,double lxmin,double lxmax
+         ,double perc=0.1,double dlxinc=-1.,double dlxmax=-1.,unsigned short glorder=4);
+
+void Compute_GaussLeg(unsigned short glorder,vector<double>& x,vector<double>& w,double x1=0.,double x2=1.);
+
+}  // Fin namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/hu_power.c
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/hu_power.c	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/hu_power.c	(revision 3445)
@@ -0,0 +1,274 @@
+/* Fitting Formulae for CDM + Baryon + Massive Neutrino (MDM) cosmologies. */
+/* Daniel J. Eisenstein & Wayne Hu, Institute for Advanced Study */
+
+/* There are two primary routines here, one to set the cosmology, the
+other to construct the transfer function for a single wavenumber k. 
+You should call the former once (per cosmology) and the latter as 
+many times as you want. */
+
+/* TFmdm_set_cosm() -- User passes all the cosmological parameters as
+	arguments; the routine sets up all of the scalar quantites needed 
+	computation of the fitting formula.  The input parameters are: 
+	1) omega_matter -- Density of CDM, baryons, and massive neutrinos,
+				in units of the critical density. 
+	2) omega_baryon -- Density of baryons, in units of critical. 
+	3) omega_hdm    -- Density of massive neutrinos, in units of critical 
+	4) degen_hdm    -- (Int) Number of degenerate massive neutrino species 
+	5) omega_lambda -- Cosmological constant 
+	6) hubble       -- Hubble constant, in units of 100 km/s/Mpc 
+	7) redshift     -- The redshift at which to evaluate */
+
+/* TFmdm_onek_mpc() -- User passes a single wavenumber, in units of Mpc^-1.
+	Routine returns the transfer function from the Eisenstein & Hu
+	fitting formula, based on the cosmology currently held in the 
+	internal variables.  The routine returns T_cb (the CDM+Baryon
+	density-weighted transfer function), although T_cbn (the CDM+
+	Baryon+Neutrino density-weighted transfer function) is stored
+	in the global variable tf_cbnu. */
+
+/* We also supply TFmdm_onek_hmpc(), which is identical to the previous
+	routine, but takes the wavenumber in units of h Mpc^-1. */
+
+/* We hold the internal scalar quantities in global variables, so that
+the user may access them in an external program, via "extern" declarations. */
+
+/* Please note that all internal length scales are in Mpc, not h^-1 Mpc! */
+
+/* -------------------------- Prototypes ----------------------------- */
+
+int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
+	int degen_hdm, double omega_lambda, double hubble, double redshift);
+double TFmdm_onek_mpc(double kk);
+double TFmdm_onek_hmpc(double kk);
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Convenience from Numerical Recipes in C, 2nd edition
+------------ COMPLETEMENT DEBILE (cmv) ????????? ------------
+static double sqrarg;
+#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
+*/
+#define SQR(a) (a*a)
+
+/* ------------------------- Global Variables ------------------------ */
+
+/* The following are set in TFmdm_set_cosm() */
+double   alpha_gamma,	/* sqrt(alpha_nu) */
+	alpha_nu,	/* The small-scale suppression */
+	beta_c,		/* The correction to the log in the small-scale */
+	num_degen_hdm,	/* Number of degenerate massive neutrino species */
+	f_baryon,	/* Baryon fraction */
+	f_bnu,		/* Baryon + Massive Neutrino fraction */
+	f_cb,		/* Baryon + CDM fraction */
+	f_cdm,		/* CDM fraction */
+	f_hdm,		/* Massive Neutrino fraction */
+	growth_k0,	/* D_1(z) -- the growth function as k->0 */
+	growth_to_z0,	/* D_1(z)/D_1(0) -- the growth relative to z=0 */
+	hhubble,	/* Need to pass Hubble constant to TFmdm_onek_hmpc() */
+	k_equality,	/* The comoving wave number of the horizon at equality*/
+	obhh,		/* Omega_baryon * hubble^2 */
+	omega_curv,	/* = 1 - omega_matter - omega_lambda */
+	omega_lambda_z, /* Omega_lambda at the given redshift */
+	omega_matter_z,	/* Omega_matter at the given redshift */
+	omhh,		/* Omega_matter * hubble^2 */
+	onhh,		/* Omega_hdm * hubble^2 */
+	p_c,		/* The correction to the exponent before drag epoch */
+	p_cb,		/* The correction to the exponent after drag epoch */
+	sound_horizon_fit,  /* The sound horizon at the drag epoch */
+	theta_cmb,	/* The temperature of the CMB, in units of 2.7 K */
+	y_drag,		/* Ratio of z_equality to z_drag */
+	z_drag,		/* Redshift of the drag epoch */
+	z_equality;	/* Redshift of matter-radiation equality */
+
+/* The following are set in TFmdm_onek_mpc() */
+double	gamma_eff,	/* Effective \Gamma */
+	growth_cb,	/* Growth factor for CDM+Baryon perturbations */
+	growth_cbnu,	/* Growth factor for CDM+Baryon+Neutrino pert. */
+	max_fs_correction,  /* Correction near maximal free streaming */
+	qq,		/* Wavenumber rescaled by \Gamma */
+	qq_eff,		/* Wavenumber rescaled by effective Gamma */
+	qq_nu,		/* Wavenumber compared to maximal free streaming */
+	tf_master,	/* Master TF */
+	tf_sup,		/* Suppressed TF */
+	y_freestream; 	/* The epoch of free-streaming for a given scale */
+
+/* Finally, TFmdm_onek_mpc() and TFmdm_onek_hmpc() give their answers as */
+double   tf_cb,		/* The transfer function for density-weighted
+			CDM + Baryon perturbations. */
+	tf_cbnu;	/* The transfer function for density-weighted
+			CDM + Baryon + Massive Neutrino perturbations. */
+
+/* By default, these functions return tf_cb */
+
+/* ------------------------- TFmdm_set_cosm() ------------------------ */
+int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
+	int degen_hdm, double omega_lambda, double hubble, double redshift)
+/* This routine takes cosmological parameters and a redshift and sets up
+all the internal scalar quantities needed to compute the transfer function. */
+/* INPUT: omega_matter -- Density of CDM, baryons, and massive neutrinos,
+				in units of the critical density. */
+/* 	  omega_baryon -- Density of baryons, in units of critical. */
+/* 	  omega_hdm    -- Density of massive neutrinos, in units of critical */
+/* 	  degen_hdm    -- (Int) Number of degenerate massive neutrino species */
+/*        omega_lambda -- Cosmological constant */
+/* 	  hubble       -- Hubble constant, in units of 100 km/s/Mpc */
+/*        redshift     -- The redshift at which to evaluate */
+/* OUTPUT: Returns 0 if all is well, 1 if a warning was issued.  Otherwise,
+	sets many global variables for use in TFmdm_onek_mpc() */
+{
+    double z_drag_b1, z_drag_b2, omega_denom;
+    int qwarn;
+    qwarn = 0;
+
+    theta_cmb = 2.728/2.7;	/* Assuming T_cmb = 2.728 K */
+
+    /* Look for strange input */
+    if (omega_baryon<0.0) {
+	fprintf(stderr,
+	  "TFmdm_set_cosm(): Negative omega_baryon set to trace amount.\n");
+	qwarn = 1;
+    }
+    if (omega_hdm<0.0) {
+	fprintf(stderr,
+	  "TFmdm_set_cosm(): Negative omega_hdm set to trace amount.\n");
+	qwarn = 1;
+    }
+    if (hubble<=0.0) {
+	fprintf(stderr,"TFmdm_set_cosm(): Negative Hubble constant illegal.\n");
+	exit(1);  /* Can't recover */
+    } else if (hubble>2.0) {
+	fprintf(stderr,"TFmdm_set_cosm(): Hubble constant should be in units of 100 km/s/Mpc.\n");
+	qwarn = 1;
+    }
+    if (redshift<=-1.0) {
+	fprintf(stderr,"TFmdm_set_cosm(): Redshift < -1 is illegal.\n");
+	exit(1);
+    } else if (redshift>99.0) {
+	fprintf(stderr,
+	  "TFmdm_set_cosm(): Large redshift entered.  TF may be inaccurate.\n");
+	qwarn = 1;
+    }
+    if (degen_hdm<1) degen_hdm=1;
+    num_degen_hdm = (double) degen_hdm;	
+	/* Have to save this for TFmdm_onek_mpc() */
+    /* This routine would crash if baryons or neutrinos were zero, 
+	so don't allow that */
+    if (omega_baryon<=0) omega_baryon=1e-5;
+    if (omega_hdm<=0) omega_hdm=1e-5;
+
+    omega_curv = 1.0-omega_matter-omega_lambda;
+    omhh = omega_matter*SQR(hubble);
+    obhh = omega_baryon*SQR(hubble);
+    onhh = omega_hdm*SQR(hubble);
+    f_baryon = omega_baryon/omega_matter;
+    f_hdm = omega_hdm/omega_matter;
+    f_cdm = 1.0-f_baryon-f_hdm;
+    f_cb = f_cdm+f_baryon;
+    f_bnu = f_baryon+f_hdm;
+
+    /* Compute the equality scale. */
+    z_equality = 25000.0*omhh/SQR(SQR(theta_cmb));	/* Actually 1+z_eq */
+    k_equality = 0.0746*omhh/SQR(theta_cmb);
+
+    /* Compute the drag epoch and sound horizon */
+    z_drag_b1 = 0.313*pow(omhh,-0.419)*(1+0.607*pow(omhh,0.674));
+    z_drag_b2 = 0.238*pow(omhh,0.223);
+    z_drag = 1291*pow(omhh,0.251)/(1.0+0.659*pow(omhh,0.828))*
+		(1.0+z_drag_b1*pow(obhh,z_drag_b2));
+    y_drag = z_equality/(1.0+z_drag);
+
+    sound_horizon_fit = 44.5*log(9.83/omhh)/sqrt(1.0+10.0*pow(obhh,0.75));
+
+    /* Set up for the free-streaming & infall growth function */
+    p_c = 0.25*(5.0-sqrt(1+24.0*f_cdm));
+    p_cb = 0.25*(5.0-sqrt(1+24.0*f_cb));
+
+    omega_denom = omega_lambda+SQR(1.0+redshift)*(omega_curv+
+			omega_matter*(1.0+redshift));
+    omega_lambda_z = omega_lambda/omega_denom;
+    omega_matter_z = omega_matter*SQR(1.0+redshift)*(1.0+redshift)/omega_denom;
+    growth_k0 = z_equality/(1.0+redshift)*2.5*omega_matter_z/
+	    (pow(omega_matter_z,4.0/7.0)-omega_lambda_z+
+	    (1.0+omega_matter_z/2.0)*(1.0+omega_lambda_z/70.0));
+    growth_to_z0 = z_equality*2.5*omega_matter/(pow(omega_matter,4.0/7.0)
+	    -omega_lambda + (1.0+omega_matter/2.0)*(1.0+omega_lambda/70.0));
+    growth_to_z0 = growth_k0/growth_to_z0;	
+    
+    /* Compute small-scale suppression */
+    alpha_nu = f_cdm/f_cb*(5.0-2.*(p_c+p_cb))/(5.-4.*p_cb)*
+	pow(1+y_drag,p_cb-p_c)*
+	(1+f_bnu*(-0.553+0.126*f_bnu*f_bnu))/
+	(1-0.193*sqrt(f_hdm*num_degen_hdm)+0.169*f_hdm*pow(num_degen_hdm,0.2))*
+	(1+(p_c-p_cb)/2*(1+1/(3.-4.*p_c)/(7.-4.*p_cb))/(1+y_drag));
+    alpha_gamma = sqrt(alpha_nu);
+    beta_c = 1/(1-0.949*f_bnu);
+    /* Done setting scalar variables */
+    hhubble = hubble;	/* Need to pass Hubble constant to TFmdm_onek_hmpc() */
+    return qwarn;
+}
+
+/* ---------------------------- TFmdm_onek_mpc() ---------------------- */
+
+double TFmdm_onek_mpc(double kk)
+/* Given a wavenumber in Mpc^-1, return the transfer function for the
+cosmology held in the global variables. */
+/* Input: kk -- Wavenumber in Mpc^-1 */
+/* Output: The following are set as global variables:
+	growth_cb -- the transfer function for density-weighted
+			CDM + Baryon perturbations. 
+ 	growth_cbnu -- the transfer function for density-weighted
+			CDM + Baryon + Massive Neutrino perturbations. */
+/* The function returns growth_cb */
+{
+    double tf_sup_L, tf_sup_C;
+    double temp1, temp2;
+
+    qq = kk/omhh*SQR(theta_cmb);
+
+    /* Compute the scale-dependent growth functions */
+    y_freestream = 17.2*f_hdm*(1+0.488*pow(f_hdm,-7.0/6.0))*
+		SQR(num_degen_hdm*qq/f_hdm);
+    temp1 = pow(growth_k0, 1.0-p_cb);
+    temp2 = pow(growth_k0/(1+y_freestream),0.7);
+    growth_cb = pow(1.0+temp2, p_cb/0.7)*temp1;
+    growth_cbnu = pow(pow(f_cb,0.7/p_cb)+temp2, p_cb/0.7)*temp1;
+
+    /* Compute the master function */
+    gamma_eff =omhh*(alpha_gamma+(1-alpha_gamma)/
+		(1+SQR(SQR(kk*sound_horizon_fit*0.43))));
+    qq_eff = qq*omhh/gamma_eff;
+
+    tf_sup_L = log(2.71828+1.84*beta_c*alpha_gamma*qq_eff);
+    tf_sup_C = 14.4+325/(1+60.5*pow(qq_eff,1.11));
+    tf_sup = tf_sup_L/(tf_sup_L+tf_sup_C*SQR(qq_eff));
+
+    qq_nu = 3.92*qq*sqrt(num_degen_hdm/f_hdm);
+    max_fs_correction = 1+1.2*pow(f_hdm,0.64)*pow(num_degen_hdm,0.3+0.6*f_hdm)/
+		(pow(qq_nu,-1.6)+pow(qq_nu,0.8));
+    tf_master = tf_sup*max_fs_correction;
+
+    /* Now compute the CDM+HDM+baryon transfer functions */
+    tf_cb = tf_master*growth_cb/growth_k0;
+    tf_cbnu = tf_master*growth_cbnu/growth_k0;
+    return tf_cb;
+}
+
+/* ---------------------------- TFmdm_onek_hmpc() ---------------------- */
+
+double TFmdm_onek_hmpc(double kk)
+/* Given a wavenumber in h Mpc^-1, return the transfer function for the
+cosmology held in the global variables. */
+/* Input: kk -- Wavenumber in h Mpc^-1 */
+/* Output: The following are set as global variables:
+	growth_cb -- the transfer function for density-weighted
+			CDM + Baryon perturbations. 
+ 	growth_cbnu -- the transfer function for density-weighted
+			CDM + Baryon + Massive Neutrino perturbations. */
+/* The function returns growth_cb */
+{
+    return TFmdm_onek_mpc(kk*hhubble);
+}
+
+
Index: /tags/V_Nov2007/Cosmo/SimLSS/hu_power.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/hu_power.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/hu_power.h	(revision 3445)
@@ -0,0 +1,17 @@
+#ifndef HU_POWER_SEEN
+#define HU_POWER_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
+	int degen_hdm, double omega_lambda, double hubble, double redshift);
+double TFmdm_onek_mpc(double kk);
+double TFmdm_onek_hmpc(double kk);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HU_POWER_SEEN
Index: /tags/V_Nov2007/Cosmo/SimLSS/hu_sigma8.c
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/hu_sigma8.c	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/hu_sigma8.c	(revision 3445)
@@ -0,0 +1,526 @@
+/* Code to calculate sigma8 for COBE-normalized CDM and MDM models, 
+using the approximation of Eisenstein & Hu (1997). */
+
+/* This code will calculate sigma_8 and other quantities for CDM and
+MDM models.  Because the fitting form for the transfer function does not
+include the baryon oscillations, the answer will not be accurate for
+large baryon fractions.  The COBE normalization is from the papers
+on Bunn & White (1997) and Hu & White (1997). */
+
+/* Accuracy is generally better than 5%.  Recall that the COBE normalization
+is only 7% accurate (1-sigma).  This program gives low answers compared to
+CMBfast for lower values of Omega_0*h^2, and vice versa for higher values. 
+Values of Omega_0 near 0.2 can produce answers that are 5% low. */
+
+/* The integrator used here is a bit crude, but suffices for rapid
+10^-3 accuracy.  You could get better performance by substituting an
+integrator from a numerical package.  See the end of the file for details. */
+
+/* This program uses the routines TFmdm_set_cosm() and TFmdm_onek_hmpc(),
+available from http://www.sns.ias.edu/~whu/power/power.html in the file
+power.c.  To compile this program, you'll need that file as well, e.g.
+	cc -O sigma8.c power.c -o sigma8 -lm 		*/
+
+/* Lists of versions and bugs:
+v1.0 -- 10/23/97 -- Original release version.
+v1.1 -- 11/13/97 -- We correct a missing factor of omega_m in the
+		    conversion between mass and length scales [lines
+		    32 and 34 of main()].  This only affects the results 
+		    if you explicitly used the -mass option.
+v1.2 -- 04/08/98 -- We correct a typo in the second-order tilt scaling
+		    of the COBE normalization for flat models with tensors.
+v1.3 -- 09/15/98 -- We correct a typo in the tilt scaling of the COBE
+		    normalization for open models with tensors.
+v1.4 -- 12/02/98 -- We correct the COBE normalization for tilted open models,
+		    undoing the change of v1.3 and fixing what was
+		    wrong there to begin with.
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
+	int degen_hdm, double omega_lambda, double hubble, double redshift);
+double TFmdm_onek_hmpc(double kk);
+
+double sig2tophat(double x);
+double sig2gauss(double x);
+double sig2sharpk(double x);
+double sig2tophatnu(double x);
+double sig2gaussnu(double x);
+double sig2sharpknu(double x);
+
+#define WEIRD  -2538	/* A strange number, unlikely to be entered */
+#define RHOCRIT 2.78e11	/* The critical density, for h=1, in Msun/Mpc^3 */
+
+/* Convenience from Numerical Recipes in C, 2nd edition
+------------ COMPLETEMENT DEBILE (cmv) ????????? ------------
+static double sqrarg;
+#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
+*/
+#define SQR(a) (a*a)
+
+/* Global variable */
+double   omega_m, omega_b, omega_n, 
+	numdegen, lambda, redshift, 
+	hubble, scale, mass, tilt;
+double   deltaH;		/* COBE-normalization */
+double   sig2_scale;	/* For passing a length scale to the integrator */
+int 	qtensors, quiet, qredshift;
+
+/* ========================== User interaction routines ============== */
+void usage()
+/* Print out information about the allowed options and then quit. */
+{
+    fprintf(stderr,"Command line options:\n");
+    fprintf(stderr,"-om or -omega <omega_matter, including CDM, baryons, massive neutrinos>\n");
+    fprintf(stderr,"-ob <omega_baryon> -fb <baryon_fraction>\n");
+    fprintf(stderr,"-on <omega_neutrino> -fn <neutrino_fraction>\n");
+    fprintf(stderr,"-numdegen or -Nnu <number of degenerate neutrino species>, default 1\n");
+    fprintf(stderr,"-lambda <omega_lambda> -flat (choose lambda appropriately)\n");
+    fprintf(stderr,"-h or -hubble <H_0, units of 100 km/s/Mpc>\n");
+    fprintf(stderr,"-H or -Hubble <H_0, units of 1 km/s/Mpc>\n");
+    fprintf(stderr,"-tilt or -n <scalar spectral tilt>, no tensors.\n");
+    fprintf(stderr,"-Tilt or -N <scalar spectral tilt>, power-law tensors.\n");
+    fprintf(stderr,"-z <redshift>, if none given then appropriate value assumed.\n");
+    fprintf(stderr,"The following request the rms fluctuations inside a tophat window function:\n");
+    fprintf(stderr,"-scale <comoving length scale, h^-1 Mpc>\n");
+    fprintf(stderr,"-mass <mass scale, h^-1 Msun>\n");
+    fprintf(stderr,"If neither -scale or -mass is given, sigma_8 and other quantities are computed.\n");
+    fprintf(stderr,"-quiet (print only answer to stdout)\n");
+    exit(1);
+    return;
+}
+
+void crash(char *s)
+{
+    fprintf(stderr,"%s\n", s); exit(1); return;
+}
+
+void warn(char *s)
+{
+    fprintf(stderr,"%s\n", s); return;
+}
+
+
+void parse_command_line(int argc, char *argv[])
+/* Parse the command line, and look for illegal entries */
+{
+    int i;
+    if (argc==1) usage();
+    i = 1;
+    omega_m = 1.0;
+    omega_b = 0.05;
+    omega_n = 0.0;
+    numdegen = 1.0;
+    lambda = 0.0;
+    redshift = 0.0;
+    hubble = 0.5;
+    scale = -1.0;
+    mass = -1.0;
+    qtensors = 0;
+    quiet = 0;
+    tilt = 1.0;
+    qredshift = 0;
+
+    while (i<argc) {
+	if (!strcmp(argv[i],"-om")||!strcmp(argv[i],"-omega")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&omega_m); ++i;
+	} else if (!strcmp(argv[i],"-ob")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&omega_b); ++i;
+	} else if (!strcmp(argv[i],"-fb")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&omega_b); ++i;
+	    omega_b *= -1.0;	/* Signal that a fraction was desired */
+	} else if (!strcmp(argv[i],"-on")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&omega_n); ++i;
+	} else if (!strcmp(argv[i],"-fn")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&omega_n); ++i;
+	    omega_n *= -1.0;	/* Signal that a fraction was desired */
+	} else if (!strcmp(argv[i],"-h")||!strcmp(argv[i],"-hubble")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&hubble); ++i;
+	} else if (!strcmp(argv[i],"-H")||!strcmp(argv[i],"-Hubble")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&hubble); ++i;
+	    hubble /= 100.0;	/* Units were 1 km/s/Mpc */
+	} else if (!strcmp(argv[i],"-lambda")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&lambda); ++i;
+	} else if (!strcmp(argv[i],"-flat")) {
+	    ++i;
+	    lambda = WEIRD;
+	} else if (!strcmp(argv[i],"-numdegen")||!strcmp(argv[i],"-Nnu")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&numdegen); ++i;
+	} else if (!strcmp(argv[i],"-n")||!strcmp(argv[i],"-tilt")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&tilt); ++i;
+	    qtensors = 0;
+	} else if (!strcmp(argv[i],"-N")||!strcmp(argv[i],"-Tilt")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&tilt); ++i;
+	    qtensors = 1;
+	} else if (!strcmp(argv[i],"-z")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&redshift); ++i;
+	    qredshift = 1;
+	} else if (!strcmp(argv[i],"-scale")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&scale); ++i;
+	} else if (!strcmp(argv[i],"-mass")) {
+	    ++i;
+	    if (i>=argc) usage();
+	    sscanf(argv[i],"%lf",&mass); ++i;
+	} else if (!strcmp(argv[i],"-quiet")) {
+	    ++i;
+	    quiet = 1;
+	} else usage();
+    }
+
+    /* Look for illegal entries */
+    if (omega_m<=0.0) crash("Omega must be positive.");
+    if (hubble<=0.0) crash("Hubble constant must be positive.");
+	else if (hubble>10.0) warn("Did you get the Hubble units right?");
+    if (numdegen<0) {
+	warn("Negative number of degenerate species reset to 1.");
+	numdegen = 1.0;
+    }
+    if (redshift<=-1.0) crash("Redshift must exceed -1.");
+    if (scale>0.0 && mass>0.0) {
+	warn("Input length OR mass scale.  Defaulting to length.");
+	mass = -1.0;
+    }
+
+    /* Now look for fractions, if they were input. */
+    if (omega_b<0.0) omega_b = omega_m*(-omega_b);	
+    if (omega_n<0.0) omega_n = omega_m*(-omega_n);	
+    if (lambda== WEIRD) lambda = 1-omega_m;	/* Set to be flat */
+
+    if (omega_b+omega_n>omega_m) crash("Baryons + Neutrinos exceeds Omega_0.");
+	else if (omega_b+omega_n>0.6*omega_m) 
+	    warn("CDM fraction is below range of TF fitting formula.");
+    if (tilt>1.3 || tilt < 0.7) 
+	warn("Tilt out of range of Bunn and White fitting formula.");
+    if (tilt!=1 && (omega_m<0.2 || omega_m>1.0)) 
+	warn("Omega out of range of Bunn and White fitting formula.");
+    if (tilt==1 && (omega_m<0.2 || omega_m>1.6 || lambda<0.0 || lambda>0.8))
+	warn("Omega or Lambda out of range of Bunn and White fitting formula.");
+    if (qtensors!=0&&(tilt>1.0||
+	(fabs(lambda)>1e-5&&fabs(1.0-omega_m-lambda)>1e-5))) 
+	crash("Tensor formulae only hold for tilts < 1 and simple cosmologies.");
+    if (omega_b/omega_m>0.4) warn("Baryon oscillations will be large.  TF fitting form will be inaccurate.");
+    if (omega_n/omega_m>0.4) warn("Neutrino fraction outside of range of TF fitting form.");
+    if (omega_m*hubble*hubble>0.4) warn("Omega_0 h^2 outside of range of TF fitting form.");
+    if (omega_m*hubble*hubble<0.06) warn("Omega_0 h^2 outside of range of TF fitting form.");
+    if (redshift>29) warn("Redshift is higher than range of TF fitting form.");
+
+    return;
+}
+
+/* ==================================== MAIN() ========================= */
+
+void main(int argc, char *argv[])
+{
+    double erfcc(double x);
+    double sigma, sigma8;
+    extern double growth_to_z0, z_equality, alpha_nu, beta_c;
+    double cobenorm();
+    double integrate(double (*func)(double));
+    parse_command_line(argc, argv);
+
+    /* Set all the background quantities */
+    TFmdm_set_cosm(omega_m, omega_b, omega_n, (int) numdegen, lambda, 
+			hubble, redshift);
+    deltaH = cobenorm();
+
+    if (!quiet) {	/* Echo cosmological information to the screen */
+	printf("Omega_0  = %5.3f, Omega_baryon = %5.3f, Omega_neutrino = %5.3f\n",
+		omega_m, omega_b, omega_n);
+	printf("Hubble   = %5.3f, Lambda       = %5.3f, N_neutrinos    = %d\n",
+		hubble, lambda, (int) numdegen);
+	printf("Redshift = %5.3f, Growth = %6.4f relative to z=0\n",
+		redshift, growth_to_z0);
+	printf("Tilt     = %5.3f, COBE normalization: deltaH = %8.3e",
+		tilt, deltaH);
+	if (tilt!=1.0) 
+	    if (qtensors) printf(" with tensors.\n");
+	    else printf(" without tensors.\n");
+	else printf("\n");
+    }
+    /* If we've been asked to compute for a particular scale, do that */
+    if (scale>0 || mass>0) {
+	if (mass<0)
+	    mass = 4.0*M_PI/3.0*omega_m*RHOCRIT*scale*scale*scale;
+	else if (scale<0) 
+	    scale = pow(3.0/4.0/M_PI/RHOCRIT/omega_m*mass, 1.0/3.0);
+	/* Integrate tophat for the given scale */
+	sig2_scale = scale;
+	sigma = sqrt(integrate(sig2tophatnu));
+
+	/* Print out the result */
+	if (!quiet) printf("For length scale %6.4f h^-1 Mpc, mass scale %8.3e h^-1 Msun.\nrms tophat fluctuations are ",
+		sig2_scale, mass);
+	printf("%6.4f\n", sigma);
+    } else {	
+	/* No scale was requested, so we do the standard tasks */
+	/* Calculate sigma_8 */
+	sig2_scale = 8.0;	
+	sigma8 = sqrt(integrate(sig2tophatnu));
+	if (quiet) {
+	    printf("%6.4f\n", sigma8);
+	    return;	/* This is all we're doing */
+	}
+	printf("Sigma_8  = %6.4f\n", sigma8);
+
+	/* Calculate sigma_50 */
+	sig2_scale = 50.0;
+	sigma = sqrt(integrate(sig2tophatnu));
+	printf("Sigma_50 = %6.4f   Sigma_50/sigma_8 = %6.4f\n",
+		sigma, sigma/sigma8);
+
+	/* We default to z=4 for DLA */
+	if (!qredshift) {
+	    redshift = 4.0;		
+	    TFmdm_set_cosm(omega_m, omega_b, omega_n, (int) numdegen, lambda, 
+			hubble, redshift);
+	}
+	sig2_scale = 50.0/100.0/sqrt(1+redshift)/sqrt(2*3.14159)*
+		pow(8.0*3.14159/3.0/sqrt(89.0),1./3.);
+	sigma = sqrt(integrate(sig2gaussnu));
+	printf("Omega_gas = %8.3e at redshift %5.3f due to \n   sigma(50 km/s) = sigma(%5.3f h^-1 Mpc) = %6.4f (DLA, Klypin et al. 1994)\n", 
+	    omega_b*erfcc(1.33/1.414/sigma), redshift, sig2_scale, sigma);
+
+	/* We default to z=3 for Lyman alpha forest */
+	if (!qredshift) {
+	    redshift = 3.0;		
+	    TFmdm_set_cosm(omega_m, omega_b, omega_n, (int) numdegen, lambda, 
+			hubble, redshift);
+	}
+	sig2_scale = 1.0/(34.0*sqrt(omega_m/2.0));	/* Gnedin's k_34 */
+	sigma = sqrt(integrate(sig2gauss));
+	printf("Sigma_Lya = %6.4f at redshift %5.3f (Ly-alpha forest, Gnedin 1997)\n", 
+		sigma, redshift);
+
+	printf("Small-scale: alpha_nu = %6.4f, beta_c = %6.4f\n", 
+		alpha_nu, beta_c);
+    }
+    return;
+}
+
+/* ========================== Integration Kernals ======================= */
+
+double W2tophat(double x)
+/* The square of the tophat window */
+{
+    double j1onx;
+    if (x<0.03) 
+	j1onx = (1.0/3.0-x*x*1.0/30.0);
+    else j1onx = (cos(x)-sin(x)/x)/x/x;
+    return 9.0*j1onx*j1onx;
+}
+
+double sig2tophat(double x)
+/* This is the integrand for the mass fluctuation integral
+sig2 = \int_0^\infty (dk/k) Delta^2(k) W^2(kr)
+broken and recombined so that one integrates on (0,1] in a new variable x. */
+/* Here, the window is a real-space tophat of radius sig2_scale, the
+latter being passed from outside in units of h^-1 Mpc */
+{
+    double powerspcb(double k);
+    return (powerspcb(x/sig2_scale)*W2tophat(x)+
+ 	    powerspcb(1.0/x/sig2_scale)*W2tophat(1.0/x))/x;
+}
+
+double sig2tophatnu(double x)
+/* Same as sig2tophat(), but with P_cbnu */
+{
+    double powerspcbnu(double k);
+    return (powerspcbnu(x/sig2_scale)*W2tophat(x)+
+ 	    powerspcbnu(1.0/x/sig2_scale)*W2tophat(1.0/x))/x;
+}
+
+double sig2gauss(double x)
+/* This is the integrand for the mass fluctuation integral
+sig2 = \int_0^\infty (dk/k) Delta^2(k) W^2(kr)
+broken and recombined so that one integrates on (0,1] in a new variable x. */
+/* Here, the window is a gaussian of radius sig2_scale, the
+latter being passed from outside in units of h^-1 Mpc */
+{
+    double powerspcb(double k);
+    return (powerspcb(x/sig2_scale)*exp(-x*x)+
+ 	    powerspcb(1.0/x/sig2_scale)*exp(-1.0/x/x))/x;
+}
+
+double sig2gaussnu(double x)
+/* Same as sig2gauss(), but with P_cbnu */
+{
+    double powerspcbnu(double k);
+    return (powerspcbnu(x/sig2_scale)*exp(-x*x)+
+ 	    powerspcbnu(1.0/x/sig2_scale)*exp(-1.0/x/x))/x;
+}
+
+double sig2sharpk(double x)
+/* This is the integrand for the mass fluctuation integral
+sig2 = \int_0^\infty (dk/k) Delta^2(k) W^2(kr)
+broken and recombined so that one integrates on (0,1] in a new variable x. */
+/* Here, the window is a k-space tophat of radius 1/sig2_scale, the
+latter being passed from outside in units of h^-1 Mpc */
+{
+    double powerspcb(double k);
+    return (powerspcb(x/sig2_scale))/x;
+}
+
+double sig2sharpknu(double x)
+/* Same as sig2sharpk(), but with P_cbnu */
+{
+    double powerspcbnu(double k);
+    return (powerspcbnu(x/sig2_scale))/x;
+}
+
+/* ============================ Power Spectrum and COBE ================ */
+double powerspcbnu(double k)
+/* Returns Delta^2(k), COBE-normalized, based on the approximations of 
+Eisenstein & Hu (1997).  k is in h^-1 Mpc. */
+/* TFmdm_set_cosm() and cobenorm() must have been called before this */
+/* Returns the density-weighted CDM+Baryon+Neutrino power spectrum */
+{
+    extern double tf_cbnu, growth_to_z0;
+    TFmdm_onek_hmpc(k);  /* This sets the value in tf_cbnu */
+    return pow(2997.0*k, tilt+3.0)*SQR(deltaH*tf_cbnu*growth_to_z0);
+}
+
+double powerspcb(double k)
+/* Returns Delta^2(k), COBE-normalized, based on the approximations of 
+Eisenstein & Hu (1997).  k is in h^-1 Mpc. */
+/* TFmdm_set_cosm() and cobenorm() must have been called before this */
+/* Returns the density-weighted CDM+Baryon power spectrum */
+{
+    extern double growth_to_z0;
+    return pow(2997.0*k, tilt+3.0)*SQR(deltaH*TFmdm_onek_hmpc(k)*growth_to_z0); 
+}
+
+double cobenorm()
+/* Return the Bunn & White (1997) fit for delta_H */
+/* Given lambda, omega_m, qtensors, and tilt */
+/* Open model with tensors is from Hu & White */
+{
+    double n;
+    n = tilt-1;
+    if (fabs(omega_m+lambda-1.0)<1e-5) {	/* Flat universe */
+	if (qtensors) 
+	    return 1.94e-5*pow(omega_m, -0.785-0.05*log(omega_m))*
+		exp(n+1.97*n*n);
+	else return 1.94e-5*pow(omega_m, -0.785-0.05*log(omega_m))*
+		exp(-0.95*n-0.169*n*n);
+	/* Error -- was 0.0169 in earlier version of code */
+    } else if (fabs(lambda)<1e-5) {	/* No lambda */
+	if (qtensors)
+	    return 1.95e-5*pow(omega_m,-0.35-0.19*log(omega_m)-0.15*n)*
+		exp(+1.02*n+1.7*n*n);
+	 /* Error -- was exp(-1.02n-1.7*n*n) in earlier version (v1-1.3)*/
+	else return 1.95e-5*pow(omega_m, -0.35-0.19*log(omega_m)-0.17*n)*
+		exp(-n-0.14*n*n);
+	 /* Error -- was exp(-n-0.14*n*n) in earlier version (v1-1.2)*/
+	 /* Error -- was exp(n+0.14*n*n) in earlier version (v1.3) */
+    } else return 1e-5*(2.422-1.166*exp(omega_m)+0.800*exp(lambda)
+	+3.780*omega_m-2.267*omega_m*exp(lambda)+0.487*SQR(omega_m)+
+	0.561*lambda+3.329*lambda*exp(omega_m)-8.568*omega_m*lambda+
+	1.080*SQR(lambda));
+}
+
+/* The following routine is from Numerical Recipes in C, 2nd edition,
+by Press, Teulkolsky, Vetterling, and Flannery, (Cambridge Univ. Press) */
+double erfcc(double x)
+{
+	double t,z,ans;
+	z=fabs(x);
+	t=1.0/(1.0+0.5*z);
+	ans=t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
+		t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
+		t*(-0.82215223+t*0.17087277)))))))));
+	return x >= 0.0 ? ans : 2.0-ans;
+}
+
+/* ======================= Integration Engine ======================= */
+
+double midpoint_int(double (*func)(double))
+/* Integrate the function func() on the range (0,1] */
+/* Use midpoint rule, expanding by factor of 3 each time */
+/* Linearly extrapolate to zero stepsize.  Not fancy */
+{
+    int iter, bins, j;
+    double width, xeval, sum[11];
+
+    sum[0] = (*func)(0.5);	/* First step is easy */
+    bins = 1; width = 1.0;
+    for (iter=1; iter<11; iter++) {	/* Now start increasing the bins */
+	bins *= 3;
+	width /= 3.0;
+	sum[iter]=0.0;
+	for (xeval=width/2.0,j=1;j<=bins;xeval+=width,j++) {
+	    if (j%3==2) continue;	/* We've already done this one */
+	    sum[iter]+=(*func)(xeval);
+	}
+	/* Add the new evaluations to the old ones. */
+	sum[iter]=sum[iter]*width+sum[iter-1]/3.0;
+	/* printf("%d iteration, sum = %f\n", iter, sum[iter]); */
+	/* Now decide if we're done */
+	if (iter<4) continue;	/* We certainly want to do some work */
+	/* If error scales as width^2, then linear extrapolation in
+	quantity width^2 is sum[iter]+(sum[iter]-sum[iter-1])/8.0 */
+	if (fabs( (sum[iter]+(sum[iter]-sum[iter-1])/8.0)/
+		  (sum[iter-1]+(sum[iter-1]-sum[iter-2])/8.0)-1.0)<1e-4) 
+	    return sum[iter]+(sum[iter]-sum[iter-1])/8.0;
+	/* if (fabs(sum[iter-1]/sum[iter]-1)<1e-4) return sum[iter];  */
+    }
+    crash("Too many steps in the integration.");
+}
+
+double integrate(double (*func)(double))
+/* Integrate the function func() on the range (0,1] */
+{
+    double midpoint_int(double (*func)(double));
+    return midpoint_int(func);
+}
+
+/* The above is a simple integrator.  You could get faster execution times
+by using a more accurate integrator.  The following is an example from 
+Numerical Recipes, but all that is needed is for the call to integrate()
+to return the value of func() integrated on the range (0,1]. */
+
+#ifdef YES_NR
+#include "qromo.c"
+#include "midpnt.c"
+#include "polint.c"
+#include "nrutil.c"
+
+float integrate(float (*func)(float))
+/* Integrate the function func() on the range (0,1] */
+{
+    float qromo(float (*func)(float), float a, float b,
+	float (*choose)(float(*)(float),float,float,int));
+    float midpnt(float (*func)(float), float a, float b, int n);
+    return qromo(func,0,1,midpnt);
+}
+#endif
+
Index: /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.c
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.c	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.c	(revision 3445)
@@ -0,0 +1,358 @@
+/* The following routines implement all of the fitting formulae in 
+Eisenstein \& Hu (1997) */
+
+/* There are two sets of routines here.  The first set,
+
+	TFfit_hmpc(), TFset_parameters(), and TFfit_onek(),
+
+calculate the transfer function for an arbitrary CDM+baryon universe using
+the fitting formula in Section 3 of the paper.  The second set,
+
+	TFsound_horizon_fit(), TFk_peak(), TFnowiggles(), and TFzerobaryon(),
+
+calculate other quantities given in Section 4 of the paper. */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void TFset_parameters(double omega0hh, double f_baryon, double Tcmb);
+double TFfit_onek(double k, double *tf_baryon, double *tf_cdm); 
+
+void TFfit_hmpc(double omega0, double f_baryon, double hubble, double Tcmb,
+	int numk, double *k, double *tf_full, double *tf_baryon, double *tf_cdm);
+
+double TFsound_horizon_fit(double omega0, double f_baryon, double hubble);
+double TFk_peak(double omega0, double f_baryon, double hubble);
+double TFnowiggles(double omega0, double f_baryon, double hubble, 
+		double Tcmb, double k_hmpc);
+double TFzerobaryon(double omega0, double hubble, double Tcmb, double k_hmpc);
+
+/* ------------------------ DRIVER ROUTINE --------------------------- */
+/* The following is an example of a driver routine you might use. */
+/* Basically, the driver routine needs to call TFset_parameters() to
+set all the scalar parameters, and then call TFfit_onek() for each 
+wavenumber k you desire. */
+
+/* While the routines use Mpc^-1 units internally, this driver has been
+written to take an array of wavenumbers in units of h Mpc^-1.  On the
+other hand, if you want to use Mpc^-1 externally, you can do this by
+altering the variables you pass to the driver:  
+	omega0 -> omega0*hubble*hubble, hubble -> 1.0 		*/
+
+/* INPUT: omega0 -- the matter density (baryons+CDM) in units of critical 
+	  f_baryon -- the ratio of baryon density to matter density 
+	  hubble -- the Hubble constant, in units of 100 km/s/Mpc
+	  Tcmb -- the CMB temperature in Kelvin. T<=0 uses the COBE value 2.728.
+	  numk -- the length of the following zero-offset array
+	  k[] -- the array of wavevectors k[0..numk-1]  */
+
+/* INPUT/OUTPUT: There are three output arrays of transfer functions. 
+All are zero-offset and, if used, must have storage [0..numk-1] declared
+in the calling program.  However, if you substitute the NULL pointer for
+one or more of the arrays, then that particular transfer function won't
+be outputted. The transfer functions are:
+
+	tf_full[] -- The full fitting formula, eq. (16), for the matter
+			transfer function. 
+	tf_baryon[] -- The baryonic piece of the full fitting formula, eq. 21.
+	tf_cdm[] -- The CDM piece of the full fitting formula, eq. 17. */
+
+/* Again, you can set these pointers to NULL in the function call if
+you don't want a particular output. */
+
+/* Various intermediate scalar quantities are stored in global variables, 
+so that you might more easily access them.  However, this also means that
+you would be better off not simply #include'ing this file in your programs,
+but rather compiling it separately, calling only the driver, and using
+extern declarations to access the intermediate quantities. */
+
+/* ----------------------------- DRIVER ------------------------------- */
+
+void TFfit_hmpc(double omega0, double f_baryon, double hubble, double Tcmb,
+	int numk, double *k, double *tf_full, double *tf_baryon, double *tf_cdm)
+/* Remember: k[0..numk-1] is in units of h Mpc^-1. */
+{
+    int j;
+    double tf_thisk, baryon_piece, cdm_piece;
+
+    TFset_parameters(omega0*hubble*hubble, f_baryon, Tcmb);
+
+    for (j=0;j<numk;j++) {
+    	tf_thisk = TFfit_onek(k[j]*hubble, &baryon_piece, &cdm_piece); 
+	if (tf_full!=NULL) tf_full[j] = tf_thisk;
+	if (tf_baryon!=NULL) tf_baryon[j] = baryon_piece;
+	if (tf_cdm!=NULL) tf_cdm[j] = cdm_piece;
+    }
+    return;
+}
+
+/* ------------------------ FITTING FORMULAE ROUTINES ----------------- */
+
+/* There are two routines here.  TFset_parameters() sets all the scalar
+parameters, while TFfit_onek() calculates the transfer function for a 
+given wavenumber k.  TFfit_onek() may be called many times after a single
+call to TFset_parameters() */
+
+/* Global variables -- We've left many of the intermediate results as 
+global variables in case you wish to access them, e.g. by declaring
+them as extern variables in your main program. */
+/* Note that all internal scales are in Mpc, without any Hubble constants! */
+
+double	omhh,		/* Omega_matter*h^2 */
+	obhh,		/* Omega_baryon*h^2 */
+	theta_cmb,	/* Tcmb in units of 2.7 K */
+	z_equality,	/* Redshift of matter-radiation equality, really 1+z */
+	k_equality,	/* Scale of equality, in Mpc^-1 */
+	z_drag,		/* Redshift of drag epoch */
+	R_drag,		/* Photon-baryon ratio at drag epoch */
+	R_equality,	/* Photon-baryon ratio at equality epoch */
+	sound_horizon,	/* Sound horizon at drag epoch, in Mpc */
+	k_silk,		/* Silk damping scale, in Mpc^-1 */
+	alpha_c,	/* CDM suppression */
+	beta_c,		/* CDM log shift */
+	alpha_b,	/* Baryon suppression */
+	beta_b,		/* Baryon envelope shift */
+	beta_node,	/* Sound horizon shift */
+	k_peak,		/* Fit to wavenumber of first peak, in Mpc^-1 */
+	sound_horizon_fit,	/* Fit to sound horizon, in Mpc */
+	alpha_gamma;	/* Gamma suppression in approximate TF */
+
+/* Convenience from Numerical Recipes in C, 2nd edition
+------------ COMPLETEMENT DEBILE (cmv) ????????? ------------
+static double sqrarg;
+#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
+static double cubearg;
+#define CUBE(a) ((cubearg=(a)) == 0.0 ? 0.0 : cubearg*cubearg*cubearg)
+static double pow4arg;
+#define POW4(a) ((pow4arg=(a)) == 0.0 ? 0.0 : pow4arg*pow4arg*pow4arg*pow4arg)
+	Yes, I know the last one isn't optimal; it doesn't appear much */
+#define SQR(a) (a*a)
+#define CUBE(a) (a*a*a)
+#define POW4(a) (a*a*a*a)
+
+void TFset_parameters(double omega0hh, double f_baryon, double Tcmb)
+/* Set all the scalars quantities for Eisenstein & Hu 1997 fitting formula */
+/* Input: omega0hh -- The density of CDM and baryons, in units of critical dens,
+		multiplied by the square of the Hubble constant, in units
+		of 100 km/s/Mpc */
+/* 	  f_baryon -- The fraction of baryons to CDM */
+/*        Tcmb -- The temperature of the CMB in Kelvin.  Tcmb<=0 forces use
+			of the COBE value of  2.728 K. */
+/* Output: Nothing, but set many global variables used in TFfit_onek(). 
+You can access them yourself, if you want. */
+/* Note: Units are always Mpc, never h^-1 Mpc. */
+{
+    double z_drag_b1, z_drag_b2;
+    double alpha_c_a1, alpha_c_a2, beta_c_b1, beta_c_b2, alpha_b_G, y;
+
+    if (f_baryon<=0.0 || omega0hh<=0.0) {
+	fprintf(stderr, "TFset_parameters(): Illegal input.\n");
+	exit(1);
+    }
+    omhh = omega0hh;
+    obhh = omhh*f_baryon;
+    if (Tcmb<=0.0) Tcmb=2.728;	/* COBE FIRAS */
+    theta_cmb = Tcmb/2.7;
+
+    z_equality = 2.50e4*omhh/POW4(theta_cmb);  /* Really 1+z */
+    k_equality = 0.0746*omhh/SQR(theta_cmb);
+
+    z_drag_b1 = 0.313*pow(omhh,-0.419)*(1+0.607*pow(omhh,0.674));
+    z_drag_b2 = 0.238*pow(omhh,0.223);
+    z_drag = 1291*pow(omhh,0.251)/(1+0.659*pow(omhh,0.828))*
+		(1+z_drag_b1*pow(obhh,z_drag_b2));
+    
+    R_drag = 31.5*obhh/POW4(theta_cmb)*(1000/(1+z_drag));
+    R_equality = 31.5*obhh/POW4(theta_cmb)*(1000/z_equality);
+
+    sound_horizon = 2./3./k_equality*sqrt(6./R_equality)*
+	    log((sqrt(1+R_drag)+sqrt(R_drag+R_equality))/(1+sqrt(R_equality)));
+
+    k_silk = 1.6*pow(obhh,0.52)*pow(omhh,0.73)*(1+pow(10.4*omhh,-0.95));
+
+    alpha_c_a1 = pow(46.9*omhh,0.670)*(1+pow(32.1*omhh,-0.532));
+    alpha_c_a2 = pow(12.0*omhh,0.424)*(1+pow(45.0*omhh,-0.582));
+    alpha_c = pow(alpha_c_a1,-f_baryon)*
+		pow(alpha_c_a2,-CUBE(f_baryon));
+    
+    beta_c_b1 = 0.944/(1+pow(458*omhh,-0.708));
+    beta_c_b2 = pow(0.395*omhh, -0.0266);
+    beta_c = 1.0/(1+beta_c_b1*(pow(1-f_baryon, beta_c_b2)-1));
+
+    y = z_equality/(1+z_drag);
+    alpha_b_G = y*(-6.*sqrt(1+y)+(2.+3.*y)*log((sqrt(1+y)+1)/(sqrt(1+y)-1)));
+    alpha_b = 2.07*k_equality*sound_horizon*pow(1+R_drag,-0.75)*alpha_b_G;
+
+    beta_node = 8.41*pow(omhh, 0.435);
+    beta_b = 0.5+f_baryon+(3.-2.*f_baryon)*sqrt(pow(17.2*omhh,2.0)+1);
+
+    k_peak = 2.5*3.14159*(1+0.217*omhh)/sound_horizon;
+    sound_horizon_fit = 44.5*log(9.83/omhh)/sqrt(1+10.0*pow(obhh,0.75));
+
+    alpha_gamma = 1-0.328*log(431.0*omhh)*f_baryon + 0.38*log(22.3*omhh)*
+		SQR(f_baryon);
+    
+    return;
+}
+
+double TFfit_onek(double k, double *tf_baryon, double *tf_cdm)
+/* Input: k -- Wavenumber at which to calculate transfer function, in Mpc^-1.
+	  *tf_baryon, *tf_cdm -- Input value not used; replaced on output if
+				the input was not NULL. */
+/* Output: Returns the value of the full transfer function fitting formula.
+		This is the form given in Section 3 of Eisenstein & Hu (1997).
+  	  *tf_baryon -- The baryonic contribution to the full fit.
+	  *tf_cdm -- The CDM contribution to the full fit. */
+/* Notes: Units are Mpc, not h^-1 Mpc. */
+{
+    double T_c_ln_beta, T_c_ln_nobeta, T_c_C_alpha, T_c_C_noalpha;
+    double q, xx, xx_tilde, q_eff;
+    double T_c_f, T_c, s_tilde, T_b_T0, T_b, f_baryon, T_full;
+    double T_0_L0, T_0_C0, T_0, gamma_eff; 
+    double T_nowiggles_L0, T_nowiggles_C0, T_nowiggles;
+
+    k = fabs(k);	/* Just define negative k as positive */
+    if (k==0.0) {
+	if (tf_baryon!=NULL) *tf_baryon = 1.0;
+	if (tf_cdm!=NULL) *tf_cdm = 1.0;
+	return 1.0;
+    }
+
+    q = k/13.41/k_equality;
+    xx = k*sound_horizon;
+
+    T_c_ln_beta = log(2.718282+1.8*beta_c*q);
+    T_c_ln_nobeta = log(2.718282+1.8*q);
+    T_c_C_alpha = 14.2/alpha_c + 386.0/(1+69.9*pow(q,1.08));
+    T_c_C_noalpha = 14.2 + 386.0/(1+69.9*pow(q,1.08));
+
+    T_c_f = 1.0/(1.0+POW4(xx/5.4));
+    T_c = T_c_f*T_c_ln_beta/(T_c_ln_beta+T_c_C_noalpha*SQR(q)) +
+	    (1-T_c_f)*T_c_ln_beta/(T_c_ln_beta+T_c_C_alpha*SQR(q));
+    
+    s_tilde = sound_horizon*pow(1+CUBE(beta_node/xx),-1./3.);
+    xx_tilde = k*s_tilde;
+
+    T_b_T0 = T_c_ln_nobeta/(T_c_ln_nobeta+T_c_C_noalpha*SQR(q));
+    T_b = sin(xx_tilde)/(xx_tilde)*(T_b_T0/(1+SQR(xx/5.2))+
+		alpha_b/(1+CUBE(beta_b/xx))*exp(-pow(k/k_silk,1.4)));
+
+    f_baryon = obhh/omhh;
+    T_full = f_baryon*T_b + (1-f_baryon)*T_c;
+
+    /* Now to store these transfer functions */
+    if (tf_baryon!=NULL) *tf_baryon = T_b;
+    if (tf_cdm!=NULL) *tf_cdm = T_c;
+    return T_full;
+}
+
+/* ======================= Approximate forms =========================== */
+
+double TFsound_horizon_fit(double omega0, double f_baryon, double hubble)
+/* Input: omega0 -- CDM density, in units of critical density
+	  f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
+	  hubble -- Hubble constant, in units of 100 km/s/Mpc */
+/* Output: The approximate value of the sound horizon, in h^-1 Mpc. */
+/* Note: If you prefer to have the answer in  units of Mpc, use hubble -> 1
+and omega0 -> omega0*hubble^2. */ 
+{
+    double omhh, sound_horizon_fit_mpc;
+    omhh = omega0*hubble*hubble;
+    sound_horizon_fit_mpc = 
+	44.5*log(9.83/omhh)/sqrt(1+10.0*pow(omhh*f_baryon,0.75));
+    return sound_horizon_fit_mpc*hubble;
+}
+
+double TFk_peak(double omega0, double f_baryon, double hubble)
+/* Input: omega0 -- CDM density, in units of critical density
+	  f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
+	  hubble -- Hubble constant, in units of 100 km/s/Mpc */
+/* Output: The approximate location of the first baryonic peak, in h Mpc^-1 */
+/* Note: If you prefer to have the answer in  units of Mpc^-1, use hubble -> 1
+and omega0 -> omega0*hubble^2. */ 
+{
+    double omhh, k_peak_mpc;
+    omhh = omega0*hubble*hubble;
+    k_peak_mpc = 2.5*3.14159*(1+0.217*omhh)/TFsound_horizon_fit(omhh,f_baryon,1.0);
+    return k_peak_mpc/hubble;
+}
+
+double TFnowiggles(double omega0, double f_baryon, double hubble, 
+		double Tcmb, double k_hmpc)
+/* Input: omega0 -- CDM density, in units of critical density
+	  f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
+	  hubble -- Hubble constant, in units of 100 km/s/Mpc
+	  Tcmb -- Temperature of the CMB in Kelvin; Tcmb<=0 forces use of
+			COBE FIRAS value of 2.728 K
+	  k_hmpc -- Wavenumber in units of (h Mpc^-1). */
+/* Output: The value of an approximate transfer function that captures the
+non-oscillatory part of a partial baryon transfer function.  In other words,
+the baryon oscillations are left out, but the suppression of power below
+the sound horizon is included. See equations (30) and (31).  */
+/* Note: If you prefer to use wavenumbers in units of Mpc^-1, use hubble -> 1
+and omega0 -> omega0*hubble^2. */ 
+{
+    double k, omhh, theta_cmb, k_equality, q, xx, alpha_gamma, gamma_eff;
+    double q_eff, T_nowiggles_L0, T_nowiggles_C0;
+
+    k = k_hmpc*hubble;	/* Convert to Mpc^-1 */
+    omhh = omega0*hubble*hubble;
+    if (Tcmb<=0.0) Tcmb=2.728;	/* COBE FIRAS */
+    theta_cmb = Tcmb/2.7;
+
+    k_equality = 0.0746*omhh/SQR(theta_cmb);
+    q = k/13.41/k_equality;
+    xx = k*TFsound_horizon_fit(omhh, f_baryon, 1.0);
+
+    alpha_gamma = 1-0.328*log(431.0*omhh)*f_baryon + 0.38*log(22.3*omhh)*
+		SQR(f_baryon);
+    gamma_eff = omhh*(alpha_gamma+(1-alpha_gamma)/(1+POW4(0.43*xx)));
+    q_eff = q*omhh/gamma_eff;
+
+    T_nowiggles_L0 = log(2.0*2.718282+1.8*q_eff);
+    T_nowiggles_C0 = 14.2 + 731.0/(1+62.5*q_eff);
+    return T_nowiggles_L0/(T_nowiggles_L0+T_nowiggles_C0*SQR(q_eff));
+}
+
+/* ======================= Zero Baryon Formula =========================== */
+
+double TFzerobaryon(double omega0, double hubble, double Tcmb, double k_hmpc)
+/* Input: omega0 -- CDM density, in units of critical density
+	  hubble -- Hubble constant, in units of 100 km/s/Mpc
+	  Tcmb -- Temperature of the CMB in Kelvin; Tcmb<=0 forces use of
+			COBE FIRAS value of 2.728 K
+	  k_hmpc -- Wavenumber in units of (h Mpc^-1). */
+/* Output: The value of the transfer function for a zero-baryon universe. */
+/* Note: If you prefer to use wavenumbers in units of Mpc^-1, use hubble -> 1
+and omega0 -> omega0*hubble^2. */ 
+{
+    double k, omhh, theta_cmb, k_equality, q, T_0_L0, T_0_C0;
+
+    k = k_hmpc*hubble;	/* Convert to Mpc^-1 */
+    omhh = omega0*hubble*hubble;
+    if (Tcmb<=0.0) Tcmb=2.728;	/* COBE FIRAS */
+    theta_cmb = Tcmb/2.7;
+
+    k_equality = 0.0746*omhh/SQR(theta_cmb);
+    q = k/13.41/k_equality;
+
+    T_0_L0 = log(2.0*2.718282+1.8*q);
+    T_0_C0 = 14.2 + 731.0/(1+62.5*q);
+    return T_0_L0/(T_0_L0+T_0_C0*q*q);
+}
+
+
+/* Added by cmv 24/08/2007 */
+void TFprint_parameters(void)
+{
+  printf("omhh=%g obhh=%g theta_cmb=%g\n",omhh,obhh,theta_cmb);
+  printf("z_equality=%g k_equality=%g R_equality=%g\n",z_equality,k_equality,R_equality);
+  printf("z_drag=%g R_drag=%g sound_horizon=%g\n",z_drag,R_drag,sound_horizon);
+  printf("k_silk=%g\n",k_silk);
+  printf("alpha_c=%g beta_c=%g\n",alpha_c,beta_c);
+  printf("alpha_b=%g beta_b=%g\n",alpha_b,beta_b);
+  printf("beta_node=%g\n",beta_node);
+  printf("k_peak=%g sound_horizon_fit=%g\n",k_peak,sound_horizon_fit);
+  printf("alpha_gamma=%g\n",alpha_gamma);
+}
Index: /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/hu_tf_fit.h	(revision 3445)
@@ -0,0 +1,29 @@
+#ifndef HU_TF_FIT_SEEN
+#define HU_TF_FIT_SEEN
+
+//http://background.uchicago.edu/~whu/transfer/transferpage.html
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void TFset_parameters(double omega0hh, double f_baryon, double Tcmb);
+double TFfit_onek(double k, double *tf_baryon, double *tf_cdm); 
+
+void TFfit_hmpc(double omega0, double f_baryon, double hubble, double Tcmb,
+	int numk, double *k, double *tf_full, double *tf_baryon, double *tf_cdm);
+
+double TFsound_horizon_fit(double omega0, double f_baryon, double hubble);
+double TFk_peak(double omega0, double f_baryon, double hubble);
+double TFnowiggles(double omega0, double f_baryon, double hubble, 
+		double Tcmb, double k_hmpc);
+double TFzerobaryon(double omega0, double hubble, double Tcmb, double k_hmpc);
+
+/* Added by cmv 24/08/2007 */
+void TFprint_parameters(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HU_TF_FIT_SEEN
Index: /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.cc	(revision 3445)
@@ -0,0 +1,692 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "pexceptions.h"
+
+#include "constcosmo.h"
+#include "geneutils.h"
+#include "pkspectrum.h"
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////
+//******************** InitialSpectrum ******************//
+///////////////////////////////////////////////////////////
+
+InitialSpectrum::InitialSpectrum(double n,double a)
+  : n_(n), A_(a)
+{
+}
+
+InitialSpectrum::InitialSpectrum(InitialSpectrum& pkinf)
+  : n_(pkinf.n_), A_(pkinf.A_)
+{
+}
+
+InitialSpectrum::~InitialSpectrum(void)
+{
+}
+
+
+///////////////////////////////////////////////////////////
+//****************** TransfertEisenstein ****************//
+///////////////////////////////////////////////////////////
+
+// From Eisenstein & Hu ApJ 496:605-614 1998 April 1 (ou astro-ph/9709112)
+TransfertEisenstein::TransfertEisenstein(double h100,double OmegaCDM0,double OmegaBaryon0,double tcmb,bool nobaryon,int lp)
+  : lp_(lp)
+  , Oc_(OmegaCDM0) , Ob_(OmegaBaryon0) , h100_(h100) , tcmb_(tcmb)
+  , nobaryon_(nobaryon) , nooscenv_(0), retpart_(ALL)
+{
+ zero_();
+ Init_();
+}
+
+TransfertEisenstein::TransfertEisenstein(TransfertEisenstein& tf)
+  : lp_(tf.lp_)
+  ,Oc_(tf.Oc_) , Ob_(tf.Ob_) , h100_(tf.h100_) , tcmb_(tf.tcmb_)
+  , nobaryon_(tf.nobaryon_) , nooscenv_(tf.nooscenv_), retpart_(tf.retpart_)
+{
+ zero_();
+ Init_();
+}
+
+TransfertEisenstein::~TransfertEisenstein(void)
+{
+}
+
+void TransfertEisenstein::zero_(void)
+{
+ th2p7_=zeq_=keq_=zd_=Req_=Rd_=s_=ksilk_=alphac_=betac_=bnode_
+       =alphab_=betab_=alphag_=sfit_=kpeak_=1.e99;
+}
+
+void TransfertEisenstein::Init_(void)
+{
+
+  O0_ = Oc_ + Ob_;
+  if(nobaryon_) {O0_ = Oc_; Ob_ = 0.;}
+  double H0 = 100. * h100_, h2 = h100_*h100_;
+  if(lp_) cout<<"h100="<<h100_<<" H0="<<H0<<") Omatter="<<O0_<<" Ocdm="<<Oc_<<" Ob="<<Ob_<<endl;
+
+
+  if(tcmb_<0.) tcmb_ = T_CMB_Par;
+  th2p7_ = tcmb_/2.7;
+  double th2p7P4 = th2p7_*th2p7_*th2p7_*th2p7_;
+  if(lp_) cout<<"tcmb = "<<tcmb_<<" K = "<<th2p7_<<" *2.7K "<<endl;
+
+  // Formule 2 p 606
+  zeq_ = 2.50e4 * O0_ * h2 / th2p7P4;
+  if(lp_) cout<<"zeq = "<<zeq_<<" (redshift of matter-radiation equality)"<<endl;
+
+  // Formule 3 p 607
+  // (attention ici C=1 : H0 -> H0/C si on utilise la premiere formule)
+  //  keq_ = sqrt(2.*O0_*H0*H0*zeq_) / SpeedOfLight_Cst;
+  keq_ = 7.46e-2 * O0_ * h2 / (th2p7_*th2p7_);
+  if(lp_) cout<<"keq = "<<keq_<<" Mpc^-1 (scale of equality)"<<endl;
+
+  // On s'arrete ici si pas de baryons
+  if(nobaryon_) return;
+
+  // Formule 4 p 607
+  double b1_eq4 = 0.313*pow(O0_*h2,-0.419)*(1. + 0.607*pow(O0_*h2,0.674));
+  double b2_eq4 = 0.238*pow(O0_*h2,0.223);
+  zd_ = 1291. * pow(O0_*h2,0.251) / (1.+0.659* pow(O0_*h2,0.828))
+              * (1. + b1_eq4*pow(Ob_*h2,b2_eq4));
+  if(lp_) cout<<"zd = "<<zd_<<" (Redshift of drag epoch)"<<endl;
+
+  // Formule 5 page 607    (R = 3*rho_baryon/4*rho_gamma)
+  Req_ = 31.5*Ob_*h2 / th2p7P4 * (1.e3/zeq_);
+  //WARNING: W.Hu code (tf_fit.c) en des-accord avec l'article: zd -> (1+zd)
+  Rd_  = 31.5*Ob_*h2 / th2p7P4 * (1.e3/zd_);
+  //in tf_fit.c: Rd_  = 31.5*Ob_*h2 / th2p7P4 * (1.e3/(1.+zd_));
+  if(lp_) {
+    cout<<"Req = "<<Req_<<" Rd = "<<Rd_
+        <<" (Photon-baryon ratio at equality/drag epoch)"<<endl;
+    cout<<"Sound speed at equality "<<1./sqrt(3.*(1.+Req_))
+        <<", at drag "<<1./sqrt(3.*(1.+Rd_))<<" in unit of C"<<endl;
+  }
+
+  // Formule 6 p 607
+  s_ = 2./(3.*keq_) * sqrt(6./Req_)
+      * log( (sqrt(1.+Rd_) + sqrt(Rd_+Req_)) / (1.+sqrt(Req_)) );
+  if(lp_) cout<<"s = "<<s_<<" Mpc (sound horizon at drag epoch)"<<endl;
+
+  // Formule 7 page 607
+  ksilk_ = 1.6*pow(Ob_*h2,0.52)*pow(O0_*h2,0.73) * (1. + pow(10.4*O0_*h2,-0.95));
+  if(lp_) cout<<"ksilk = "<<ksilk_<<" Mpc^-1 (silk damping scale)"<<endl;
+
+  // Formules 10 page 608
+  double a1 = pow(46.9*O0_*h2,0.670) * (1. + pow(32.1*O0_*h2,-0.532));
+  double a2 = pow(12.0*O0_*h2,0.424) * (1. + pow(45.0*O0_*h2,-0.582));
+  alphac_ = pow(a1,-Ob_/O0_) * pow(a2,-pow(Ob_/O0_,3.));
+  double b1 = 0.944 / (1. + pow(458.*O0_*h2,-0.708));
+  double b2 = pow(0.395*O0_*h2,-0.0266);
+  betac_ = 1 / ( 1. + b1*(pow(Oc_/O0_,b2) - 1.) );
+  if(lp_) cout<<"alphac = "<<alphac_<<" betac = "<<betac_
+               <<" (CDM suppression/log shift)"<<endl;
+
+  // Formule 23 page 610
+  bnode_ = 8.41 * pow(O0_*h2,0.435);
+  if(lp_) cout<<"bnode = "<<bnode_<<" (sound horizon shift)"<<endl;
+
+  // Formule 14 page 608
+  //WARNING: W.Hu code (tf_fit.c) en des-accord avec l'article: (1+zeq) -> zeq
+  double y = (1.+zeq_)/(1.+zd_);
+  //in tf_fit.c: double y = zeq_/(1.+zd_);
+  double s1py = sqrt(1.+y);
+  double Gy = y*( -6.*s1py + (2.+3.*y)*log((s1py+1.)/(s1py-1.)) );
+  alphab_ = 2.07*keq_*s_*pow(1.+Rd_,-3./4.)*Gy;
+
+  // Formule 24 page 610
+  betab_ = 0.5 + Ob_/O0_
+         + (3.-2.*Ob_/O0_) * sqrt(pow(17.2*O0_*h2,2.) + 1.);
+  if(lp_) cout<<"alphab = "<<alphab_<<" betab = "<<betab_
+               <<" (Baryon suppression/envelope shift)"<<endl;
+
+  // Formule 31 page 612
+  alphag_ = 1.
+          - 0.328*log(431.*O0_*h2)*Ob_/O0_
+          + 0.38*log(22.3*O0_*h2)*pow(Ob_/O0_,2.);
+  if(lp_) cout<<"alphag = "<<alphag_<<" (gamma suppression in approximate TF)"<<endl;
+
+ // The approximate value of the sound horizon, formule 26 page 611
+ sfit_ = 44.5*log(9.83/(O0_*h2)) / sqrt(1.+10.*pow(Ob_*h2,3./4.));  // Mpc
+ if(lp_) cout<<"sfit="<<sfit_<<" Mpc (fit to sound horizon)"<<endl;
+
+ // La positoin du premier pic acoustique, formule 25 page 611
+ kpeak_ = 5*M_PI/(2.*sfit_) * (1.+0.217*O0_*h2);  // 1/Mpc
+ if(lp_) cout<<"kpeak="<<kpeak_<<" Mpc^-1 (fit to wavenumber of first peak)"<<endl;
+
+  return;
+}
+
+bool TransfertEisenstein::SetParTo(double h100,double OmegaCDM0,double OmegaBaryon0)
+// Changement des valeurs des parametres (suivi de re-init eventuel)
+// Si h100,Omega...<=0. alors pas de changement, on garde l'ancienne valeur
+{
+ bool haschanged = false;
+
+ if(h100>0.) {h100_ = h100; haschanged = true;}
+ if(OmegaCDM0>0.) {Oc_ = OmegaCDM0; haschanged = true;}
+ if(OmegaBaryon0>0.) {Ob_ = OmegaBaryon0; haschanged = true;}
+
+ // et on recalcule les initialisations
+ if(haschanged) Init_();
+
+ return haschanged;
+}
+
+void TransfertEisenstein::SetNoOscEnv(unsigned short nooscenv)
+// To obtain an approximate form of the non-oscillatory part of the transfert function
+// nooscenv = 0 : use the baryon oscillatory part of transfert function (full tf)
+// nooscenv = 1 : use approx. paragraph 3.3 p610 (middle of right column)
+//                Replace  j0(k*stilde)  ->  [1+(k*stilde)^4]^(-1/4)
+// nooscenv = 2 : use formulae 29+30+31 page 612
+//                The value of an approximate transfer function that captures
+//                the non-oscillatory part of a partial baryon transfer function.
+//                In other words, the baryon oscillations are left out,
+//                but the suppression of power below the sound horizon is included.
+{
+ if(nooscenv!=1 && nooscenv!=2) nooscenv = 0;
+ nooscenv_ = nooscenv;
+}
+
+void TransfertEisenstein::SetReturnPart(ReturnPart retpart)
+// To return only baryon or CDM part part of transfert function
+// retpart = ALL: return full transfert function
+//         = CDM : return only CDM part of transfert function
+//         = BARYON : return only Baryon part of transfert function
+// WARNING: only relevant for nobaryon_=false AND nooscenv!=2
+{
+ retpart_ = retpart;
+}
+
+void TransfertEisenstein::SetPrintLevel(int lp)
+{
+ lp_ = lp;
+}
+
+
+double TransfertEisenstein::T0tild(double k,double alphac,double betac)
+{
+  // Formule 10 p 608
+  //double q = k*th2p7_*th2p7_/(O0_*h100_*h100_);
+  double q = k/(13.41*keq_);
+  // Formule 20 p 610
+  double C = (14.2/alphac) + 386./(1.+69.9*pow(q,1.08));
+  // Formule 19 p 610
+  double x = log(M_E+1.8*betac*q);
+  return x / (x + C*q*q);
+}
+
+double TransfertEisenstein::operator() (double k)
+{
+
+  // --- Pour zero baryon
+  //  OU Pour function lissee sans oscillation baryon
+  if(nobaryon_  || nooscenv_ == 2) {
+    double gamma = O0_*h100_;
+    // Calcul de Gamma_eff, formule 30 page 612 (pour fct lissee)
+    if( nobaryon_==false && nooscenv_ == 2 )
+      gamma = O0_*h100_*(alphag_ + (1.-alphag_)/(1.+pow(0.43*k*sfit_,4.))); // Gamma_eff
+    // Formule 28 page 612 : qui est est equivalent a:
+    //    q = k / h100_ * th2p7_*th2p7_ / gamma;
+    // qui est est equivalent a:
+    //    q = k / (13.41 * keq)                   pour Ob=0
+    //    q = k / (13.41 * keq) * (O0*h/Gamma)    pour le spectre lisse
+    // Les resultats sont legerement differents a cause des valeurs approx.
+    // des constantes numeriques: on prend comme W.Hu (tf_fit.c)
+    //double q = k / h100_ * th2p7_*th2p7_ / gamma;  // Mpc^-1
+    double q = k/(13.41*keq_) * (O0_*h100_/gamma);  // Mpc^-1
+    // Formules 29 page 612
+    double l0 = log(2.*M_E + 1.8*q);
+    double c0 = 14.2 + 731./(1.+62.5*q);
+    return l0 / (l0 + c0*q*q);
+  }
+
+  // --- Pour CDM + Baryons
+  // --- CDM
+  double f = 1. / (1. + pow(k*s_/5.4,4.));
+  double Tc = f*T0tild(k,1.,betac_) + (1.-f)*T0tild(k,alphac_,betac_);
+  if(retpart_ == CDM) return Tc; 
+
+  // --- Baryons
+  // Formule 22 page 610
+  double stilde, ksbnode = k*s_/bnode_;
+  if(ksbnode<0.001) stilde =s_ * ksbnode;
+     else   stilde = s_ / pow(1. + pow(1./ksbnode,3.), 1./3.);
+  // Formule 21 page 610
+  double j0kst = 0.;
+  if(nooscenv_ == 1) {
+    j0kst = pow(1.+pow(k*stilde,4.) , -1./4.); //lissee sans oscillation baryon
+  } else {
+    double x = k*stilde;
+    if(x<0.01) j0kst = 1. - x*x/6.*(1.-x*x/20.);
+      else j0kst = sin(x)/x;
+    //cout<<"DEBUG: k="<<k<<" stilde="<<stilde<<" x="<<x<<" j0kst="<<j0kst<<endl;
+  }
+  double Tb = T0tild(k,1.,1.) / (1. + pow(k*s_/5.2,2.));
+  Tb += alphab_/(1.+pow(betab_/(k*s_),3.)) * exp(-pow(k/ksilk_,1.4));
+  Tb *= j0kst;
+  if(retpart_ == BARYON) return Tb;
+
+  // --- Total
+  double T = (Ob_/O0_)*Tb + (Oc_/O0_)*Tc;
+
+  return T;
+}
+
+double TransfertEisenstein::KPeak(void)
+// Position du premier pic acoustic
+{
+ if(nobaryon_) return -1.;
+ return kpeak_;
+}
+
+
+///////////////////////////////////////////////////////////
+//******************* TransfertTabulate *****************//
+///////////////////////////////////////////////////////////
+
+TransfertTabulate::TransfertTabulate(double h100,double OmegaCDM0,double OmegaBaryon0)
+: Oc_(OmegaCDM0) , Ob_(OmegaBaryon0) , h100_(h100) , kmin_(1.) , kmax_(-1.)
+, interptyp_(0)
+{
+}
+
+TransfertTabulate::TransfertTabulate(TransfertTabulate& tf)
+: Oc_(tf.Oc_) , Ob_(tf.Ob_) , h100_(tf.h100_) , kmin_(tf.kmin_) , kmax_(tf.kmax_)
+, interptyp_(tf.interptyp_) , k_(tf.k_) , tf_(tf.tf_)
+{
+}
+
+TransfertTabulate::~TransfertTabulate(void)
+{
+}
+
+void TransfertTabulate::SetInterpTyp(int typ)
+// see comment in InterpTab
+{
+ if(typ<0) typ=0; else if(typ>2) typ=2;
+ interptyp_ = typ;
+}
+
+double TransfertTabulate::operator() (double k)
+{
+ return InterpTab(k,k_,tf_,interptyp_);
+}
+
+int TransfertTabulate::ReadCMBFast(string filename)
+{
+ FILE *file = fopen(filename.c_str(),"r");
+ if(file==NULL) return -1;
+
+ const int lenline = 512;
+ char *line = new char[lenline];
+
+ int nread = 0;
+ double tmax = -1.;
+ while ( fgets(line,lenline,file) != NULL ) {
+   double k,tc,tb,tf;
+   sscanf(line,"%lf %lf %lf",&k,&tc,&tb);
+   k *= h100_;     // convert h^-1 Mpc  ->  Mpc
+   tf = (Oc_*tc+Ob_*tb)/(Oc_+Ob_);
+   if(tf>tmax) tmax = tf;
+   k_.push_back(k);
+   tf_.push_back(tf);
+   nread++;
+ }
+
+ cout<<"TransfertTabulate::ReadCMBFast: nread="<<nread<<" tf_max="<<tmax<<endl;
+ delete [] line;
+ if(nread==0) return nread;
+
+ for(unsigned int i=0;i<tf_.size();i++) tf_[i] /= tmax;
+
+ return nread;
+}
+
+///////////////////////////////////////////////////////////
+//********************* GrowthFactor ********************//
+///////////////////////////////////////////////////////////
+
+// From Eisenstein & Hu ApJ 496:605-614 1998 April 1
+// Pour avoir D(z) = 1/(1+z) faire: OmegaMatter0=1 OmegaLambda0=0
+GrowthFactor::GrowthFactor(double OmegaMatter0,double OmegaLambda0)
+  : O0_(OmegaMatter0) , Ol_(OmegaLambda0)
+{
+  if(OmegaMatter0==0.) {
+    cout<<"GrowthFactor::GrowthFactor: Error bad OmegaMatter0  value : "<<OmegaMatter0<<endl;
+    throw ParmError("GrowthFactor::GrowthFactor: Error badOmegaMatter0  value");
+  }
+}
+
+GrowthFactor::GrowthFactor(GrowthFactor& d1)
+  : O0_(d1.O0_) , Ol_(d1.Ol_)
+{
+}
+
+GrowthFactor::~GrowthFactor(void)
+{
+}
+
+double GrowthFactor::operator() (double z)
+// see Formulae A4 + A5 + A6 page 614
+{
+ z += 1.;
+ double z2 = z*z, z3 = z2*z;
+
+ // Calcul de la normalisation (pour z=0 -> growth=1.)
+ double D1z0 = pow(O0_,4./7.) - Ol_ + (1.+O0_/2.)*(1.+Ol_/70.);
+ D1z0 = 2.5*O0_ / D1z0;
+
+ // Calcul du growthfactor pour z
+ double Ok = 1. - O0_ - Ol_;
+ double den = Ol_ + Ok*z2 + O0_*z3;
+ double o0z = O0_ *z3 / den;
+ double olz = Ol_ / den;
+
+ double D1z = pow(o0z,4./7.) - olz + (1.+o0z/2.)*(1.+olz/70.);
+ D1z = 2.5*o0z / z / D1z;
+
+ return D1z / D1z0;
+}
+
+void GrowthFactor::SetParTo(double OmegaMatter0,double OmegaLambda0)
+{
+ if(OmegaMatter0>0.) O0_ = OmegaMatter0;
+ Ol_ = OmegaLambda0;
+}
+
+bool GrowthFactor::SetParTo(double OmegaMatter0)
+// idem precedent sans changer OmegaLambda0
+{
+ if(OmegaMatter0<=0.) return false;
+ O0_ = OmegaMatter0;
+ return true;
+}
+
+
+///////////////////////////////////////////////////////////
+//************** PkSpectrum0 et PkSpectrumZ *************//
+///////////////////////////////////////////////////////////
+
+PkSpectrum0::PkSpectrum0(InitialSpectrum& pkinf,TransfertEisenstein& tf)
+  : pkinf_(pkinf) , tf_(tf)
+{
+}
+
+PkSpectrum0::PkSpectrum0(PkSpectrum0& pk0)
+  : pkinf_(pk0.pkinf_) , tf_(pk0.tf_)
+{
+}
+
+PkSpectrum0::~PkSpectrum0(void)
+{
+}
+
+double PkSpectrum0::operator() (double k)
+{
+  double tf = tf_(k);
+  double pkinf = pkinf_(k);
+  return pkinf *tf*tf;
+}
+
+//------------------------------------
+PkSpectrumZ::PkSpectrumZ(PkSpectrum0& pk0,GrowthFactor& d1,double zref)
+  : pk0_(pk0) , d1_(d1) , zref_(zref) , scale_(1.) , typspec_(PK)
+{
+}
+
+PkSpectrumZ::PkSpectrumZ(PkSpectrumZ& pkz)
+  : pk0_(pkz.pk0_) , d1_(pkz.d1_) , zref_(pkz.zref_) , scale_(pkz.scale_) , typspec_(PK)
+{
+}
+
+PkSpectrumZ::~PkSpectrumZ(void) 
+{
+}
+
+void PkSpectrumZ::SetTypSpec(ReturnSpectrum typspec)
+// typsec = PK : compute Pk(k)
+//        = DELTA : compute Delta^2(k) = k^3*Pk(k)/2Pi^2
+{
+  typspec_ = typspec;
+}
+
+double PkSpectrumZ::operator() (double k)
+{
+  return (*this)(k,zref_);
+}
+
+double PkSpectrumZ::operator() (double k,double z)
+{
+  double d1 = d1_(z);
+
+  double v = pk0_(k) * d1*d1;
+  if(typspec_==DELTA) v *= k*k*k/(2.*M_PI*M_PI);
+
+  return scale_ * v;
+}
+
+
+
+///////////////////////////////////////////////////////////
+//******************* VarianceSpectrum ******************//
+///////////////////////////////////////////////////////////
+
+VarianceSpectrum::VarianceSpectrum(GenericFunc& pk,double R,TypeFilter typfilter)
+  : pk_(pk)
+{
+  SetRadius(R);
+  SetFilter(typfilter);
+}
+
+VarianceSpectrum::VarianceSpectrum(VarianceSpectrum& vpk)
+  : pk_(vpk.pk_) , R_(vpk.R_)
+{
+  SetFilter(vpk.typfilter_);
+}
+
+VarianceSpectrum::~VarianceSpectrum(void)
+{
+}
+
+void VarianceSpectrum::SetRadius(double R)
+// R = taille du filter top-hat ou gaussien
+{
+ if(R<=0.) {
+    cout<<"VarianceSpectrum::SetRadius: Error R<=0"<<endl;
+    throw ParmError("VarianceSpectrum::SetRadius: Error R<=0");
+  }
+  R_ = R;
+}
+
+//------------------------------------
+void VarianceSpectrum::SetFilter(TypeFilter typfilter)
+// typfilter = TOPHAT : spherical 3D top-hat
+//           = GAUSSIAN : spherical 3D gaussian
+//           = NOFILTER : no filter juste integrate spectrum)
+// Remarque:
+//   la meilleure approximation du filtre top-hat (R) est un filtre gaussien avec (Rg=R/sqrt(5))
+{
+  typfilter_ = typfilter;
+}
+
+void VarianceSpectrum::SetInteg(double dperc,double dlogkinc,double dlogkmax,unsigned short glorder)
+// ATTENTION: on n'integre pas f(k)*dk mais k*f(k)*d(log10(k))
+// see argument details in function IntegrateFuncLog (geneutils.cc)
+{
+  dperc_ = dperc;  if(dperc_<=0.) dperc_ = 0.1;
+  dlogkinc_ = dlogkinc;
+  dlogkmax_ = dlogkmax;
+  glorder_ = glorder;
+}
+
+
+//------------------------------------
+double VarianceSpectrum::Filter2(double x)
+// ATTENTION: c'est le filtre au carre qui est renvoye
+{
+  // Just integrate the spectrum without filtering
+  if(typfilter_ == NOFILTER) return 1.;
+
+  double x2 = x*x;
+  // Filtre gaussien G(x) = exp(-x^2/2)
+  //        remarque G(x)^2 = exp(-x^2)
+  // on prend le DL de G(x)^2 pour x->0 a l'ordre O(x^6)
+  //             DL(x) = 1-x^2*(1-x^2/2)
+  //             pour x<0.01  |DL(x)-G(X)^2|<2.0e-13
+  if(typfilter_ == GAUSSIAN)
+    if(x<0.01) return 1.-x2*(1.-x2/2.); else return exp(-x2);
+
+  // Filtre top-hat T(x) = 3*(sin(x)-x*cos(x))/x^3
+  // --- Gestion de la pseudo-divergence pour x->0
+  // on prend le DL de T(x)^2 pour x->0 a l'ordre O(x^7)
+  //             DL(x) = 1-x^2/5*(1-3*x^2/35*(1-4*x^2/81))
+  //             pour x<0.1  |DL(x)-T(X)^2|<2.5e-13
+  double f2=0.;
+  if(x<0.1) {
+    f2 = 1.-x2/5.*(1.-3.*x2/35.*(1.-4.*x2/81.));
+  } else {
+    f2 = 3.*(sin(x)-x*cos(x))/(x2*x);
+    f2 *= f2;
+  }
+  return f2;
+  
+}
+
+double VarianceSpectrum::Variance(double kmin,double kmax)
+// Compute variance of spectrum pk_ by integration
+// Input:
+//     kmin,kmax = bornes en k de l'integrale pour calculer la variance
+// Return:
+//     valeur de la variance (sigma^2)
+// Remarque:
+//   la variance renvoyee est la variance de la masse
+{
+  if(kmin<=0 || kmax<=0. || kmin>=kmax) {
+    cout<<"VarianceSpectrum::Variance: Error kmin<=0 or kmax<=0 or kmin>=kmax"<<endl;
+    throw ParmError("VarianceSpectrum::Variance: Error kmin<=0 or kmax<=0 or kmin>=kmax");
+  }
+
+  double lkmin = log10(kmin), lkmax = log10(kmax);
+
+  double var = IntegrateFuncLog(*this,lkmin,lkmax,dperc_,dlogkinc_,dlogkmax_,glorder_);
+
+  return var;
+}
+
+//------------------------------------
+double VarianceSpectrum::FindMaximum(double kmin,double kmax,double eps)
+// Retourne le maximum de la fonction a integrer
+// La recherche a lieu entre [kmin,kmax] par pas logarithmiques
+// Input:
+//     kmin,kmax : intervalle de recherche
+//     eps : precision requise sur les valeurs
+// Return:
+//     position (en k) du maximum
+{
+  if(kmin<=0 || kmax<=0. || kmin>=kmax) {
+    cout<<"VarianceSpectrum::FindMaximum: Error kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0"<<endl;
+    throw ParmError("VarianceSpectrum::FindMaximum: Error kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
+  }
+
+  int n = 10; // toujours >2
+  double lkmin = log10(kmin), lkmax = log10(kmax), dlk = (lkmax-lkmin)/n;
+
+  double lkfind=lkmin, pkfind=-1.;
+  while(1) {
+    for(int i=0; i<=n; i++) {
+      double lk = lkmin  + i*dlk;
+      double v = (*this)(pow(10.,lk));
+      if(v<pkfind) continue;
+      pkfind = v; lkfind = lk;
+    }
+    //cout<<"VarianceSpectrum::FindMaximum: lkfind="<<lkfind<<" pkfind="<<pkfind
+    //    <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
+    // --- Convergence si l'encadrement de "kfind" est tel que "dk/kfind<eps"
+    // On a dk = 10^(lkfind+dlk) - 10^(lkfind-dlk) = kfind * (10^(dlk) - 10^(-dlk))
+    if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
+    if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
+    if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
+    dlk = (lkmax-lkmin)/n;
+  }
+
+  return pow(10.,lkfind);
+}
+
+int VarianceSpectrum::FindLimits(double high,double &kmin,double &kmax,double eps)
+// Retourne "[kmin,kmax]" tel que la fonction a integrer soit "f(k) <= high"
+//   La recherche a lieu entre [kmin,kmax] par pas logarithmiques
+// Input:
+//     kmin,kmax : intervalle de recherche
+//     eps : precision requise sur les valeurs kmin et kmax
+// Output:
+//     kmin,kmax telles que "f(k) <= high"
+// Return:
+//     rc  = 0 si OK
+//     rc |= 1 "f(kmin) >= high"   (bit0 =1)
+//     rc |= 2 "f(kmax) >= high"   (bit1 =1)
+//     rc |= 4 "f(k) < high pour tout k"   (bit2 =1)
+{
+  if(kmin<=0 || kmax<=0. || kmin>=kmax  || eps<=0.) {
+    cout<<"VarianceSpectrum::FindLimits: Error kmin<=0 or kmax<=0 or kmin>=kmax or eps<=0"<<endl;
+    throw ParmError("VarianceSpectrum::FindLimits: Error kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
+  }
+
+  int n = 10; // toujours >2
+
+  int rc = 0;
+  double lkmin,lkmax,dlk,lkfind;
+
+  // --- Find kmin
+  lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
+  while(1) {
+    lkfind = lkmin;
+    for(int i=0;i<=n;i++) {
+      if( (*this)(pow(10,lkfind)) >= high ) break;
+      lkfind = lkmin + i*dlk;
+    }
+    //cout<<"VarianceSpectrum::FindLimits[kmin]: lkfind="<<lkfind
+    //    <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
+    if(fabs(lkfind-lkmax)<dlk/2.) {rc |= 4; return rc;} // protect against f(k)<high for all k
+    if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
+    if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
+    if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
+    dlk = (lkmax-lkmin)/n;
+  }
+  if(lkfind-lkmin<dlk/2.) rc |= 1;  // f(kmin) >= high
+  else kmin = pow(10.,lkmin);
+  //cout<<"rc="<<rc<<" lkmin="<<lkmin<<"  pk="<<(*this)(pow(10.,lkmin))<<endl;
+
+  // --- Find kmax
+  lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
+  while(1) {
+    lkfind=lkmax;
+    for(int i=0;i<=n;i++) {
+      if( (*this)(pow(10,lkfind)) >= high ) break;
+      lkfind -= dlk;
+      lkfind = lkmax - i*dlk;
+    }
+    //cout<<"VarianceSpectrum::FindLimits[kmax]: lkfind="<<lkfind
+    //    <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
+    if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
+    if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
+    if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
+    dlk = (lkmax-lkmin)/n;
+  }
+  if(lkmax-lkfind<dlk/2.) rc |= 2;  // f(kmax) >= high
+  else kmax = pow(10.,lkmax);
+  //cout<<"rc="<<rc<<" lkmax="<<lkmax<<"  pk="<<(*this)(pow(10.,lkmax))<<endl;
+
+  return rc;
+}
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/pkspectrum.h	(revision 3445)
@@ -0,0 +1,160 @@
+#ifndef PKSPECTRUM_SEEN
+#define PKSPECTRUM_SEEN
+
+#include "machdefs.h"
+#include "genericfunc.h"
+
+namespace SOPHYA {
+
+//-----------------------------------------------------------------------------------
+class InitialSpectrum : public GenericFunc {
+public:
+  InitialSpectrum(double n,double a=1.);
+  InitialSpectrum(InitialSpectrum& pkinf);
+  virtual ~InitialSpectrum(void);
+  virtual double operator() (double k) {return A_ * pow(k,n_);}
+  void SetNorm(double a) {A_ = a;}
+  void SetSlope(double n) {n_ = n;}
+protected:
+  double n_, A_;
+};
+
+//-----------------------------------------------------------------------------------
+class TransfertEisenstein : public GenericFunc {
+public:
+
+  typedef enum{ALL=0, CDM=1, BARYON=2} ReturnPart;
+
+  TransfertEisenstein(double h100,double OmegaCDM0,double OmegaBaryon0,double tcmb,bool nobaryon=false,int lp=0);
+  TransfertEisenstein(TransfertEisenstein& tf);
+  virtual ~TransfertEisenstein(void);
+  bool SetParTo(double h100,double OmegaCDM0,double OmegaBaryon0);
+  virtual double operator() (double k);
+  double KPeak(void);
+  void SetNoOscEnv(unsigned short nooscenv=0);
+  void SetReturnPart(ReturnPart retpart=ALL);
+  void SetPrintLevel(int lp=0);
+protected:
+  int lp_;
+  double O0_,Oc_,Ob_,h100_,tcmb_;
+  double th2p7_;
+  double zeq_,keq_,zd_,Req_,Rd_,s_,ksilk_,alphac_,betac_,bnode_,alphab_,betab_;
+  double alphag_;
+  double sfit_,kpeak_;
+
+  bool nobaryon_;
+  unsigned short nooscenv_;
+  ReturnPart retpart_;
+
+  double T0tild(double k,double alphac,double betac);
+  void Init_(void);
+  void zero_(void);
+};
+
+//-----------------------------------------------------------------------------------
+class TransfertTabulate : public GenericFunc {
+public:
+  TransfertTabulate(double h100,double OmegaCDM0,double OmegaBaryon0);
+  TransfertTabulate(TransfertTabulate& tf);
+  virtual ~TransfertTabulate(void);
+  virtual double operator() (double k);
+  int NPoints(void) {return k_.size();}
+  void SetInterpTyp(int typ=0);
+  int ReadCMBFast(string filename);
+protected:
+  double Oc_,Ob_,h100_;
+  double kmin_,kmax_;
+  int interptyp_;
+  vector<double> k_, tf_;
+};
+
+
+//-----------------------------------------------------------------------------------
+class GrowthFactor : public GenericFunc {
+public:
+  GrowthFactor(double OmegaMatter0,double OmegaLambda0);
+  GrowthFactor(GrowthFactor& d1);
+  virtual ~GrowthFactor(void);
+  virtual double operator() (double z);
+  void SetParTo(double OmegaMatter0,double OmegaLambda0);
+  bool SetParTo(double OmegaMatter0);
+protected:
+  double O0_,Ol_;
+};
+
+
+//-----------------------------------------------------------------------------------
+class PkSpectrum0 : public GenericFunc {
+public:
+  PkSpectrum0(InitialSpectrum& pkinf,TransfertEisenstein& tf);
+  PkSpectrum0(PkSpectrum0& pk0);
+  virtual ~PkSpectrum0(void);
+  virtual double operator() (double z);
+  InitialSpectrum& GetPkIni(void) {return pkinf_;}
+  TransfertEisenstein& GetTransfert(void) {return tf_;}
+protected:
+  InitialSpectrum& pkinf_;
+  TransfertEisenstein& tf_;
+};
+
+//-----------------------------------------------------------------------------------
+class PkSpectrumZ : public GenericFunc {
+public:
+  typedef enum {PK=0, DELTA=1} ReturnSpectrum;
+  PkSpectrumZ(PkSpectrum0& pk0,GrowthFactor& d1,double zref=0.);
+  PkSpectrumZ(PkSpectrumZ& pkz);
+  virtual ~PkSpectrumZ(void);
+  virtual double operator() (double k);
+  virtual double operator() (double k,double z);
+  void   SetZ(double z) {zref_ = z;}
+  double GetZ(void) {return zref_;}
+  void SetTypSpec(ReturnSpectrum typspec=PK);
+  void SetScale(double scale=1.) {scale_=scale;}
+  double GetScale(void) {return scale_;}
+  PkSpectrum0& GetPk0(void) {return pk0_;}
+  GrowthFactor& GetGrowthFactor(void) {return d1_;}
+protected:
+  PkSpectrum0& pk0_;
+  GrowthFactor& d1_;
+  double zref_, scale_;
+  ReturnSpectrum typspec_;
+};
+
+//-----------------------------------------------------------------------------------
+class VarianceSpectrum : public GenericFunc {
+public:
+
+  typedef enum {TOPHAT=0, GAUSSIAN=1, NOFILTER=2} TypeFilter;
+
+  VarianceSpectrum(GenericFunc& pk,double R,TypeFilter typfilter);
+  VarianceSpectrum(VarianceSpectrum& pkinf);
+  virtual ~VarianceSpectrum(void);
+
+  void SetRadius(double R);
+  void SetFilter(TypeFilter typfilter=TOPHAT);
+  void SetInteg(double dperc=0.1,double dlogkinc=-1.,double dlogkmax=-1.,unsigned short glorder=4);
+
+  double Variance(double kmin,double kmax);
+
+  // ATTENTION: La fonction a integrer est : f(k)dk = k^3*Pk(k)/(2Pi^2) *filter2(k*R) *dk/k
+  virtual double operator() (double k) {return k*k*pk_(k)*Filter2(k*R_)/(2.*M_PI*M_PI);}
+  double Filter2(double x);
+
+  // Aide a l'integration
+  double FindMaximum(double kmin,double kmax,double eps=1.e-3);
+  int FindLimits(double high,double &kmin,double &kmax,double eps=1.e-3);
+
+protected:
+
+  GenericFunc& pk_;
+  TypeFilter typfilter_;
+  double R_;
+
+  double dperc_,dlogkinc_,dlogkmax_;
+  unsigned short glorder_;
+
+};
+
+} // Fin du namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.cc	(revision 3445)
@@ -0,0 +1,323 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "pexceptions.h"
+
+#include "constcosmo.h"
+#include "planckspectra.h"
+
+namespace SOPHYA {
+
+/*
+----------------------------------------------------------------
+- UNITES:
+     Temperature en Kelvin  "K"
+     Frequence en GigaHertz  "Hz"
+     Longueur d'onde en Metre  "m"
+----------------------------------------------------------------
+- Frequence / Longeur d'onde
+ l = c/f ; f = c/l
+ dl = c/f^2 df = l^2/c df
+ df = c/l^2 dl = f^2/c dl
+ P[f] df = P[l] dl = P[f] c/l^2 dl = P[l] c/f^2 df
+----------------------------------------------------------------
+- Lois de Planck Wien et Rayleigh
+     Planck   H*Nu/(K*T) = H*C/(Lambda*K*T) quelconque
+     Wien     H*Nu/(K*T) = H*C/(Lambda*K*T) >> 1
+     Rayleigh H*Nu/(K*T) = H*C/(Lambda*K*T) << 1
+----------------------------------------------------------------
+- Les termes en facteur pour les lois de Planck Wien et Rayleigh
+        (la partie contenant l'exponentielle)
+ ainsi que pour les derivees des ces termes par rapport a la temperature
+ Planck:   1/[exp(H*f/(K*t))-1] = 1/[exp(HC/(l*K*t))-1]
+     der=  H*f/(K*t) /t * exp(HC/(l*K*t))/[exp(HC/(l*K*t))-1]^2
+ Wien:     1/exp(H*f/(K*t))
+     der=  H*f/(K*t) /t /exp(H*f/(K*t))
+ Rayleigh: 1/(H*f/(K*t))
+     der=  K/(H*f)
+ Pour x->0: compute exp(x)=1+x+x^2/2 for 1/(exp(x)-1)
+            soit 1/(exp(x)-1)  -> 1/(x+x^2/2)
+  car exp(x)-1 vaut zero plus vite que son DL a cause de la soustraction
+----------------------------------------------------------------
+ - RADIANCE (Brillance) en fonction de nu ou lambda
+ nombre de watts (ou photons par seconde)
+ radies par unite de surface par steradian et par hertz (ou metre)
+    2*f^2/c^2   * 1/(exp()-1)    ph/s/m^2/Sr/Hz
+    2*h*f^3/c^2 * 1/(exp()-1)    W/m^2/Sr/Hz
+    2*c/l^4     * 1/(exp()-1)    ph/s/m^2/Sr/m
+    2*h*c^2/l^5 * 1/(exp()-1)    W/m^2/Sr/m
+----------------------------------------------------------------
+ - EMITTANCE en fonction de nu ou lambda
+ nombre de watts (ou photons par seconde)
+ radies dans un hemisphere (2*PI sr)
+ par unite de surface et par hertz (ou metre)
+ ..quand on integre sur 2Pi sr il faut
+ ..multiplier par cos(theta)  -> facteur Pi uniquement
+    EMITTANCE = Pi * RADIANCE
+    2*Pi*f^2/c^2   * 1/(exp()-1)    ph/s/m^2/Hz
+    2*Pi*h*f^3/c^2 * 1/(exp()-1)    W/m^2/Hz
+    2*Pi*c/l^4     * 1/(exp()-1)    ph/s/m^2/m
+    2*Pi*h*c^2/l^5 * 1/(exp()-1)    W/m^2/m
+----------------------------------------------------------------
+ - DENSITE en fonction de nu ou lambda
+ nombre de joules (ou photons) par m^3  et par hertz (ou metre)
+   DENSITE = 4*Pi/c * RADIANCE
+   8*Pi*f^2/c^3    * 1/(exp()-1)    ph/m^3/Hz
+   8*Pi*h*f^3/c^3  * 1/(exp()-1)    J/m^3/Hz
+   8*Pi/l^4        * 1/(exp()-1)    ph/m^3/m
+   8*Pi*h*c/l^5    * 1/(exp()-1)    J/m^3/m
+----------------------------------------------------------------
+ - DENSITE d'energie totale  (loi de Stefan-Boltzman)
+   4*sigma*T^4/C   J/m^3
+   Sigma = 2*PI^5*K^4/(15.*C^2*H^3) = PI^2*K^4/(60.*Hbar^3*C2)
+----------------------------------------------------------------
+*/
+
+/*
+POUR TESTER LES LIMITES DE L'EXPONENTIELLE:
+1-/ copier/coller les lignes suivantes dans toto.icc
+double x=10.;
+for(int i=0;i<35;i++) {
+  double ex = exp(x);
+  double exm1a = x*(1.+x/2.*(1.+x/3.)),;
+  printf("x=%g exp(x)=%e exp(x)-1=%e dl=%e (d=%e)\n",x,ex,ex-1.,exm1a,ex-1.-exm1a);
+  x /= 10.;
+}
+2-/ executer sous spiapp: > c++execfrf toto.icc
+*/
+
+
+#define MAXARGEXP 100.    /* maxi = 709.7827128933840 */
+#define MINARGEXP 1.e-10  /* Replace exp(x) by DL for 1/(exp(x)-1) when x->0 */
+
+//************************************************************************
+// vitesse de la lumiere en m/s
+double CinM_ = SpeedOfLight_Cst*1e+3;
+// h/k pour une frequence en Hz
+double HsK_ = h_Planck_Cst/k_Boltzman_Cst;
+// hc/k pour une longeur d'onde en metre
+double HCsK_ = h_Planck_Cst*CinM_/k_Boltzman_Cst;
+
+//************************************************************************
+PlanckSpectra::PlanckSpectra(double T)
+  : T_(T) , spectraapprox_(PLANCK) , spectrafunc_(VALUE) , spectravar_(NU)
+  , spectraunit_(ANGSFLUX) , spectrapower_(POWER)
+{
+}
+
+PlanckSpectra::PlanckSpectra(PlanckSpectra& s)
+  : T_(s.T_) , spectraapprox_(s.spectraapprox_) , spectrafunc_(s.spectrafunc_) , spectravar_(s.spectravar_)
+  , spectraunit_(s.spectraunit_), spectrapower_(s.spectrapower_)
+{
+}
+
+PlanckSpectra::~PlanckSpectra(void)
+{
+}
+
+//************************************************************************
+void PlanckSpectra::SetSpectraApprox(SpectraApprox spectraapprox)
+// spectraapprox = PLANCK   : Planck spectra
+//               = RAYLEIGH : Rayleigh spectra
+//               = WIEN     : Wien spectra
+{
+  spectraapprox_ = spectraapprox;
+}
+
+void PlanckSpectra::SetSpectraFunc(SpectraFunc spectrafunc)
+// spectrafunc = VALUE : spectra
+//             = DERIV : derivative of spectra relative to temperature
+{
+  spectrafunc_ = spectrafunc;
+}
+
+void PlanckSpectra::SetSpectraVar(SpectraVar spectravar)
+// spectravar = NU     : variable is frequency (Hz)
+//            = LAMBDA : variable is wavelength (m)
+{
+  spectravar_ = spectravar;
+}
+
+void PlanckSpectra::SetSpectraPower(SpectraPower spectrapower)
+// spectrapower = POWER : in W/...
+//              = PHOTON : in photon/s/...
+{
+  spectrapower_ = spectrapower;
+}
+
+void PlanckSpectra::SetSpectraUnit(SpectraUnit spectraunit)
+// spectraunit = ANGSFLUX  : radiance   W/m^2/Sr/Hz  or ...
+//             = SFLUX     : emittance  W/m^2/Hz     or ... 
+//             = DENSENERG : density    J/m^3/Hz     or ...
+//             = EXPON     : just the function exp() or equivalent for Rayleigh
+{
+  spectraunit_ = spectraunit;
+}
+
+
+//************************************************************************
+double PlanckSpectra::F2L(double nu_or_lambda)
+// Convert frequency (GHz) to/from Wavelength (m)
+// Lambda(m) * Nu(GHz) = C(km/s) * 10^-6
+{
+  return CinM_ / nu_or_lambda;
+}
+
+//************************************************************************
+double PlanckSpectra::PlanckExp(double fl)
+{
+  double x = (spectravar_==LAMBDA) ? HCsK_/(fl*T_) : HsK_*fl/T_;
+
+  if(spectraapprox_ == RAYLEIGH) return 1./x;  // Rayleigh
+
+  if(x>MAXARGEXP) return 0.;
+
+  if(spectraapprox_ == WIEN) return exp(-x);  // Wien
+
+  if(x<MINARGEXP) return 1./(x*(1.+x/2.));
+  return 1./(exp(x)-1.);
+}
+
+double PlanckSpectra::DPlanckExp_DT(double fl)
+{
+  if(spectraapprox_ == RAYLEIGH)
+    return (spectravar_==LAMBDA) ? fl/HCsK_: 1. / (HsK_*fl);  // Rayleigh
+
+  double x = (spectravar_==LAMBDA) ? HCsK_/(fl*T_) : HsK_*fl/T_;
+
+  if(x>MAXARGEXP) return 0.;
+
+  if(spectraapprox_ == WIEN) return x/T_ * exp(-x);  // Wien
+
+  double v;
+  if(x<MINARGEXP) { // 1/(exp(x)-1)  -derive-> -exp(x)/(exp(x)-1)^2
+    v = x*(1.+x/2.);
+    return x/T_ * (1.+v)/(v*v);
+  }
+  v = exp(x);
+  return x/T_ * v/((v-1.)*(v-1.));  
+}
+
+//------------------------------------------------------------
+double PlanckSpectra::operator() (double x)
+{
+  // --- type de spectre et d'approximation selon choix variable
+  double fex = (spectrafunc_==DERIV) ? DPlanckExp_DT(x): PlanckExp(x);
+
+  // --- le coefficient multiplicateur devant l'expo
+  if(spectraunit_ == EXPON) return fex;  // expo seule
+
+  // radiance en ph/...               longeur d'onde         frequency
+  double coeff = (spectravar_==LAMBDA) ? 2.*CinM_/(x*x*x*x): 2.*x*x/(CinM_*CinM_);
+
+  if(spectraunit_ == SFLUX)      coeff *= M_PI;  // emittance en ph/...
+  else if(spectraunit_ == DENSENERG) coeff *= 4.*M_PI/CinM_;  // densite en ph/...
+
+  // unite en W/...                longeur d'onde         frequency
+  if(spectrapower_ == POWER)
+    coeff *= (spectravar_==LAMBDA) ? h_Planck_Cst*CinM_/x: h_Planck_Cst*x;
+
+  return coeff * fex;
+}
+
+//------------------------------------------------------------
+double PlanckSpectra::PlanckEnergie(void)
+//  densite d'energie: energie par m^3  en "J / m^3"
+// cste de Stefan-Boltzmann en W/m^2/K^4
+{
+  return 4.*StefBoltz_Cst*T_*T_*T_*T_/(SpeedOfLight_Cst*1000.);
+}
+
+//------------------------------------------------------------
+double PlanckSpectra::PlanckPhoton(void)
+//  densite de photons: nombre de photons par m^3  en "ph / m^3"
+{
+  double x = k_Boltzman_Cst*T_/(h_Planck_Cst*SpeedOfLight_Cst*1000.);
+  return 16.*M_PI*Zeta_3_Cst* x*x*x;
+}
+
+double PlanckSpectra::WienLaw(void)
+// Retourne la frequence (ou longeur d'onde) du maximum
+// du spectre de radiance (ou emittance ou densite).
+// La valeur du maximum depend de l'unite du spectre (W/... ou Ph/s/...)
+/*
+--- Les fonctions:
+En frequence: n = 3  en W/...  ,  n = 2  en Ph/...
+En longueur d'onde: n = 5  en W/...  ,  n = 4  en Ph/...
+f[x_] := x^n*Exp[-x]; Solve[f'[x]==0,x]   // Wien
+f[x_] := x^n/(Exp[x]-1); NSolve[f'[x]==0,x,17]  // Planck
+La derivee par rapport a T des fonctions en frequence:
+df/dT[x_] := x^(n+1)*Exp[-x]; Solve[f'[x]==0,x]  // Wien
+df/dT[x_] := x^(n+1)*Exp[x]/(Exp[x]-1)^2; NSolve[f'[x]==0,x,17]  // Planck
+*/
+{
+  double x=-1.;
+  if(spectravar_ == NU) { // Frequence
+    if(spectrafunc_ == VALUE) {  // Le spectre
+      if(spectrapower_ == POWER) //  W/...
+        {if(spectraapprox_==PLANCK) x=2.82143938074; else if(spectraapprox_==WIEN) x=3.;}
+      else if(spectrapower_ == PHOTON) //  Ph/s/...
+        {if(spectraapprox_==PLANCK) x=1.59362426; else if(spectraapprox_==WIEN) x=2.;}
+    } else if(spectrafunc_ == DERIV) {  // La derivee du spectre
+      if(spectrapower_ == POWER) //  W/... 
+        {if(spectraapprox_==PLANCK) x=3.830016095; else if(spectraapprox_==WIEN) x=4.;}
+      else if(spectrapower_ == PHOTON) //  Ph/s/...
+        {if(spectraapprox_==PLANCK) x=2.575678888; else if(spectraapprox_==WIEN) x=3.;}
+    }
+  } else { // Longeur d'onde
+    if(spectrafunc_ == VALUE) {  // Le spectre
+      if(spectrapower_ == POWER) //  W/...
+        {if(spectraapprox_==PLANCK) x=4.96511420; else if(spectraapprox_==WIEN) x=5.;}
+      else if(spectrapower_ == PHOTON) //  Ph/s/...
+        {if(spectraapprox_==PLANCK) x=3.9206904099; else if(spectraapprox_==WIEN) x=4.;}
+    } else if(spectrafunc_ == DERIV) {  // La derivee du spectre
+      if(spectrapower_ == POWER) //  W/...
+        {if(spectraapprox_==PLANCK) x=5.969409190; else if(spectraapprox_==WIEN) x=6.;}
+     else if(spectrapower_ == PHOTON) //  Ph/s/...
+        {if(spectraapprox_==PLANCK) x=4.928119345; else if(spectraapprox_==WIEN) x=5.;}
+    }
+  }
+
+  if(x<0.) return x;  // Rayleigh n'a pas de maximum
+  if(spectravar_ == NU) return x / HsK_ *T_; // Frequence
+  return HCsK_ / x /T_; // Longeur d'onde
+}
+
+double PlanckSpectra::FindMaximum(double eps)
+// Retourne le maximum des spectres (a la precicion eps)
+{
+  if(spectraapprox_ == RAYLEIGH) {  // Pas de maximum pour les spectres de Raleigh
+    cout<<"PlanckSpectra::FindMaximum : no maximum for Raleigh spectra"<<endl;
+    throw ParmError("PlanckSpectra::FindMaximum : no maximum for Raleigh spectra");
+  }
+  if(eps<=0.) eps = 0.001;
+
+  double xmax = WienLaw(), wmax=(*this)(xmax);
+  double xlim[2]={xmax,xmax};
+
+  // Encadrement du maximum par xlim[0] et xlim[1]
+  while( (*this)(xlim[1])>=0.01*wmax ) xlim[1] *= 2.;
+  while( (*this)(xlim[0])>=0.01*wmax ) xlim[0] /= 2.;
+  //cout<<"FindMaximum: wmax="<<wmax<<" pour x=["<<xlim[0]<<","<<xlim[1]<<"]"<<endl;
+
+  while( (xlim[1]-xlim[0])/xmax > eps ) {
+   wmax=-1.;
+   double dx = (xlim[1]-xlim[0])/10.;
+   for(double x=xlim[0]; x<=xlim[1]; x+=dx) {
+     double f=(*this)(x);
+     if(f>wmax) {wmax=f; xmax=x;}
+   }
+   //cout<<"...wmax="<<wmax<<" pour xmax="<<xmax<<" dx="<<dx<<endl;
+   xlim[0] = xmax-dx*1.1; xlim[1] = xmax+dx*1.1;
+ }
+
+
+  //cout<<"wmax="<<wmax<<" pour x="<<xmax<<"  dx="<<xlim[1]-xlim[0]<<endl;
+  return xmax;
+}
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/planckspectra.h	(revision 3445)
@@ -0,0 +1,56 @@
+#ifndef PLANCKSPECTRA_SEEN
+#define PLANCKSPECTRA_SEEN
+
+#include "machdefs.h"
+#include "genericfunc.h"
+
+namespace SOPHYA {
+
+//-----------------------------------------------------------------------------------
+class PlanckSpectra : public GenericFunc {
+public:
+
+  typedef enum {PLANCK=0, RAYLEIGH=1, WIEN=2} SpectraApprox;
+  typedef enum {POWER=0, PHOTON=1} SpectraPower;
+  typedef enum {VALUE=0, DERIV=1} SpectraFunc;
+  typedef enum {NU=0, LAMBDA=1} SpectraVar;
+  typedef enum {ANGSFLUX=0, SFLUX=1, DENSENERG=2, EXPON=3} SpectraUnit;
+
+  PlanckSpectra(double T);
+  PlanckSpectra(PlanckSpectra& s);
+  virtual ~PlanckSpectra(void);
+
+  inline void SetTemperature(double T) {T_ = T;}
+  inline double GetTemperature(void) {return T_;}
+
+  void SetSpectraApprox(SpectraApprox spectraapprox=PLANCK);
+  void SetSpectraFunc(SpectraFunc spectrafunc=VALUE);
+  void SetSpectraVar(SpectraVar spectravar=NU);
+  void SetSpectraUnit(SpectraUnit spectraunit=ANGSFLUX);
+  void SetSpectraPower(SpectraPower spectrapower=POWER);
+
+
+  virtual double operator() (double x);
+
+  double F2L(double nu_or_lambda);
+  double PlanckEnergie(void);
+  double PlanckPhoton(void);
+  double WienLaw(void);
+  double FindMaximum(double eps=0.001);
+
+protected:
+  double T_;
+  SpectraApprox spectraapprox_;
+  SpectraFunc spectrafunc_;
+  SpectraVar spectravar_;
+  SpectraUnit spectraunit_;
+  SpectraPower spectrapower_;
+
+  double PlanckExp(double fl);
+  double DPlanckExp_DT(double fl);
+
+};
+
+} // Fin du namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/Cosmo/SimLSS/schechter.cc
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/schechter.cc	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/schechter.cc	(revision 3445)
@@ -0,0 +1,473 @@
+#include "machdefs.h"
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "pexceptions.h"
+#include "histos.h"
+#include "perandom.h"
+#include "tvector.h"
+#include "fioarr.h"
+
+#include "constcosmo.h"
+#include "geneutils.h"
+#include "schechter.h"
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////
+//***************** Schechter Functions *****************//
+///////////////////////////////////////////////////////////
+
+// HI mass function:
+//    see M.Zwaan astroph-0502257 (MNRAS Letters, Volume 359, Issue 1, pp. L30-L34.)
+//    see M.Zwaan astroph-9707109 (ApJ, Volume 509, Issue 2, pp. 687-702.)
+
+Schechter::Schechter(double nstar,double mstar,double alpha)
+  : nstar_(nstar) , mstar_(mstar) , alpha_(alpha) , outvalue_(0)
+{
+}
+
+Schechter::Schechter(Schechter& f)
+  : nstar_(f.nstar_) , mstar_(f.mstar_) , alpha_(f.alpha_) , outvalue_(f.outvalue_)
+{
+}
+
+Schechter::Schechter(void)
+  : nstar_(0.) , mstar_(0.) , alpha_(0.) , outvalue_(0)
+{
+}
+
+Schechter::~Schechter(void)
+{
+}
+
+void Schechter::SetOutValue(unsigned short outvalue)
+// outvalue = 0 : give dn/dm
+//          = 1 : give m*dn/dm
+{
+  if(outvalue>1) {
+    cout<<"Schechter::SetOutValue: Error bad outvalue: "<<outvalue<<endl;
+    throw ParmError("Schechter::SetOutValue: Error bad outvalue");
+  }
+  outvalue_ = outvalue;
+}
+
+unsigned short Schechter::GetOutValue(void)
+{
+  return outvalue_;
+}
+
+void Schechter::SetParam(double nstar,double mstar,double alpha)
+{
+  nstar_ = nstar; mstar_ = mstar; alpha_ = alpha;
+}
+
+void Schechter::GetParam(double& nstar,double& mstar,double& alpha)
+{
+  nstar = nstar_; mstar = mstar_; alpha = alpha_;
+}
+
+double Schechter::operator() (double m)
+// Return : "dn/dm = f(m)" or "m*dn/dm = f(m)"
+{
+  double x = m/mstar_;
+  double dndm = nstar_/mstar_ * pow(x,alpha_) * exp(-x);
+  if(outvalue_) dndm *= m;  // on veut m*dn/dm
+  return dndm;
+}
+
+
+double Schechter::Integrate(double massmin,double massmax,int npt)
+// Integrate from massmin to massmax with at least npt points log10 spaced
+{
+ if(massmin<=0. || massmax<=0. || massmax<=massmin) return 0.;
+ if(npt<1) npt = 100;
+ double lmassmin = log10(massmin), lmassmax = log10(massmax);
+ double perc=0.01, dlxinc=(lmassmax-lmassmin)/npt, dlxmax=10.*dlxinc; unsigned short glorder=4;
+ double sum = IntegrateFuncLog(*this,lmassmin,lmassmax,perc,dlxinc,dlxmax,glorder);
+ return sum;
+}
+
+void Schechter::Print(void)
+{
+  cout<<"Schechter::Print: nstar="<<nstar_<<" Mpc^-3"
+      <<"  mstar="<<mstar_<<" MSol"
+      <<"  alpha="<<alpha_
+      <<"  (outvalue="<<outvalue_<<" -> return ";
+  if(outvalue_) cout<<"m*dn/dm)"; else cout<<"dn/dm)";
+  cout<<endl;
+}
+
+///////////////////////////////////////////////////////////
+//******* Les facilites pour tirer sur Schechter ********//
+///////////////////////////////////////////////////////////
+
+SchechterMassDist::SchechterMassDist(Schechter sch,double massmin,double massmax,int nbinmass)
+// On veut une fonction de tirage aleatoire de la masse de N galaxies sur une Schechter
+// Pour optimiser on cree (eventuellement) des histos de tirage
+// ATTENTION: on donne les limites en masses pour les histos mais leurs abscisses
+//   sont en log10(masse): histo [log10(massmin),log10(massmax)] avec nbinmass bins
+// Si nbinmass<0 alors c'est le nombre de points par decade
+  : sch_(sch) , sch_outvalue_(sch.GetOutValue())
+  , massmin_(massmin) , massmax_(massmax) , nbinmass_(nbinmass)
+  , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
+  , ntrial_dir(0) , ntrial_tab(0)
+  , hmdndm_(NULL) , tirhmdndm_(NULL)
+{
+  if(massmin_>massmax_  || massmin_<=0. || massmax_<=0.|| nbinmass_==0) {
+    cout<<"SchechterMassDist::SchechterMassDist: error in input values"<<endl;
+    throw ParmError("SchechterMassDist::SchechterMassDist: error in input values");
+  }
+
+  // Creation du tirage aleatoire sur la Schechter
+  sch_outvalue_ = sch.GetOutValue();  // on sauve la configuration de la schechter
+  sch.SetOutValue(1);  // on veut m*dN/dm
+  double lnx1 = log10(massmin_), lnx2 = log10(massmax_); // Binning en log10 de la masse
+  if(nbinmass_<0) nbinmass_ = int((-nbinmass_)*(lnx2-lnx1+1.));
+  hmdndm_ = new Histo(lnx1,lnx2,nbinmass_); hmdndm_->ReCenterBin();
+  FuncToHisto(sch,*hmdndm_,true);  // true -> bin en log10(x)
+  tirhmdndm_ = new FunRan(*hmdndm_,true);  // true -> histo est pdf
+  sch.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
+}
+
+SchechterMassDist::SchechterMassDist(void)
+  : sch_outvalue_(0)
+  , massmin_(0.) , massmax_(0.) , nbinmass_(0)
+  , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
+  , ntrial_dir(0) , ntrial_tab(0)
+  , hmdndm_(NULL) , tirhmdndm_(NULL)
+{
+}
+
+SchechterMassDist::~SchechterMassDist(void)
+{
+ Delete();
+}
+
+void SchechterMassDist::Delete(void)
+{
+ if(hmdndm_) delete hmdndm_;
+ if(tirhmdndm_) delete tirhmdndm_;
+ hmass_.resize(0);
+ tmass_.resize(0);
+ ntrial_dir = ntrial_tab = 0;
+}
+
+int SchechterMassDist::GetMassLim(double& massmin,double& massmax)
+{
+ massmin = massmin_;
+ massmax = massmax_;
+ return nbinmass_;
+}
+
+int SchechterMassDist::SetNgalLim(int ngalmax,int ngalmin,unsigned long nalea)
+// Creation des Histos de tirage pour ngalmin a ngalmax galaxies
+{
+ int lp=2;
+ ngalmin_=ngalmax_=nvalngal_=0;
+ if(ngalmin<=0) ngalmin=1;
+ if(ngalmax<ngalmin || ngalmax==1) return 0;
+ ngalmin_ = ngalmin;
+ ngalmax_ = ngalmax;
+ nvalngal_ = ngalmax-ngalmin+1;
+  
+ if(nalea<1) nalea = 100000;
+
+ if(lp>0) cout<<"SchechterMassDist::SetNgalLim: ngal=["
+              <<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_
+              <<" filling with "<<nalea<<" trials"<<endl;
+
+ //------- Construct histo
+ double lnx1 = log10(massmin_), lnx2 = log10(massmax_);
+ if(lp>0) cout<<"> Creating "<<nvalngal_<<" histos ["<<lnx1<<","<<lnx2<<"] n="<<nbinmass_<<endl;
+ for(int i=ngalmin_;i<=ngalmax_;i++) {
+   Histo h(*hmdndm_); h.Zero();
+   hmass_.push_back(h);
+ }
+ if(lp>1) cout<<"...number of histos is "<<hmass_.size()<<endl;
+
+ //------- Remplissage random
+ sch_.SetOutValue(1);  // on veut m*dN/dm
+ int lpmod = nalea/20; if(lpmod<=0) lpmod=1;
+ double s1=0., sc1=0.; unsigned long ns1=0;
+ double sax=0., scax=0.; unsigned long nsax=0;
+ for(unsigned long ia=0;ia<nalea;ia++) {
+   if(lp>1 && ia%lpmod==0) cout<<"...tirage "<<ia<<endl;
+   double sum = 0.;
+   for(int i=1;i<=ngalmax_;i++) {
+     //double l10m = tirhmdndm_->Random();
+     double l10m = tirhmdndm_->RandomInterp();
+     double m = pow(10.,l10m);
+     sum += m;
+     s1 += m; sc1 += m*m; ns1++;
+     int ipo = i-ngalmin_;
+     if(ipo<0) continue;
+     // ATTENTION: l'histo de tirage stoque le log10(moyenne=somme_masses/ngal).
+     //            Ca permet d'avoir le meme binning quelque soit ngal
+     double v = log10(sum/(double)i);
+     hmass_[ipo].Add(v);
+     if(i==ngalmax) {sax += sum/(double)i; scax += sum/(double)i*sum/(double)i; nsax++;}
+   }
+ }
+ sch_.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
+
+ if(ns1>1) {
+   s1 /= ns1; sc1 = sc1/ns1 - s1*s1;
+   cout<<"...Mean mass for ngal=1: "<<s1<<" ("<<log10(fabs(s1))<<")"
+       <<" s="<<sqrt(fabs(sc1))<<" (ntrials "<<ns1<<")"<<endl;
+ }
+ if(nsax>1) {
+   sax /= nsax; scax = scax/nsax - sax*sax;
+   cout<<"...Mean mass for ngal="<<ngalmax_<<": "<<sax<<" ("<<log10(fabs(sax))<<")"
+       <<" s="<<sqrt(fabs(scax))<<" (ntrials "<<nsax<<")"<<endl;
+ }
+
+ //------- Generation des classes de tirage aleatoire et des histos de verif
+ if(lp>0) cout<<"> Creating "<<nvalngal_<<" FunRan"<<endl;
+ for(unsigned int i=0;i<hmass_.size();i++) {
+   FunRan t(hmass_[i],true);
+   tmass_.push_back(t);
+ }
+ if(lp>1) cout<<"...number of funran is "<<tmass_.size()<<endl;
+
+ return nvalngal_;
+}
+
+int SchechterMassDist::GetNgalLim(int& ngalmax,int& ngalmin)
+{
+ ngalmax = ngalmax_;
+ ngalmin = ngalmin_;
+ return nvalngal_;
+}
+
+Histo SchechterMassDist::GetHmDnDm(void) const
+{
+  return *hmdndm_;
+}
+
+FunRan SchechterMassDist::GetTmDnDm(void) const
+{
+  return *tirhmdndm_;
+}
+
+Histo SchechterMassDist::GetHisto(int i) const
+{
+  if(i<0 || i>=nvalngal_) {
+    cout<<"SchechterMassDist::GetHisto: error in input values"<<endl;
+    throw ParmError("SchechterMassDist::GetHisto: error in input values");
+  }
+  return hmass_[i];
+}
+
+FunRan SchechterMassDist::GetFunRan(int i) const
+{
+  if(i<0 || i>=nvalngal_) {
+    cout<<"SchechterMassDist::GetFunRan: error in input values"<<endl;
+    throw ParmError("SchechterMassDist::GetFunRan: error in input values");
+  }
+  return tmass_[i];
+}
+
+double SchechterMassDist::TirMass(int ngal)
+{
+ if(ngal<1) return 0.;
+
+ int ipo = IndexFrNGal(ngal);
+ double masse_des_ngal = 0.;
+ if(ipo<0) {  // Pas d'histos de tirage pour ce nombre de galaxies
+   for(long i=0;i<ngal;i++) {  // On tire donc ngal fois sur la Schechter
+     // double lm = tirhmdndm_->Random();
+     double lm = tirhmdndm_->RandomInterp();
+     masse_des_ngal += pow(10.,lm);  // ATTENTION abscisse en log10(masse)
+   }
+   ntrial_dir++;
+ } else {
+   // ATTENTION l'histo de tirage stoque le log10(moyenne=somme_masses/ngal)
+   //double lmngal = tmass_[ipo].Random();
+   double lmngal = tmass_[ipo].RandomInterp();
+   masse_des_ngal = pow(10.,lmngal) * ngal;
+   ntrial_tab++;
+ }
+
+ return masse_des_ngal;
+}
+
+void SchechterMassDist::Print(void)
+{
+ cout<<"SchechterMassDist::Print: mass=["<<massmin_<<","<<massmax_<<"] n="<<nbinmass_<<endl
+     <<"                 ngal=["<<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_<<endl;
+ sch_.Print();
+}
+
+void SchechterMassDist::PrintStatus(void)
+{
+ cout<<"SchechterMassDist::PrintStatus: number of trials: direct="<<ntrial_dir
+     <<" tabulated="<<ntrial_tab<<endl;
+}
+
+void SchechterMassDist::WritePPF(string ppfname)
+{
+ char str[64];
+ cout<<"SchechterMassDist::WritePPF into "<<ppfname<<endl;
+ POutPersist pos(ppfname.c_str());
+
+ double nstar,mstar,alpha;
+ sch_.GetParam(nstar,mstar,alpha);
+ TVector<r_8> tdum(20); tdum = 0.;
+ tdum(0) = nstar;
+ tdum(1) = mstar;
+ tdum(2) = alpha;
+ tdum(3) = sch_outvalue_;
+ tdum(4) = massmin_;
+ tdum(5) = massmax_;
+ tdum(6) = nbinmass_;
+ tdum(7) = ngalmin_;
+ tdum(8) = ngalmax_;
+ tdum(9) = nvalngal_;
+ tdum(10) = hmass_.size();
+ tdum(11) = tmass_.size();
+ pos << PPFNameTag("SMDparam") << tdum;
+
+ pos << PPFNameTag("SMDhmdndm") << *hmdndm_;
+ pos << PPFNameTag("SMDtirhmdndm") << *tirhmdndm_;
+
+ if(hmass_.size()>0) {
+   for(unsigned int i=0;i<hmass_.size();i++) {
+     sprintf(str,"SMDh%d",NGalFrIndex(i));
+     pos << PPFNameTag(str) << hmass_[i];
+   }
+ }
+
+ if(tmass_.size()>0) {
+   for(unsigned int i=0;i<tmass_.size();i++) {
+     sprintf(str,"SMDt%d",NGalFrIndex(i));
+     Histo hdum(tmass_[i]);
+     pos << PPFNameTag(str) << hdum;
+   }
+ }
+
+}
+
+void SchechterMassDist::ReadPPF(string ppfname)
+{
+ Delete(); // On des-alloue si deja remplit!
+
+ char str[64];
+ cout<<"SchechterMassDist::ReadPPF from "<<ppfname<<endl;
+ PInPersist pis(ppfname.c_str());
+
+ TVector<r_8> tdum;
+ pis >> PPFNameTag("SMDparam") >> tdum;
+ sch_.SetParam(tdum(0),tdum(1),tdum(2));
+ sch_.SetOutValue((unsigned short)(tdum(3)+0.1));
+ massmin_ = tdum(4);
+ massmax_ = tdum(5);
+ nbinmass_ = int(tdum(6)+0.1);
+ ngalmin_ = int(tdum(7)+0.1);
+ ngalmax_ = int(tdum(8)+0.1);
+ nvalngal_ = int(tdum(9)+0.1);
+ unsigned int nhmass = (unsigned int)(tdum(10)+0.1);
+ unsigned int ntmass = (unsigned int)(tdum(11)+0.1);
+
+ {
+ Histo hdum;
+ pis >> PPFNameTag("SMDhmdndm") >> hdum;
+ hmdndm_ = new Histo(hdum);
+ pis >> PPFNameTag("SMDtirhmdndm") >> hdum;
+ tirhmdndm_ = new FunRan(hdum,false);
+ }
+
+ if(nhmass>0) {
+   for(unsigned int i=0;i<nhmass;i++) {
+     sprintf(str,"SMDh%d",NGalFrIndex(i));
+     Histo hdum;
+     pis >> PPFNameTag(str) >> hdum;
+     hmass_.push_back(hdum);
+   }
+ }
+
+ if(ntmass>0) {
+   for(unsigned int i=0;i<ntmass;i++) {
+     sprintf(str,"SMDt%d",NGalFrIndex(i));
+     Histo hdum;
+     pis >> PPFNameTag(str) >> hdum;
+     FunRan fdum(hdum,false);
+     tmass_.push_back(fdum);
+   }
+ }
+
+}
+
+///////////////////////////////////////////////////////////
+//***************** Fonctions de Check ******************//
+///////////////////////////////////////////////////////////
+
+bool IsCompatible(Schechter& sch1,Schechter& sch2,double eps)
+// on compare les differences a eps pres
+{
+  if(eps<=0.) eps=1.e-4;
+  double nstar1,mstar1,alpha1;
+  sch1.GetParam(nstar1,mstar1,alpha1);
+  double nstar2,mstar2,alpha2;
+  sch2.GetParam(nstar2,mstar2,alpha2);
+
+  // nstar et mstar ne sont jamais nuls
+  if(fabs(nstar1-nstar2)>fabs(nstar1+nstar2)/2.*eps) return false;
+  if(fabs(mstar1-mstar2)>fabs(mstar1+mstar2)/2.*eps) return false;
+
+  // alpha peut etre eventuellement nul
+  if(fabs(alpha1)<1.e-100 && fabs(alpha2)<1.e-100 && fabs(alpha1-alpha2)>eps) return false;
+  if(fabs(alpha1-alpha2)>fabs(alpha1+alpha2)/2.*eps) return false;
+  return true;
+}
+
+
+///////////////////////////////////////////////////////////
+//******************* Le Flux a 21cm ********************//
+///////////////////////////////////////////////////////////
+double Msol2LumiHI(double m)
+// Input:
+//    m : masse de HI en "Msol"
+// Return:
+//    la luminosite en W
+// L(m) =  2.393e+18* m(en masse solaire) en W
+{
+  return 2.393e+18 * m;
+}
+
+double Msol2FluxHI(double m,double d)
+// Input:
+//    m : masse de HI en "Msol"
+//    d : distance en "Mpc"  (si cosmo d=DLum(z))
+// Return:
+//    le flux total emis a 21 cm en W/m^2
+// Ref:
+// -- Binney & Merrifield, Galactic Astronomy p474 (ed:1998)
+// S(W/m^2) = 1e-26 * Nu_21cm(Hz) * m(en masse solaire) /(2.35e5 * C(km/s) * Dlum^2)
+//          = 2.0e-28 * m / Dlum^2
+// -- J.Peterson & K.Bandura, astroph-0606104  (eq 7)
+//    F.Abdalla & Rawlings, astroph-0411342 (eq 7 mais pb de d'unites?)
+//          (A_21cm = 2.86888e-15 s^-1)
+// S(W/m^2) = 3/4 * h(J.s) * Nu_21cm(Hz) * A_21cm(s^-1) * Msol(kg)/m_proton(kg)
+//                         / (4 Pi) / (Dlum(Mpc) * 3.0857e22(m/Mpc))^2
+//          = 2.0e-28 * m / Dlum^2
+//-------------
+{
+  return  2.0e-28 * m / (d*d);
+}
+
+double FluxHI2Msol(double f,double d)
+// Input:
+//    f : flux total emis a 21 cm en W/m^2
+//    d : distance en "Mpc"  (si cosmo d=DLum(z))
+// Return:
+//    m : masse de HI en "Msol"
+{
+  return f *d*d / 2.0e-28;
+}
+
+
+}  // Fin namespace SOPHYA
Index: /tags/V_Nov2007/Cosmo/SimLSS/schechter.h
===================================================================
--- /tags/V_Nov2007/Cosmo/SimLSS/schechter.h	(revision 3445)
+++ /tags/V_Nov2007/Cosmo/SimLSS/schechter.h	(revision 3445)
@@ -0,0 +1,101 @@
+#ifndef SCHECHTER_SEEN
+#define SCHECHTER_SEEN
+
+#include "machdefs.h"
+#include "genericfunc.h"
+
+namespace SOPHYA {
+
+class Histo;
+class FunRan;
+
+//-----------------------------------------------------------------------------------
+class Schechter : public GenericFunc {
+public:
+  Schechter(double nstar,double mstar,double alpha);
+  Schechter(Schechter& f);
+  Schechter(void);
+  virtual ~Schechter(void);
+
+  void SetOutValue(unsigned short outvalue=0);
+  unsigned short GetOutValue(void);
+  void SetParam(double nstar,double mstar,double alpha);
+  void GetParam(double& nstar,double& mstar,double& alpha);
+
+  virtual double operator() (double m);
+
+  double Integrate(double massmin,double massmax,int npt=100);
+
+  virtual void Print(void);
+
+protected:
+  double nstar_,mstar_,alpha_;
+  unsigned short outvalue_;
+};
+
+//-----------------------------------------------------------------------------------
+class SchechterMassDist : public AnyDataObj {
+  friend class ObjFileIO<SchechterMassDist>;
+public:
+  SchechterMassDist(Schechter sch,double massmin,double massmax,int nbinmass);
+  SchechterMassDist(void);
+  virtual ~SchechterMassDist(void);
+
+  int GetMassLim(double& massmin,double& massmax);
+  int SetNgalLim(int ngalmax,int ngalmin=1,unsigned long nalea=10000);
+  int GetNgalLim(int& ngalmax,int& ngalmin);
+  int GetNgalLim(void) {return nvalngal_;}
+  Schechter& GetSchechter(void) {return sch_;}
+
+  inline int IndexFrNGal(int ngal) {
+    int i = ngal-ngalmin_;
+    if(nvalngal_<1 || i<0) return -1;
+    if(i>=nvalngal_) return -2; else return i;
+  }
+  inline int NGalFrIndex(int i) {
+    if(nvalngal_<1 || i<0 || i>=nvalngal_) return -1;
+    return ngalmin_+i;
+  }
+
+  Histo GetHmDnDm(void) const;
+  FunRan GetTmDnDm(void) const;
+
+  Histo GetHisto(int i) const;
+  FunRan GetFunRan(int i) const;
+
+  double TirMass(int ngal);
+
+  void Print(void);
+  void PrintStatus(void);
+
+  void WritePPF(string ppfname);
+  void ReadPPF(string ppfname);
+
+protected:
+ void Delete(void);
+
+ Schechter sch_;
+ unsigned short sch_outvalue_;
+
+ double massmin_,massmax_;   int nbinmass_;
+ int ngalmin_,ngalmax_,nvalngal_;
+ unsigned long ntrial_dir, ntrial_tab;
+
+ Histo* hmdndm_;
+ FunRan* tirhmdndm_;
+
+ vector<Histo> hmass_;
+ vector<FunRan> tmass_;
+};
+
+//-----------------------------------------------------------------------------------
+bool IsCompatible(Schechter& sch1,Schechter& sch2,double eps=1.e-4);
+
+//-----------------------------------------------------------------------------------
+double Msol2LumiHI(double m);
+double Msol2FluxHI(double m,double d);
+double FluxHI2Msol(double f,double d);
+
+} // Fin du namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile	(revision 3445)
@@ -0,0 +1,697 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libFitsIOServer.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datacirclefits.o $(SOPHYAOBJP)fabtcolread.o $(SOPHYAOBJP)fabtwriter.o $(SOPHYAOBJP)fboloread.o $(SOPHYAOBJP)fbtntintf.o $(SOPHYAOBJP)fiosinit.o $(SOPHYAOBJP)fitsautoreader.o $(SOPHYAOBJP)fitsbntbllineRW.o $(SOPHYAOBJP)fitsfile.o $(SOPHYAOBJP)fitsgenedata.o $(SOPHYAOBJP)fitshdtable.o $(SOPHYAOBJP)fitshisterr.o $(SOPHYAOBJP)fitshistos.o $(SOPHYAOBJP)fitsinoutfile.o $(SOPHYAOBJP)fitslocalmap.o $(SOPHYAOBJP)fitsmanager.o $(SOPHYAOBJP)fitsntuple.o $(SOPHYAOBJP)fitsspherehealpix.o $(SOPHYAOBJP)fitsspherethetaphi.o $(SOPHYAOBJP)fitstarray.o $(SOPHYAOBJP)fitsxntuple.o $(SOPHYAOBJP)swfitsdtable.o
+	rm -f $(SOPHYALIBP)libFitsIOServer.a
+ 
+$(SOPHYALIBP)libFitsIOServer.a : $(SOPHYAOBJP)datacirclefits.o $(SOPHYAOBJP)fabtcolread.o $(SOPHYAOBJP)fabtwriter.o $(SOPHYAOBJP)fboloread.o $(SOPHYAOBJP)fbtntintf.o $(SOPHYAOBJP)fiosinit.o $(SOPHYAOBJP)fitsautoreader.o $(SOPHYAOBJP)fitsbntbllineRW.o $(SOPHYAOBJP)fitsfile.o $(SOPHYAOBJP)fitsgenedata.o $(SOPHYAOBJP)fitshdtable.o $(SOPHYAOBJP)fitshisterr.o $(SOPHYAOBJP)fitshistos.o $(SOPHYAOBJP)fitsinoutfile.o $(SOPHYAOBJP)fitslocalmap.o $(SOPHYAOBJP)fitsmanager.o $(SOPHYAOBJP)fitsntuple.o $(SOPHYAOBJP)fitsspherehealpix.o $(SOPHYAOBJP)fitsspherethetaphi.o $(SOPHYAOBJP)fitstarray.o $(SOPHYAOBJP)fitsxntuple.o $(SOPHYAOBJP)swfitsdtable.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)datacirclefits.o: datacirclefits.cc \
+  $(SOPHYAINCP)sopnamsp.h datacirclefits.h \
+  $(SOPHYAINCP)datacirclebase.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacirclefits.cc
+ 
+$(SOPHYAOBJP)fabtcolread.o: fabtcolread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fabtcolread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fabtcolread.cc
+ 
+$(SOPHYAOBJP)fabtwriter.o: fabtwriter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fabtwriter.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fabtwriter.cc
+ 
+$(SOPHYAOBJP)fboloread.o: fboloread.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fboloread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fabtcolread.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fboloread.cc
+ 
+$(SOPHYAOBJP)fbtntintf.o: fbtntintf.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fbtntintf.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fbtntintf.cc
+ 
+$(SOPHYAOBJP)fiosinit.o: fiosinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h fitsmanager.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshdtable.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitshandler.h \
+  fitsarrhand.h $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tvector.h fitsblkrw.h fitsntuple.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  fitsspherethetaphi.h \
+  $(SOPHYAINCP)spherethetaphi.h fitslocalmap.h \
+  $(SOPHYAINCP)localmap.h fitshistos.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h fitsgenedata.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiosinit.cc
+ 
+$(SOPHYAOBJP)fitsautoreader.o: fitsautoreader.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsautoreader.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  fitstarray.h $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h fitsntuple.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ppersist.h fitsxntuple.h \
+  $(SOPHYAINCP)xntuple.h fitslocalmap.h \
+  $(SOPHYAINCP)localmap.h fbtntintf.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsautoreader.cc
+ 
+$(SOPHYAOBJP)fitsbntbllineRW.o: fitsbntbllineRW.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsbntbllineRW.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)utils.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbntbllineRW.cc
+ 
+$(SOPHYAOBJP)fitsfile.o: fitsfile.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsfile.cc
+ 
+$(SOPHYAOBJP)fitsgenedata.o: fitsgenedata.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsgenedata.cc
+ 
+$(SOPHYAOBJP)fitshdtable.o: fitshdtable.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  swfitsdtable.h $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swsegdb.h fitsswapper.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshdtable.cc
+ 
+$(SOPHYAOBJP)fitshisterr.o: fitshisterr.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hist2err.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshisterr.cc
+ 
+$(SOPHYAOBJP)fitshistos.o: fitshistos.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshistos.cc
+ 
+$(SOPHYAOBJP)fitsinoutfile.o: fitsinoutfile.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)pexceptions.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsinoutfile.cc
+ 
+$(SOPHYAOBJP)fitslocalmap.o: fitslocalmap.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fitslocalmap.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitslocalmap.cc
+ 
+$(SOPHYAOBJP)fitsmanager.o: fitsmanager.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sopnamsp.h fitsmanager.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsmanager.cc
+ 
+$(SOPHYAOBJP)fitsntuple.o: fitsntuple.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsntuple.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsntuple.cc
+ 
+$(SOPHYAOBJP)fitsspherehealpix.o: fitsspherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)tarray.h fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsspherehealpix.cc
+ 
+$(SOPHYAOBJP)fitsspherethetaphi.o: fitsspherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsspherethetaphi.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)tarray.h fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsspherethetaphi.cc
+ 
+$(SOPHYAOBJP)fitstarray.o: fitstarray.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitstarray.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitstarray.cc
+ 
+$(SOPHYAOBJP)fitsxntuple.o: fitsxntuple.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsxntuple.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsxntuple.cc
+ 
+$(SOPHYAOBJP)swfitsdtable.o: swfitsdtable.cc swfitsdtable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swsegdb.h fitsswapper.h \
+  $(SOPHYAINCP)machdefs.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitsblkrw.h \
+  fitshandler.h fitshdtable.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  swfitsdtable.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/Makefile.mgr	(revision 3445)
@@ -0,0 +1,270 @@
+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)fitsspherethetaphi.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 fbtntintf.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)fitsspherethetaphi.o: fitsspherethetaphi.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsspherethetaphi.h \
+ $(INC)spherethetaphi.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 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_Nov2007/SophyaExt/FitsIOServer/datacirclefits.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/datacirclefits.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/datacirclefits.cc	(revision 3445)
@@ -0,0 +1,143 @@
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaExt/FitsIOServer/datacirclefits.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/datacirclefits.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/datacirclefits.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/FitsIOServer/extlib_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/extlib_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/extlib_list	(revision 3445)
@@ -0,0 +1,1 @@
+cfitsio
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/extslb_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/extslb_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/extslb_list	(revision 3445)
@@ -0,0 +1,1 @@
+cfitsio
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 3445)
@@ -0,0 +1,1660 @@
+/* Lecteur de colonne de table Fits (binaire ou ASCII) avec buffer */
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fabtcolread.h"
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for opening a FITS file for reading
+
+/*!
+  \class SOPHYA::FitsOpenFile
+  \ingroup FitsIOServer
+  Class for opening a FITS file for reading
+*/
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be opened for reading
+*/
+FitsOpenFile::FitsOpenFile(string fname)
+{
+  Init(fname.c_str());
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be opened for reading
+*/
+FitsOpenFile::FitsOpenFile(const char *cfname)
+{
+  Init(cfname);
+}
+
+/*!
+  Constructor by default.
+*/
+FitsOpenFile::FitsOpenFile()
+{
+  FitsFN = "";
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
+  FitsPtr = NULL;
+}
+
+/*!
+  Constructor by copy.
+*/
+FitsOpenFile::FitsOpenFile(FitsOpenFile& fof)
+{
+  Init(fof.FileName().c_str());
+}
+
+/*!
+  Destructor.
+*/
+FitsOpenFile::~FitsOpenFile()
+{
+  Delete();
+  FitsFN = "";
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
+}
+
+/*!
+  Delete routine called by the destructor.
+*/
+void FitsOpenFile::Delete(void)
+{
+  if(FitsPtr != NULL) {
+    int sta = 0;
+    if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+    FitsPtr = NULL;
+  }
+}
+
+/*! Init routine called by the constructor */
+void FitsOpenFile::Init(const char* fname)
+{
+  // Parametres Generaux
+  FitsFN = fname;
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
+  FitsPtr = NULL;
+
+  // Ouverture du fichier
+  if(FitsFN.size() <= 0 )
+     throw ParmError("FitsOpenFile::Init: Fits file name error\n");
+
+  int sta = 0;
+  if(fits_open_file(&FitsPtr,FitsFN.c_str(),READONLY,&sta)) {
+    printerror(sta);
+    FitsPtr = NULL;
+    throw NullPtrError("FitsOpenFile::Init: Error opening Fits file\n");
+  }
+
+  // Get number of hdu
+  if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
+    printerror(sta);
+    NHdu = 0;
+    Delete();
+    throw NotAvailableOperation("FitsOpenFile::Init: Error getting NHdu\n");
+  }
+  if(NHdu<=0) {
+    Delete();
+    throw SzMismatchError("FitsOpenFile::Init: Bad NHdu\n");
+  }
+
+  MoveToHDU(1);
+}
+
+/*! Move to an HDU
+\param ihdu: hdu number to move
+\warning ihdu = [1,nhdu]
+\return 0 if positionning failed, ihdu if success
+*/
+int FitsOpenFile::MoveToHDU(int ihdu)
+{
+ if(FitsPtr==NULL)
+   throw NullPtrError("FitsOpenFile::MoveToHDU: no fits file open FitsPtr==NULL\n");
+ int ihdusave = IHdu;
+ if(ihdu<=0) ihdu=1; if(ihdu>NHdu) ihdu=NHdu;
+ int sta=0;
+ if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) {
+   printerror(sta);
+   // On se repositionne ou on etait
+   fits_movabs_hdu(FitsPtr,ihdusave,&HduType,&sta);
+   IHdu = ihdusave;
+ } else IHdu = ihdu;
+ return IHdu;
+}
+
+/*! Move to the first HDU of a certain type
+\param hdutype: type of the hdu
+\param hdudeb: start at that hdu
+\return the type of HDU the file is positionned
+*/
+int FitsOpenFile::MoveToFirst(int hdutype,int ihdudeb)
+{
+ if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
+ int ihdusave = IHdu;
+ for(int ihdu=ihdudeb;ihdu<=NHdu;ihdu++) {
+   MoveToHDU(ihdu);
+   if(HduType==hdutype) break;
+ }
+ // Si echec, on se repositionne ou on etait
+ if(HduType!=hdutype) MoveToHDU(ihdusave);
+ return HduType;
+}
+
+/*! Move to the last HDU of a certain type
+\param hdutype: type of the hdu
+\param hdudeb: stop at that hdu
+\return the type of HDU the file is positionned
+*/
+int FitsOpenFile::MoveToLast(int hdutype,int ihdudeb)
+{
+ if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
+ int ihdusave = IHdu;
+ for(int ihdu=NHdu;ihdu>=ihdudeb;ihdu--) {
+   MoveToHDU(ihdu);
+   if(HduType==hdutype) break;
+ }
+ // Si echec, on se repositionne ou on etait
+ if(HduType!=hdutype) MoveToHDU(ihdusave);
+ return HduType;
+}
+
+/*! Print */
+void FitsOpenFile::Print(void)
+{
+ cout<<"FitsOpenFile::Print: "<<FitsFN
+     <<" hdu="<<IHdu<<"/"<<NHdu<<" type="<<HduType
+     <<" hasbeenpos="<<HasBeenPos<<endl;
+}
+
+//////////////////////////////////////////////////////////////
+//// Methodes statiques
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsOpenFile::ReadKey(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL || fitsptr==NULL) return 0.;
+ int sta=0; double val=0.;
+ if(fits_read_key(fitsptr,TDOUBLE,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+/*!
+  Read a fitsheader key into long
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsOpenFile::ReadKeyL(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL || fitsptr==NULL) return 0;
+ int sta=0; long val=0;
+ if(fits_read_key(fitsptr,TLONG,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+/*!
+  Read a fitsheader key into long
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into long long
+*/
+LONGLONG FitsOpenFile::ReadKeyLL(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL || fitsptr==NULL) return 0;
+ int sta=0; LONGLONG val=0;
+ if(fits_read_key(fitsptr,TLONGLONG,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+/*!
+  Read a fitsheader key into string
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsOpenFile::ReadKeyS(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL || fitsptr==NULL) return (string)"";
+ int sta=0; char val[FLEN_VALUE];
+ if(fits_read_key(fitsptr,TSTRING,keyname,val,NULL,&sta))
+   printerror(sta);
+ string sval = val;
+ return sval;
+}
+
+/*!
+  CFitsIO error printing routine
+  \param sta : cfitio error return code
+*/
+ void FitsOpenFile::printerror(int sta)
+ {
+  int stat = sta;
+  fits_report_error(stdout,stat);
+  fflush(stdout);
+  return;
+ }
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a column in a FITS ASCII or BINARY table
+
+/*!
+  \class SOPHYA::FitsABTColRd
+  \ingroup FitsIOServer
+  Class for reading a column in a FITS ASCII or BINARY table.
+  You can read many columns of the same FITS table by instanciating
+  many FitsABTColRd on the same FitsOpenFile. So, the FITS file is
+  opened only once. Of course the various FitsABTColRd must read
+  the same FITS file HDU.
+  \verbatim
+  -- Exemple:
+  // Open the fits file with FitsOpenFile
+  FitsOpenFile fof = new FitsOpenFile("myfits.fits");
+  // Select the column to be read
+  FitsABTColRd fbt(fof,"BoloMuv_28",0,1000,1,3);
+  FitsABTColRd fbt2(fof,"BoloMuv_29",0,1000,1,3);
+  fbt.SetDebug(3);
+  fbt.Print(3);
+  // Read element by element
+  for(LONGLONG i=0;i<fbt.GetNbLine();i++) {
+    double x = fbt.Read(i);
+    double y = fbt2.Read(i);
+    if(i%lpmod==0) cout<<i<<": "<<x<<", "<<y<<endl;
+  }
+  // Read into a vector
+  TVector<double> data;
+  LONGLONG 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;
+  TVector<double> data2;
+  fbt2.Read(32,50,data);
+  // Close the fits file
+  delete fof;
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fof : Pointer to the Class for opening the FITS file
+  \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 first BINARY or ASCII table is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  - bsens>0    read forward
+    bsens<0    read backward
+    bsens==0   read centered
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,string collabel
+                          ,int ihdu,long blen,long bsens,int lp)
+{
+  Init(fof,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[
+*/
+FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,int colnum
+                          ,int ihdu,long blen,long bsens,int lp)
+{
+  Init(fof,"",colnum,ihdu,blen,bsens,lp);
+}
+
+/*! Constructor by copy */
+FitsABTColRd::FitsABTColRd(FitsABTColRd& fbt)
+{
+  Init(fbt.GetFitsOpenFile(),fbt.GetColLabel().c_str()
+      ,fbt.GetColNum(),fbt.HDU()
+      ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
+}
+
+/*! Constructor by default */
+FitsABTColRd::FitsABTColRd()
+{
+ ColLabel = ""; ColTUnit = ""; ColTForm = "";
+ ColNum = -1; ColTypeCode = 0;
+ NBcol = 0; NBline = 0;
+ SetNulVal(); SetDebug(0);
+ NFitsRead = 0;
+ FitsOF = NULL;
+ LineDeb = LineFin = -1;
+ Buffer = NULL;
+}
+
+/*! Init routine called by the constructor */
+void FitsABTColRd::Init(FitsOpenFile* fof,const char* collabel,int colnum
+                        ,int ihdu,long blen,long bsens,int lp)
+{
+ // Initialisation des Parametres Generaux
+ ColLabel=collabel; ColTUnit=""; ColTForm=""; ColNum=colnum; ColTypeCode=0;
+ NBcol = 0; NBline = 0;
+ SetNulVal(); SetDebug(lp);
+ NFitsRead = 0;
+ FitsOF = NULL;
+ LineDeb = LineFin = -1;
+ Buffer = NULL;
+
+ // Caracteristiques du FitsOpenFile
+ FitsOF = fof;
+ if(FitsOF==NULL)
+   throw NullPtrError("FitsABTColRd::Init: FitsOpenFile pointer is NULL\n");
+
+ if(GetFitsPtr()==NULL)
+   throw NullPtrError("FitsABTColRd::Init: FitsPtr pointer is NULL\n");
+
+ int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
+
+ // Get HDU for bin/ascii table
+ // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
+ // une classe utilisant ce fichier doit le positionner sur un HDU.
+ // Par contre, si une autre classe utilise ce meme FitsOpenFile,
+ // elle ne peut le positionner que sur ce meme HDU !
+ if(FitsOF->GetPosStatus()==false) {
+   if(ihdu==0) { // find the first BINARY then the first ASCII
+     int rc = FitsOF->MoveToFirst(BINARY_TBL);
+     if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
+   } else {
+     int rc = FitsOF->MoveToHDU(ihdu);
+     if(rc!=ihdu)
+       throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
+   }
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
+ }
+
+ // Check HDUType and set position status to TRUE
+ if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
+   throw TypeMismatchExc("FitsABTColRd::Init: HDU not ASCII/BINARY table\n");
+ if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
+ FitsOF->SetPosStatus(true);
+
+ // Get number of columns
+ if(fits_get_num_cols(GetFitsPtr(),&NBcol,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of columns\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBcol="<<NBcol<<endl;
+ if(NBcol<1)
+   throw RangeCheckError("FitsABTColRd::Init: Bad number of colums\n");
+
+ // Get number of rows
+ if(fits_get_num_rowsll(GetFitsPtr(),&NBline,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of rows\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBline="<<NBline<<endl;
+ if(NBline<1)
+   throw RangeCheckError("FitsABTColRd::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(GetFitsPtr(),CASESEN,labelcol,&ColNum,&sta)) {
+     FitsOpenFile::printerror(sta);
+     throw NotAvailableOperation("FitsABTColRd::Init: Error getting column name\n");
+   }
+   ColNum--;  // Convention [0,ncol[
+ }
+ if(DbgLevel>1) cout<<"...Init  ColNum="<<ColNum<<endl;
+ if(ColNum<0 || ColNum>=NBcol)
+   throw RangeCheckError("FitsABTColRd::Init: Bad column number\n");
+
+ // Get column type
+ if(fits_get_coltypell(GetFitsPtr(),ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw ParmError("FitsABTColRd::Init: Error getting column type\n");
+ }
+ if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
+ if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX ||  ColTypeCode==TDBLCOMPLEX
+                         || ColTypeCode<0 )
+   throw ParmError("FitsABTColRd::Init: Selected column is not Numerical\n");
+
+ // Get column name back, tunit, tform
+ char tunit[64], tform[64], tdisp[64];
+ LONGLONG repeat=0; double tscale=1., tzero=0.;
+ int rc=0;
+ if(HDUType()==BINARY_TBL) {
+   fits_get_bcolparmsll(GetFitsPtr(),ColNum+1,labelcol,tunit,tform
+                     ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
+ } else {
+   long repeatlng;
+   fits_get_acolparms(GetFitsPtr(),ColNum+1,labelcol,&repeatlng,tunit,tform
+                     ,&tscale,&tzero,NULL,tdisp,&sta);
+   repeat = repeatlng;
+ }
+ if(rc) {
+   FitsOpenFile::printerror(sta);
+   throw RangeCheckError("FitsABTColRd::Init: Error getting the column caracteristics\n");
+ }
+ ColLabel = labelcol;
+ ColTUnit = tunit;
+ ColTForm = tform;
+
+ // Set the buffer for reading
+ ChangeBuffer(blen,bsens);
+
+ if(DbgLevel)
+   cout<<"FitsABTColRd::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. */
+FitsABTColRd::~FitsABTColRd()
+{
+ Delete();
+}
+
+/*! Delete called by the destructor */
+void FitsABTColRd::Delete(void)
+{
+ if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
+ LineDeb = LineFin = -1;
+ //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
+}
+
+//////////////////////////////////////////////////////////////
+/*! Change the buffer caracteristiques (see creator) */
+void FitsABTColRd::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;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsABTColRd::ReadKey(char *keyname)
+{
+ return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsABTColRd::ReadKeyL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long long
+  \param keyname : name of the key
+  \return value into long long
+*/
+LONGLONG FitsABTColRd::ReadKeyLL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into string
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsABTColRd::ReadKeyS(char *keyname)
+{
+ return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
+}
+
+/////////////////////////////////////////////////
+/*!
+  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 FitsABTColRd::Read(LONGLONG n,bool usebuffer)
+// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
+// Attention: colnum  [0,NBcol[ , cfistio veut [1,NBcol]
+{
+ int sta=0;
+ if(n<0 || n>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read try to read outside line range\n");
+
+ // Pas de bufferisation, on lit betement
+ if(NBuffer==1 || !usebuffer) {
+   NFitsRead++;
+   double val;
+   fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     throw NotAvailableOperation("FitsABTColRd::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("FitsABTColRd::Read: Buffer not allocated\n");
+ if(n<LineDeb || n>LineFin) {
+   NFitsRead++;
+   LONGLONG row1,row2,nrow;
+   if(BuffSens>0) { // Cas remplissage forward
+     row1 = n+1;
+     row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
+   } else if(BuffSens<0) { // Cas remplissage backward
+     row2 = n+1;
+     row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
+   } else { // Cas remplissage centre
+     row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
+     row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
+   }
+   nrow = row2 - row1 + 1;
+   LineDeb = row1-1; LineFin = row2-1;
+   //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
+   //    <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
+   fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     LineDeb = LineFin = -1;
+     throw NotAvailableOperation("FitsABTColRd::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
+*/
+LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ LONGLONG nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Read_TVector<double>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of float */
+LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ LONGLONG nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ fits_read_col(GetFitsPtr(),TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Read_TVector<float>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of unsigned short */
+LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<uint_2>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ LONGLONG nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ int sta=0;
+ fits_read_col(GetFitsPtr(),TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Read_TVector<uint_2>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of int_4 */
+LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ LONGLONG nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ fits_read_col(GetFitsPtr(),T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_4>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of int_8 */
+LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_8>& data)
+{
+#ifdef TLONGLONG
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ LONGLONG nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ int sta=0;
+ fits_read_col(GetFitsPtr(),TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_8>: Error Reading Fits file\n");
+ }
+
+ return nread;
+#else
+  throw PException("FitsABTColRd::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
+*/
+LONGLONG FitsABTColRd::FirstRow(double val1,double val2,LONGLONG rowstart)
+{
+ LONGLONG 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(LONGLONG 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
+*/
+LONGLONG FitsABTColRd::LastRow(double val1,double val2,LONGLONG rowstart)
+{
+ LONGLONG 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(LONGLONG 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;
+}
+
+/*! Print on stream os */
+void FitsABTColRd::Print(ostream& os,int lp) const
+{
+ os<<"FitsABTColRd:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
+   <<" ncols="<<NBcol<<" nrows="<<NBline;
+ if(lp>0) os<<" NRead="<<NFitsRead;
+ os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"
+   <<"\n... Label["<<ColNum<<"]="<<ColLabel<<" TypeCode="<<ColTypeCode
+   <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
+   <<endl;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for reading a column in a FITS ASCII or BINARY table with fits file opening
+
+/*!
+  \class SOPHYA::FitsABTColRead
+  \ingroup FitsIOServer
+  Class for reading a column in a FITS ASCII or BINARY table with fits file opening.
+  The FITS file is opened each time you instanciate a FitsABTColRead.
+  So reading "n" columns of the same FITS table by instanciating "n"
+  FitsABTColRead, will open "n" times te FITS file.
+  Use FitsABTColRd if you want to open the FITS file only once.
+  \verbatim
+  -- Exemple:
+  FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
+  fbt.SetDebug(3);
+  fbt.Print(3);
+  // Read element by element
+  for(LONGLONG 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;
+  LONGLONG 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 first BINARY or ASCII table is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  - 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)
+: FitsABTColRd(new FitsOpenFile(fname),collabel,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)
+: FitsABTColRd(new FitsOpenFile(fname),colnum,ihdu,blen,bsens,lp)
+{
+}
+
+/*! Constructor. see below */
+FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
+                              ,int ihdu,long blen,long bsens,int lp)
+: FitsABTColRd(new FitsOpenFile(cfname),collabel,ihdu,blen,bsens,lp)
+{
+}
+
+/*! Constructor. see below */
+FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
+                              ,int ihdu,long blen,long bsens,int lp)
+: FitsABTColRd(new FitsOpenFile(cfname),colnum,ihdu,blen,bsens,lp)
+{
+}
+/*! Constructor by default */
+FitsABTColRead::FitsABTColRead()
+: FitsABTColRd()
+{
+}
+
+/*! Constructor by copy */
+FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
+{
+ // --- ATTENTION ---
+ // FitsABTColRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
+ FitsOpenFile* fof = new FitsOpenFile(*fbt.GetFitsOpenFile());
+ Init(fof,fbt.GetColLabel().c_str()
+     ,fbt.GetColNum(),fbt.HDU()
+     ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
+}
+
+/*! Destructor. */
+FitsABTColRead::~FitsABTColRead()
+{
+ Delete(); // ?? inutile ??
+ // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
+ if(FitsOF!=NULL) delete FitsOF;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for reading a 2D image from a FITS file
+
+/*!
+  \class SOPHYA::FitsImg2DRd
+  \ingroup FitsIOServer
+  Class for reading a 2D image from a FITS file
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fof : Pointer to the Class for opening the FITS file
+  \param ihdu : number of the HDU where the image is.
+  \param lp : debug level
+  \verbatim
+  - if ihdu<=0 first IMAGE hdu is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsImg2DRd::FitsImg2DRd(FitsOpenFile* fof,int ihdu,int lp)
+{
+ Init(fof,ihdu,lp);
+}
+
+/*! Constructor by copy */
+FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
+{
+ Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
+}
+
+/*! Constructor by default */
+FitsImg2DRd::FitsImg2DRd()
+{
+ Naxis[0] = Naxis[1] = 0;
+ SetNulVal(); SetDebug(0);
+ FitsOF = NULL;
+}
+
+/*! Init routine called by the constructor */
+void FitsImg2DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
+{
+ // Initialisation des Parametres Generaux
+ Naxis[0] = Naxis[1] = 0;
+ SetNulVal(); SetDebug(lp);
+ FitsOF = NULL;
+
+ // Caracteristiques du FitsOpenFile
+ FitsOF = fof;
+ if(FitsOF==NULL)
+   throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
+
+ if(GetFitsPtr()==NULL)
+   throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
+
+ int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU(); 
+
+ // Get HDU 2D image
+ // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
+ if(FitsOF->GetPosStatus()==false) {
+   if(ihdu==0) { // find the first IMAGE_HDU
+     FitsOF->MoveToFirst(IMAGE_HDU);
+   } else {
+     int rc = FitsOF->MoveToHDU(ihdu);
+     if(rc!=ihdu)
+       throw RangeCheckError("FitsImg2DRd::Init: Error moving to requested HDU\n");
+   }
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsImg2DRd::Init: file already posit. at another HDU\n");
+ }
+
+ // Check HDUType and set position status to TRUE
+ if(HDUType()!=IMAGE_HDU)
+   throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
+ FitsOF->SetPosStatus(true);
+
+ // Get NAXIS 1 et 2
+ int nfound=0;
+ // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
+ if(ffgknjj(GetFitsPtr(),"NAXIS",1,2,Naxis,&nfound,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw RangeCheckError("FitsImg2DRd::Init: Error reading NAXIS cards\n");
+ }
+ if(DbgLevel>1)
+   cout<<"...Init(hdu="<<HDU()<<")  NAXIS1="<<Naxis[0]<<" NAXIS2="
+       <<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
+ if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
+   throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
+
+}
+
+/*! Destructor. */
+FitsImg2DRd::~FitsImg2DRd()
+{
+ //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
+ Naxis[0] = Naxis[1] = 0;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsImg2DRd::ReadKey(char *keyname)
+{
+ return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsImg2DRd::ReadKeyL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long long
+  \param keyname : name of the key
+  \return value into long long
+*/
+LONGLONG FitsImg2DRd::ReadKeyLL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into string
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsImg2DRd::ReadKeyS(char *keyname)
+{
+ return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
+}
+
+//////////////////////////////////////////////////////////////
+/* REMARQUE:
+ * Si une image FITS a NAXIS1=100 et NAXIS2=50
+ * alors un tableau 2D juste assez grand pour contenir l'image
+ * doit etre declare array[50][100] (et non pas array[100][50])
+ *                   array[NAXIS2][NAXIS1]
+ */
+/*!
+Read image into a TMatrix<uint_2>
+\warning TMatrix data(Naxis2,Naxis1)
+*/
+LONGLONG FitsImg2DRd::Read(TMatrix<uint_2>& data)
+{
+ int sta=0;
+ uint_2* arr = new uint_2[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<uint_2>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+}
+
+/*! Read image into a TMatrix<int_4> */
+LONGLONG FitsImg2DRd::Read(TMatrix<int_4>& data)
+{
+ int sta=0;
+ int_4* arr = new int_4[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+
+ for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_4>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+}
+
+/*! Read image into a TMatrix<int_8> */
+LONGLONG FitsImg2DRd::Read(TMatrix<int_8>& data)
+{
+ int sta=0;
+ int_8* arr = new int_8[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_8>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+}
+
+/*! Read image into a TMatrix<float> */
+LONGLONG FitsImg2DRd::Read(TMatrix<float>& data)
+{
+ int sta=0;
+ float* arr = new float[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<float>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+}
+
+/*! Read image into a TMatrix<double> */
+LONGLONG FitsImg2DRd::Read(TMatrix<double>& data)
+{
+ int sta=0;
+ double* arr = new double[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<double>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+}
+
+/*! Read image pixel numcol,numrow with numcol=[0,Naxis1[ and numrow=[0,Naxis2[ */
+double FitsImg2DRd::Read(LONGLONG numcol, LONGLONG numrow)
+{
+ int sta=0;
+ if(numcol<0 || numrow<0 || numcol>=Naxis[0] || numrow>=Naxis[1])
+   throw
+     NotAvailableOperation("FitsImg2DRd::Read(col,row): bad col/row number\n");
+
+   LONGLONG deb = numrow*Naxis[0] + numcol + 1;
+   double val = 0.;
+   fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
+
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(col,num): Error Reading Fits file\n");
+   }
+
+   return val;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for reading a 2D image from a FITS file
+
+/*!
+  \class SOPHYA::FitsImg2DRead
+  \ingroup FitsIOServer
+  Class for reading a 2D image from a FITS file
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fname : name of the FITS file
+  \param ihdu : number of the HDU where the image is.
+  \param lp : debug level
+  \verbatim
+  - if ihdu<=0 first IMAGE hdu is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsImg2DRead::FitsImg2DRead(string fname,int ihdu,int lp)
+: FitsImg2DRd(new FitsOpenFile(fname),ihdu,lp)
+{
+}
+
+/*! Constructor. see below */
+FitsImg2DRead::FitsImg2DRead(const char * cfname,int ihdu,int lp)
+: FitsImg2DRd(new FitsOpenFile(cfname),ihdu,lp)
+{
+}
+
+/*! Constructor by default */
+FitsImg2DRead::FitsImg2DRead()
+: FitsImg2DRd()
+{
+}
+
+/*! Constructor by copy */
+FitsImg2DRead::FitsImg2DRead(FitsImg2DRead& fimg)
+{
+ // --- ATTENTION ---
+ // FitsImg2DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
+ FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
+ Init(fof,fimg.HDU(),fimg.DbgLevel);
+}
+
+/*! Destructor. */
+FitsImg2DRead::~FitsImg2DRead()
+{
+ // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
+ if(FitsOF!=NULL) delete FitsOF;
+}
+
+
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for reading a 3D image from a FITS file
+
+/*!
+  \class SOPHYA::FitsImg3DRd
+  \ingroup FitsIOServer
+  Class for reading a 3D image from a FITS file
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fof : Pointer to the Class for opening the FITS file
+  \param ihdu : number of the HDU where the 3D image is.
+  \param lp : debug level
+  \verbatim
+  - if ihdu<=0 first IMAGE hdu is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsImg3DRd::FitsImg3DRd(FitsOpenFile* fof,int ihdu,int lp)
+{
+ Init(fof,ihdu,lp);
+}
+
+/*! Constructor by copy */
+FitsImg3DRd::FitsImg3DRd(FitsImg3DRd& fbt)
+{
+ Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
+}
+
+/*! Constructor by default */
+FitsImg3DRd::FitsImg3DRd()
+{
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+ SetNulVal(); SetDebug(0);
+ FitsOF = NULL;
+}
+
+/*! Init routine called by the constructor */
+void FitsImg3DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
+{
+ // Initialisation des Parametres Generaux
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+ SetNulVal(); SetDebug(lp);
+ FitsOF = NULL;
+
+ // Caracteristiques du FitsOpenFile
+ FitsOF = fof;
+ if(FitsOF==NULL)
+   throw NullPtrError("FitsImg3DRd::Init: FitsOpenFile pointer is NULL\n");
+
+ if(GetFitsPtr()==NULL)
+   throw NullPtrError("FitsImg3DRd::Init: FitsPtr pointer is NULL\n");
+
+ int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU(); 
+
+ // Get HDU 3D image
+ // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
+ if(FitsOF->GetPosStatus()==false) {
+   if(ihdu==0) { // find the first IMAGE_HDU
+     FitsOF->MoveToFirst(IMAGE_HDU);
+   } else {
+     int rc = FitsOF->MoveToHDU(ihdu);
+     if(rc!=ihdu)
+       throw RangeCheckError("FitsImg3DRd::Init: Error moving to requested HDU\n");
+   }
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsImg3DRd::Init: file already posit. at another HDU\n");
+ }
+
+ // Check HDUType and set position status to TRUE
+ if(HDUType()!=IMAGE_HDU)
+   throw TypeMismatchExc("FitsImg3DRd::Init: HDU not IMAGE_HDU\n");
+ FitsOF->SetPosStatus(true);
+
+ // Get NAXIS 1, 2 et 3
+ int nfound=0;
+ // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
+ if(ffgknjj(GetFitsPtr(),"NAXIS",1,3,Naxis,&nfound,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw RangeCheckError("FitsImg3DRd::Init: Error reading NAXIS cards\n");
+ }
+ if(DbgLevel>1)
+   cout<<"...Init(hdu="<<HDU()<<")  NAXIS1="<<Naxis[0]<<" NAXIS2="
+       <<Naxis[1]<<" NAXIS3="<<Naxis[2]<<" (nfound="<<nfound<<")"<<endl;
+ if(nfound!=3 || Naxis[0]<=0 || Naxis[1]<=0 || Naxis[2]<=0)
+   throw NotAvailableOperation("FitsImg3DRd::Init: bad Naxis[0-2] value\n");
+
+}
+
+/*! Destructor. */
+FitsImg3DRd::~FitsImg3DRd()
+{
+ //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsImg3DRd::ReadKey(char *keyname)
+{
+ return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsImg3DRd::ReadKeyL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long long
+  \param keyname : name of the key
+  \return value into long long
+*/
+LONGLONG FitsImg3DRd::ReadKeyLL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into string
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsImg3DRd::ReadKeyS(char *keyname)
+{
+ return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
+}
+
+//////////////////////////////////////////////////////////////
+/* REMARQUE:
+ * Dans TArray A(naxis1,naxis2,naxis3);
+ *      A(i,j,k) -> i varie le plus vite et k le moins vite
+ */
+/*!
+Read 3D image into a TArray<uint_2>
+*/
+LONGLONG FitsImg3DRd::Read(TArray<uint_2>& data)
+{
+ int sta=0;
+ uint_2* arr = new uint_2[Naxis[0]];
+ sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(TArray<uint_2>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1]*Naxis[2];
+}
+
+/*! Read 3D image into a TArray<int_4> */
+LONGLONG FitsImg3DRd::Read(TArray<int_4>& data)
+{
+ int sta=0;
+ int_4* arr = new int_4[Naxis[0]];
+ sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(TArray<int_4>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1]*Naxis[2];
+}
+
+/*! Read 3D image into a TArray<int_8> */
+LONGLONG FitsImg3DRd::Read(TArray<int_8>& data)
+{
+ int sta=0;
+ int_8* arr = new int_8[Naxis[0]];
+ sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(TArray<int_8>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1]*Naxis[2];
+}
+
+/*! Read 3D image into a TArray<float> */
+LONGLONG FitsImg3DRd::Read(TArray<float>& data)
+{
+ int sta=0;
+ float* arr = new float[Naxis[0]];
+ sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(TArray<float>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1]*Naxis[2];
+}
+
+/*! Read 3D image into a TArray<double> */
+LONGLONG FitsImg3DRd::Read(TArray<double>& data)
+{
+ int sta=0;
+ double* arr = new double[Naxis[0]];
+ sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
+   fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(TArray<double>): Error Reading Fits file\n");
+   }
+   for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1]*Naxis[2];
+}
+
+/*! Read 3D image pixel i,j,k with i=[0,Naxis1[ , j=[0,Naxis2[ , k=[0,Naxis3[ */
+double FitsImg3DRd::Read(LONGLONG i, LONGLONG j, LONGLONG k)
+{
+ int sta=0;
+ if(i<0 || j<0 || k<0 || i>=Naxis[0] || j>=Naxis[1] || k>=Naxis[2])
+   throw
+     NotAvailableOperation("FitsImg3DRd::Read(i,j,k): bad i/j/k number\n");
+
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+i+1;
+   double val = 0.;
+   fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
+
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     throw
+       NotAvailableOperation("FitsImg3DRd::Read(i,j,k): Error Reading Fits file\n");
+   }
+
+   return val;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+//! Class for reading a 3D image from a FITS file
+
+/*!
+  \class SOPHYA::FitsImg3DRead
+  \ingroup FitsIOServer
+  Class for reading a 3D image from a FITS file
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fname : name of the FITS file
+  \param ihdu : number of the HDU where the 3D image is.
+  \param lp : debug level
+  \verbatim
+  - if ihdu<=0 first IMAGE hdu is taken
+  - if ihdu>nhdu ihdu is set to nhdu
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsImg3DRead::FitsImg3DRead(string fname,int ihdu,int lp)
+: FitsImg3DRd(new FitsOpenFile(fname),ihdu,lp)
+{
+}
+
+/*! Constructor. see below */
+FitsImg3DRead::FitsImg3DRead(const char * cfname,int ihdu,int lp)
+: FitsImg3DRd(new FitsOpenFile(cfname),ihdu,lp)
+{
+}
+
+/*! Constructor by default */
+FitsImg3DRead::FitsImg3DRead()
+: FitsImg3DRd()
+{
+}
+
+/*! Constructor by copy */
+FitsImg3DRead::FitsImg3DRead(FitsImg3DRead& fimg)
+{
+ // --- ATTENTION ---
+ // FitsImg3DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
+ FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
+ Init(fof,fimg.HDU(),fimg.DbgLevel);
+}
+
+/*! Destructor. */
+FitsImg3DRead::~FitsImg3DRead()
+{
+ // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
+ if(FitsOF!=NULL) delete FitsOF;
+}
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtcolread.h	(revision 3445)
@@ -0,0 +1,315 @@
+/* Interface Fits BINARY/ASCII Table Column Reader    cmv 26/09/2001 */
+#ifndef FABTCOLREAD_H_SEEN
+#define FABTCOLREAD_H_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "tvector.h"
+#include "FitsIO/fitsio.h"
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////////////
+//! Class for opening a FITS file for reading
+class FitsOpenFile : public AnyDataObj {
+public:
+  FitsOpenFile(string fname);
+  FitsOpenFile(const char *cfname);
+  FitsOpenFile();
+  FitsOpenFile(FitsOpenFile& fof);
+  virtual ~FitsOpenFile();
+
+  inline string FileName() const {return FitsFN;}
+  //! Get the number of the HDU read
+  inline int HDU(void) const {return IHdu;}
+  //! Get the number of the HDU type
+  inline int HDUType(void) const {return HduType;}
+  //! Get the number of HDU in file
+  inline int NHDU() const {return NHdu;}
+  //! Get the CFISTIO fits file pointer
+  inline fitsfile* GetFitsPtr() const {return FitsPtr;}
+  //! Set the positionning status of the file
+  inline void SetPosStatus(bool sta=true) {HasBeenPos = sta;}
+  //! Get the positionning status of the file
+  inline bool GetPosStatus(void) const {return HasBeenPos;}
+
+  int MoveToHDU(int ihdu);
+  int MoveToFirst(int hdutype,int ihdudeb=1);
+  int MoveToLast(int hdutype,int ihdudeb=1);
+  void Print(void);
+
+  static double   ReadKey(fitsfile *fitsptr,char *keyname);
+  static long     ReadKeyL(fitsfile *fitsptr,char *keyname);
+  static LONGLONG ReadKeyLL(fitsfile *fitsptr,char *keyname);
+  static string   ReadKeyS(fitsfile *fitsptr,char *keyname);
+  static void   printerror(int sta);
+
+protected:
+  void Init(const char *cfname);
+  void Delete(void);
+
+  string FitsFN;
+  int NHdu, IHdu, HduType;
+  fitsfile *FitsPtr;
+  bool HasBeenPos;
+};
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a column in a FITS ASCII or BINARY table
+class FitsABTColRd : public AnyDataObj {
+public:
+  FitsABTColRd(FitsOpenFile* fof,string collabel,int ihdu=0
+              ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRd(FitsOpenFile* fof,int colnum,int ihdu=0
+              ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRd(FitsABTColRd& fbt);
+  FitsABTColRd();
+  virtual ~FitsABTColRd();
+
+  void ChangeBuffer(long blen=100,long bsens=1);
+
+  double    ReadKey(char *keyname);
+  long      ReadKeyL(char *keyname);
+  LONGLONG  ReadKeyLL(char *keyname);
+  string    ReadKeyS(char *keyname);
+
+  double Read(LONGLONG n,bool usebuffer=true);
+
+  LONGLONG Read(LONGLONG n1,LONGLONG n2,TVector<uint_2>& data);
+  LONGLONG Read(LONGLONG n1,LONGLONG n2,TVector<int_4>& data);
+  LONGLONG Read(LONGLONG n1,LONGLONG n2,TVector<int_8>& data);
+  LONGLONG Read(LONGLONG n1,LONGLONG n2,TVector<float>& data);
+  LONGLONG Read(LONGLONG n1,LONGLONG 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);}
+
+  LONGLONG FirstRow(double val1,double val2,LONGLONG rowstart=-1);
+  LONGLONG LastRow(double val1,double val2,LONGLONG 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 FileName(void) const
+         {if(FitsOF) return FitsOF->FileName(); else return (string)"";}
+  //! Get the pointer to FitsOpenFile
+  inline FitsOpenFile* GetFitsOpenFile(void) const {return FitsOF;}
+  //! Get the FITS file pointer (cfistio pointer)
+  inline fitsfile* GetFitsPtr(void) const {return FitsOF->GetFitsPtr();}
+  //! Get the number of HDU in the FITS file
+  inline int NHDU(void) const
+         {if(FitsOF) return FitsOF->NHDU(); else return 0;}
+  //! Get the number of the HDU read
+  inline int HDU(void) const
+         {if(FitsOF) return FitsOF->HDU(); else return 0;}
+  //! Get the HDU type
+  inline int HDUType(void) const
+         {if(FitsOF) return FitsOF->HDUType(); else return 0;}
+  //! Get the number of rows in the FITS HDU to be read
+  inline LONGLONG GetNbLine(void) const {return NBline;}
+  //! Get the number of columns in the FITS HDU to be read
+  inline int GetNbCol(void) const {return NBcol;}
+  //! Get the columns number that is read
+  inline int GetColNum(void) const {return ColNum;}
+  //! Get the columns label that is read
+  inline string GetColLabel(void) const {return ColLabel;}
+  //! Get the columns type code that is read
+  inline int GetColTypeCode(void) const {return ColTypeCode;}
+  //! Get the columns fits tunit that is read
+  inline string GetColTUnit(void) const {return ColTUnit;}
+  //! Get the columns fits tform that is read
+  inline string GetColTForm(void) const {return ColTForm;}
+  //! 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 read effective buffer length
+  inline long GetNBuffer(void) const {return NBuffer;}
+  //! Get the read bufferpointer
+  inline double* GetBuffer(void) {return Buffer;}
+
+protected:
+  void Init(FitsOpenFile* fof,const char *collabel,int colnum
+           ,int ihdu,long blen,long bsens,int lp);
+  void Delete(void);
+
+  string ColLabel,ColTUnit,ColTForm;
+  int ColNum,ColTypeCode,NBcol;
+  LONGLONG NBline;
+
+  double NulVal;
+  unsigned short DbgLevel;
+  long BuffLen, BuffSens;
+
+  LONGLONG NFitsRead;
+  FitsOpenFile* FitsOF;
+  LONGLONG LineDeb, LineFin;
+  double *Buffer;
+  long NBuffer;
+};
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a column in a FITS ASCII or BINARY table with fits file opening
+class FitsABTColRead : public FitsABTColRd {
+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);
+  FitsABTColRead();
+  virtual ~FitsABTColRead();
+};
+
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 2D image from a FITS file
+class FitsImg2DRd : public AnyDataObj {
+public:
+  FitsImg2DRd(FitsOpenFile* fof,int ihdu=0,int lp=0);
+  FitsImg2DRd(FitsImg2DRd& fbt);
+  FitsImg2DRd();
+  virtual ~FitsImg2DRd();
+
+  double   ReadKey(char *keyname);
+  long     ReadKeyL(char *keyname);
+  LONGLONG ReadKeyLL(char *keyname);
+  string   ReadKeyS(char *keyname);
+
+  LONGLONG Read(TMatrix<uint_2>& data);
+  LONGLONG Read(TMatrix<int_4>& data);
+  LONGLONG Read(TMatrix<int_8>& data);
+  LONGLONG Read(TMatrix<float>& data);
+  LONGLONG Read(TMatrix<double>& data);
+  double   Read(LONGLONG numcol, LONGLONG numrow);
+
+  //! 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 pointer to FitsOpenFile
+  inline FitsOpenFile* GetFitsOpenFile(void) const {return FitsOF;}
+  //! Get the FITS file pointer (cfistio pointer)
+  inline fitsfile* GetFitsPtr(void) const {return FitsOF->GetFitsPtr();}
+  //! Get the number of HDU in the FITS file
+  inline int NHDU(void) const
+         {if(FitsOF) return FitsOF->NHDU(); else return 0;}
+  //! Get the number of the HDU read
+  inline int HDU(void) const
+         {if(FitsOF) return FitsOF->HDU(); else return 0;}
+  //! Get the HDU type
+  inline int HDUType(void) const
+         {if(FitsOF) return FitsOF->HDUType(); else return 0;}
+  //! Get NAXIS1
+  inline LONGLONG Naxis1(void) const {return Naxis[0];}
+  //! Get NAXIS2
+  inline LONGLONG Naxis2(void) const {return Naxis[1];}
+
+protected:
+  void Init(FitsOpenFile* fof,int ihdu,int lp);
+
+  LONGLONG Naxis[2];
+  double NulVal;
+  unsigned short DbgLevel;
+
+  FitsOpenFile* FitsOF;
+};
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 2D image from a FITS file
+class FitsImg2DRead : public FitsImg2DRd {
+public:
+  FitsImg2DRead(string fname,int ihdu=0,int lp=0);
+  FitsImg2DRead(const char *cfname,int ihdu=0,int lp=0);
+  FitsImg2DRead(FitsImg2DRead& fbt);
+  FitsImg2DRead();
+  virtual ~FitsImg2DRead();
+};
+
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 3D image from a FITS file
+class FitsImg3DRd : public AnyDataObj {
+public:
+  FitsImg3DRd(FitsOpenFile* fof,int ihdu=0,int lp=0);
+  FitsImg3DRd(FitsImg3DRd& fbt);
+  FitsImg3DRd();
+  virtual ~FitsImg3DRd();
+
+  double   ReadKey(char *keyname);
+  long     ReadKeyL(char *keyname);
+  LONGLONG ReadKeyLL(char *keyname);
+  string   ReadKeyS(char *keyname);
+
+  LONGLONG Read(TArray<uint_2>& data);
+  LONGLONG Read(TArray<int_4>& data);
+  LONGLONG Read(TArray<int_8>& data);
+  LONGLONG Read(TArray<float>& data);
+  LONGLONG Read(TArray<double>& data);
+  double   Read(LONGLONG i, LONGLONG j, LONGLONG k);
+
+  //! 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 pointer to FitsOpenFile
+  inline FitsOpenFile* GetFitsOpenFile(void) const {return FitsOF;}
+  //! Get the FITS file pointer (cfistio pointer)
+  inline fitsfile* GetFitsPtr(void) const {return FitsOF->GetFitsPtr();}
+  //! Get the number of HDU in the FITS file
+  inline int NHDU(void) const
+         {if(FitsOF) return FitsOF->NHDU(); else return 0;}
+  //! Get the number of the HDU read
+  inline int HDU(void) const
+         {if(FitsOF) return FitsOF->HDU(); else return 0;}
+  //! Get the HDU type
+  inline int HDUType(void) const
+         {if(FitsOF) return FitsOF->HDUType(); else return 0;}
+  //! Get NAXIS1
+  inline LONGLONG Naxis1(void) const {return Naxis[0];}
+  //! Get NAXIS2
+  inline LONGLONG Naxis2(void) const {return Naxis[1];}
+  //! Get NAXIS3
+  inline LONGLONG Naxis3(void) const {return Naxis[2];}
+
+protected:
+  void Init(FitsOpenFile* fof,int ihdu,int lp);
+
+  LONGLONG Naxis[3];
+  double NulVal;
+  unsigned short DbgLevel;
+
+  FitsOpenFile* FitsOF;
+};
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 3D image from a FITS file
+class FitsImg3DRead : public FitsImg3DRd {
+public:
+  FitsImg3DRead(string fname,int ihdu=0,int lp=0);
+  FitsImg3DRead(const char *cfname,int ihdu=0,int lp=0);
+  FitsImg3DRead(FitsImg3DRead& fbt);
+  FitsImg3DRead();
+  virtual ~FitsImg3DRead();
+};
+
+} // namespace SOPHYA
+#endif    /* FABTCOLREAD_H_SEEN */
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 3445)
@@ -0,0 +1,1105 @@
+/* Writer de table Fits (binaire ou ASCII) */
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fabtwriter.h"
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsWriter
+  \ingroup FitsIOServer
+  Class for writing into a FITS file (DO NOT USE)
+*/
+
+/*! Constructor  (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,int lp)
+{
+  cr_or_upd_fits(cfname,false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,bool update,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),update,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,bool update,int lp)
+{
+  cr_or_upd_fits(cfname,update,lp);
+}
+
+/*! See FitsWriter() */
+void FitsWriter::cr_or_upd_fits(const char *cfname,bool update,int lp)
+{
+ FitsPtr = NULL;
+ HduType = 0;
+ SetDebug(lp);
+ FitsFN = cfname;
+ NOverFlow = 0;
+ Update = update;
+ // Init key structure
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ LongLongKey.resize(0);
+ StringKey.resize(0);
+
+ if(DbgLevel)
+   cout<<"FitsWriter::cr_or_upd_fits FitsFN="<<FitsFN<<endl;
+
+ if(FitsFN.size() <= 0 )
+   throw ParmError("FitsWriter::cr_or_upd_fits: Fits file name error\n");
+
+ // create or update FITS file
+ int sta=0;
+ if(Update) {
+   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READWRITE,&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error opening Fits file for update\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: fits file has been opened for update"<<endl;
+ } else {
+   if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating new Fits file\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: a new fits file has been created"<<endl;
+ }
+
+ // create d'un Primary HDU
+ //LONGLONG naxes[1] = {0};
+ //if(fits_create_imgll(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
+ //  printerror(sta);
+ //  throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating Primary extension\n");
+ //}
+}
+
+/*! Destructor */
+FitsWriter::~FitsWriter()
+{
+ int sta = 0;
+ writekeys();
+ if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+ FitsPtr = NULL;
+}
+
+/*! Flush the FitsIO buffer to set good Fits file in case of problems */
+void FitsWriter::Flush(void)
+{
+ if(FitsPtr==NULL) return;
+ int sta = 0;
+ if(fits_flush_file(FitsPtr,&sta)) printerror(sta);
+}
+
+
+/*! Write a double value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,double val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyDouble k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ DoubleKey.push_back(k);
+}
+
+/*! Write a long value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,long val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyLong k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ LongKey.push_back(k);
+}
+
+/*! Write a long long value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,LONGLONG val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyLongLong k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ LongLongKey.push_back(k);
+}
+
+/*! Write a string value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,string val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyString k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ StringKey.push_back(k);
+}
+
+void FitsWriter::writekeys(void)
+// Ecriture effective des clefs
+{
+ if(FitsPtr==NULL) return;
+ int sta=0;
+ if(DoubleKey.size()>0)
+   for(unsigned long 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 long i=0;i<LongKey.size();i++) {
+     char* key = const_cast<char*>(LongKey[i].keyname.c_str());
+     char* com = const_cast<char*>(LongKey[i].comment.c_str());
+     long val = LongKey[i].val;
+     if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(LongLongKey.size()>0)
+   for(unsigned long i=0;i<LongLongKey.size();i++) {
+     char* key = const_cast<char*>(LongLongKey[i].keyname.c_str());
+     char* com = const_cast<char*>(LongLongKey[i].comment.c_str());
+     LONGLONG val = LongLongKey[i].val;
+     if(fits_update_key(FitsPtr,TLONGLONG,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(StringKey.size()>0)
+   for(unsigned long i=0;i<StringKey.size();i++) {
+     char* key = const_cast<char*>(StringKey[i].keyname.c_str());
+     char* com = const_cast<char*>(StringKey[i].comment.c_str());
+     char* val = const_cast<char*>(StringKey[i].val.c_str());
+     if(fits_update_key(FitsPtr,TSTRING,key,val,com,&sta))
+       printerror(sta);
+   }
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ LongLongKey.resize(0);
+ StringKey.resize(0);
+}
+
+void FitsWriter::printerrorwrite(const char* type,int col,LONGLONG row,int sta)
+{
+ if(sta==NUM_OVERFLOW) {NOverFlow++; return;}
+ printerror(sta);
+ char str[256];
+ sprintf(str,"FitsWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d"
+        ,type,col,(long)row,sta);
+ throw NotAvailableOperation(str);
+}
+
+void FitsWriter::printerror(int sta) const
+{
+ int stat = sta;
+ fits_report_error(stdout,stat);
+ fflush(stdout);
+ return;
+}
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsABTWriter
+  \ingroup FitsIOServer
+  Class for writing a FITS ASCII or BINARY table
+  \verbatim
+  //-----------------------------------------------------------
+  OPENING A NEW FILE AND WRITING INTO
+  -- Exemple 1: Writing element by element
+  FitsABTWriter fbtw(fitswrit,BINARY_TBL);
+  fbtw.SetExtName("MY_OWN_EXTENSION");
+  int c1 = fbtw.AddCol("vars",NULL,"km",TSHORT);       // col=0
+  int c2 = fbtw.AddCol("vars2",NULL,"km",TSHORT);      // col=1
+  int c3 = fbtw.AddCol("varl",NULL,"Degre",TLONG);     // col=2
+  int c4 = fbtw.AddCol("varf",NULL,"",TFLOAT);         // col=3
+  int c5 = fbtw.AddCol("vard","","arcmin",TDOUBLE);    // col=4
+  fbtw.SetDebug(3);
+  for(LONGLONG i=0;i<1000;i++) {
+    double x = i;
+    fbtw.Write(c1,i,1000.*x); // if overflow, managed by cfitsio
+                             // Write(int,long,double) is called
+    fbtw.Write(c2,i,(short)(1000.*x));
+                             // if overflow, managed by language
+                             // Write(int,long,short) is called
+    fbtw.Write(c3,i,x);
+    fbtw.Write(c4,i,x);
+    fbtw.Write(c5,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(LONGLONG i=0;i<9990;i+=100) {
+    LONGLONG i2=i+100-1; if(i2>=9990) i2=9990-1;
+    for(LONGLONG j=0;j<100;j++) datad(i) =  ...;
+    for(LONGLONG j=0;j<100;j++) dataf(i) =  ...;
+    for(LONGLONG j=0;j<100;j++) datal(i) =  ...;
+    fbtw.Write(1,i,datal);
+    fbtw.Write(2,i,dataf);
+    fbtw.Write(3,i,datad);
+  }
+  \endverbatim
+  \verbatim
+  //-----------------------------------------------------------
+  //-----------------------------------------------------------
+  //-----------------------------------------------------------
+  OPENING A NEW FILE AND WRITING 2 TABLE EXTENSIONS SIMULTANEOUSLY INTO
+ try {
+
+   cout<<">>>>> Creating a new fits file with FitsABTWriter"<<endl;
+   FitsABTWriter fbtw("!cmvtstfits3.fits",BINARY_TBL,3);
+   //FitsABTWriter fbtw("!cmvtstfits3.fits",false,BINARY_TBL,3);
+   fbtw.SetExtName("Test fits table 1");
+   cout<<"Writing Keys"<<endl;
+   fbtw.WriteKey("MYKEYL",(long)123456789,"my LONG key");
+   fbtw.WriteKey("MYKEYLL",(LONGLONG)123456789,"my LONGLONG key");
+   fbtw.WriteKey("MYKEYD",1.9999999,"my DOUBLE key");
+   fbtw.WriteKey("MYKEYC","how are you ?","my CHAR* key");
+   dum="do you feel better ?";
+   fbtw.WriteKey("MYKEYS",dum,"my STRING key");
+   i1 = fbtw.AddCol("x1",NULL,"unit1",TDOUBLE);
+   i2 = fbtw.AddCol("x2",NULL,"unit2",TDOUBLE);
+   i3 = fbtw.AddCol("x3",NULL,"unit3",TDOUBLE);
+   fbtw.Print();
+
+   cout<<">>>>> Another extension fits table with FitsABTWriter"<<endl;
+   FitsABTWriter fbtw2("cmvtstfits3.fits",true,BINARY_TBL,3);
+   fbtw2.SetExtName("Test fits table 2");
+   cout<<"Writing Keys"<<endl;
+   fbtw2.WriteKey("MYKEYL",(long)-123456789,"my new LONG key");
+   fbtw2.WriteKey("MYKEYLL",(LONGLONG)-123456789,"my new LONGLONG key");
+   fbtw2.WriteKey("MYKEYD",-1.9999999,"my new clef DOUBLE key");
+   fbtw2.WriteKey("MYKEYC","how are you NOW ?","my new CHAR* key");
+   dum="do you feel better NOW ?";
+   fbtw2.WriteKey("MYKEYS",dum,"my new STRING key");
+   i11 = fbtw2.AddCol("x11",NULL,"unit11",TDOUBLE);
+   i12 = fbtw2.AddCol("x12",NULL,"unit12",TDOUBLE);
+   i13 = fbtw2.AddCol("x13",NULL,"unit13",TDOUBLE);
+   fbtw2.Print();
+
+   cout<<">>>>> Write into the 2 tables simultaneously"<<endl;
+   for(LONGLONG i=0;i<NNN;i++) {
+     fbtw.Write(i1,i,i+1.);
+     fbtw.Write(i2,i,i+11.);
+     fbtw.Write(i3,i,i+101.);
+     fbtw2.Write(i11,i,-(i+1.));
+     fbtw2.Write(i12,i,-(i+11.));
+     fbtw2.Write(i13,i,-(i+101.));
+   }
+
+ } 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;
+ }
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (a new fits file is created)
+  \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)
+: FitsWriter(fname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (a new fits file is created)
+  \param hdutype : type of extension to be created (BINARY_TBL or ASCII_TBL)
+  \param lp : debug level
+*/
+FitsABTWriter::FitsABTWriter(const char* cfname,int hdutype,int lp)
+: FitsWriter(cfname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
+}
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param hdutype : type of extension to be created (BINARY_TBL or ASCII_TBL)
+  \param lp : debug level
+*/
+FitsABTWriter::FitsABTWriter(string fname,bool update,int hdutype,int lp)
+: FitsWriter(fname,update,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param hdutype : type of extension to be created (BINARY_TBL or ASCII_TBL)
+  \param lp : debug level
+*/
+FitsABTWriter::FitsABTWriter(const char* cfname,bool update,int hdutype,int lp)
+: FitsWriter(cfname,update,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
+}
+
+/*! Destructor */
+FitsABTWriter::~FitsABTWriter()
+{
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  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 TSBYTE. 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");
+#ifdef TSBYTE
+   else if(datatype==TSBYTE)    strcpy(str,"1S");
+#endif
+   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");
+#ifdef TSBYTE
+   else if(datatype==TSBYTE)    strcpy(str,"I5");
+#endif
+   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");
+
+ LONGLONG 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());
+ }
+ for(int 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");
+ }
+
+ // menage
+ if(extname) delete [] extname;
+ for(int 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 signed char (1 Byte) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,LONGLONG row,int_1 val)
+{
+#ifdef TSBYTE
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TSBYTE,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("signed char",col,row,sta);
+#else
+  throw PException("FitsABTWriter::Write(..,int_1) Not in that cfitsio version");
+#endif
+}
+
+/*! Write unsigned char (1 Byte) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,LONGLONG 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,LONGLONG 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,LONGLONG 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,LONGLONG 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,LONGLONG 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,LONGLONG 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,LONGLONG 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,LONGLONG 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) */
+LONGLONG FitsABTWriter::Write(int col,LONGLONG row,TVector<uint_2>& val)
+{
+  if(FirstTime) createtbl();
+  LONGLONG 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) */
+LONGLONG FitsABTWriter::Write(int col,LONGLONG row,TVector<int_4>& val)
+{
+  if(FirstTime) createtbl();
+  LONGLONG 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) */
+LONGLONG FitsABTWriter::Write(int col,LONGLONG row,TVector<int_8>& val)
+{
+#ifdef TLONGLONG
+  if(FirstTime) createtbl();
+  LONGLONG 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) */
+LONGLONG FitsABTWriter::Write(int col,LONGLONG row,TVector<float>&  val)
+{
+  if(FirstTime) createtbl();
+  LONGLONG 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) */
+LONGLONG FitsABTWriter::Write(int col,LONGLONG row,TVector<double>& val)
+{
+  if(FirstTime) createtbl();
+  LONGLONG 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::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;
+}
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsImg2DWriter
+  \ingroup FitsIOServer
+  Class for writing an image into FITS file
+*/
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,int bitpix,int lp)
+: FitsWriter(fname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,int bitpix,int lp)
+: FitsWriter(cfname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,bool update,int bitpix,int lp)
+: FitsWriter(fname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,bool update,int bitpix,int lp)
+: FitsWriter(cfname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*! Destructor */
+FitsImg2DWriter::~FitsImg2DWriter()
+{
+}
+
+/*! Create the image. Done at the first write request. */
+void FitsImg2DWriter::createimg(void)
+{
+ if(!FirstTime)
+   throw NotAvailableOperation("FitsImg2DWriter::createimg: already created image\n");
+ if(Naxis[0]<=0 || Naxis[1]<=0)
+   throw ParmError("FitsImg2DWriter::createimg: bad Naxis 1 or 2 value\n");
+
+ int sta=0;
+ if(fits_create_imgll(FitsPtr,BitPix,2,Naxis,&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsImg2DWriter::createimg: Error creating image extension\n");
+ }
+
+ FirstTime = false;
+}
+
+/*!
+  Write an unsigned short image to FITS file.
+  \warning TMatrix data(Naxis2,Naxis1) means Data(row,column)
+*/
+void FitsImg2DWriter::Write(TMatrix<uint_2>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ uint_2* arr = new uint_2[Naxis[0]];
+
+ for(LONGLONG l=0;l<Naxis[1];l++) {
+   for(LONGLONG c=0;c<Naxis[0];c++) arr[c] = data(l,c);
+   LONGLONG deb = l*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TUSHORT,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("uint_2",0,l,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<uint_2>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a long image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<int_4>& data)
+{
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ int_4* arr = new int_4[Naxis[0]];
+
+ for(LONGLONG l=0;l<Naxis[1];l++) {
+   for(LONGLONG c=0;c<Naxis[0];c++) arr[c] = data(l,c);
+   LONGLONG deb = l*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,T,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("int_4",0,l,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<int_4>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a float image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<float>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ float* arr = new float[Naxis[0]];
+
+ for(LONGLONG l=0;l<Naxis[1];l++) {
+   for(LONGLONG c=0;c<Naxis[0];c++) arr[c] = data(l,c);
+   LONGLONG deb = l*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TFLOAT,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("float",0,l,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<float>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a double image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<double>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ double* arr = new double[Naxis[0]];
+
+ for(LONGLONG l=0;l<Naxis[1];l++) {
+   for(LONGLONG c=0;c<Naxis[0];c++) arr[c] = data(l,c);
+   LONGLONG deb = l*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TDOUBLE,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("double",0,l,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<double>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Print infos. */
+void FitsImg2DWriter::Print(ostream& os) const
+{
+os<<"FitsImg2DWriter::Print: FitsFN "<<FitsFN<<endl
+  <<"  HduType "<<HduType<<"  NOverFlow "<<NOverFlow<<"  BitPix "<<BitPix
+  <<"  Naxis1 "<<Naxis[0]<<"  Naxis2 "<<Naxis[1]<<endl;
+}
+
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsImg3DWriter
+  \ingroup FitsIOServer
+  Class for writing an 3D image into FITS file
+*/
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (a new fits file is created)
+  \param bitpix : 3D image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg3DWriter::FitsImg3DWriter(string fname,int bitpix,int lp)
+: FitsWriter(fname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (a new fits file is created)
+  \param bitpix : 3D image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg3DWriter::FitsImg3DWriter(const char* cfname,int bitpix,int lp)
+: FitsWriter(cfname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+}
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : 3D image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg3DWriter::FitsImg3DWriter(string fname,bool update,int bitpix,int lp)
+: FitsWriter(fname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : 3D image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg3DWriter::FitsImg3DWriter(const char* cfname,bool update,int bitpix,int lp)
+: FitsWriter(cfname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = Naxis[2] = 0;
+}
+
+/*! Destructor */
+FitsImg3DWriter::~FitsImg3DWriter()
+{
+}
+
+/*! Create the 3D image. Done at the first write request. */
+void FitsImg3DWriter::createimg(void)
+{
+ if(!FirstTime)
+   throw NotAvailableOperation("FitsImg3DWriter::createimg: already created 3D image\n");
+ if(Naxis[0]<=0 || Naxis[1]<=0 || Naxis[2]<=0)
+   throw ParmError("FitsImg3DWriter::createimg: bad Naxis 1 or 2 or 3 value\n");
+
+ int sta=0;
+ if(fits_create_imgll(FitsPtr,BitPix,3,Naxis,&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsImg3DWriter::createimg: Error creating 3D image extension\n");
+ }
+
+ FirstTime = false;
+}
+
+/*!
+  Write an unsigned short 3D image to FITS file.
+*/
+void FitsImg3DWriter::Write(TArray<uint_2>& data)
+{
+ if(data.Rank()!=3)
+   throw ParmError("FitsImg3DRd::Write(TArray<uint_2>): not a 3D array\n");
+
+ Naxis[0]=data.SizeX(); Naxis[1]=data.SizeY(); Naxis[2]=data.SizeZ(); createimg();
+ uint_2* arr = new uint_2[Naxis[0]];
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   for(LONGLONG i=0;i<Naxis[0];i++) arr[i] = data(i,j,k);
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TUSHORT,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("uint_2",j,k,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Write(TArray<uint_2>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a long 3D image to FITS file. */
+void FitsImg3DWriter::Write(TArray<int_4>& data)
+{
+ if(data.Rank()!=3)
+   throw ParmError("FitsImg3DRd::Write(TArray<int_4>): not a 3D array\n");
+
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ Naxis[0]=data.SizeX(); Naxis[1]=data.SizeY(); Naxis[2]=data.SizeZ(); createimg();
+ int_4* arr = new int_4[Naxis[0]];
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   for(LONGLONG i=0;i<Naxis[0];i++) arr[i] = data(i,j,k);
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,T,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("int_4",j,k,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Write(TArray<int_4>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a float 3D image to FITS file. */
+void FitsImg3DWriter::Write(TArray<float>& data)
+{
+ if(data.Rank()!=3)
+   throw ParmError("FitsImg3DRd::Write(TArray<float>): not a 3D array\n");
+
+ Naxis[0]=data.SizeX(); Naxis[1]=data.SizeY(); Naxis[2]=data.SizeZ(); createimg();
+ float* arr = new float[Naxis[0]];
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   for(LONGLONG i=0;i<Naxis[0];i++) arr[i] = data(i,j,k);
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TFLOAT,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("float",j,k,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Write(TArray<float>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write a double 3D image to FITS file. */
+void FitsImg3DWriter::Write(TArray<double>& data)
+{
+ if(data.Rank()!=3)
+   throw ParmError("FitsImg3DRd::Write(TArray<double>): not a 3D array\n");
+
+ Naxis[0]=data.SizeX(); Naxis[1]=data.SizeY(); Naxis[2]=data.SizeZ(); createimg();
+ double* arr = new double[Naxis[0]];
+
+ for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
+   for(LONGLONG i=0;i<Naxis[0];i++) arr[i] = data(i,j,k);
+   LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TDOUBLE,deb,nel,arr,&sta);
+   if(sta) {
+     printerrorwrite("double",j,k,sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg3DRd::Write(TArray<double>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Print infos. */
+void FitsImg3DWriter::Print(ostream& os) const
+{
+os<<"FitsImg3DWriter::Print: FitsFN "<<FitsFN<<endl
+  <<"  HduType "<<HduType<<"  NOverFlow "<<NOverFlow<<"  BitPix "<<BitPix
+  <<"  Naxis1 "<<Naxis[0]<<"  Naxis2 "<<Naxis[1]<<"  Naxis3 "<<Naxis[2]<<endl;
+}
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fabtwriter.h	(revision 3445)
@@ -0,0 +1,193 @@
+/* Interface Fits BINARY/ASCII Table Writer    cmv 26/09/2001 */
+#ifndef FABTWRITER_H_SEEN
+#define FABTWRITER_H_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "tvector.h"
+#include "FitsIO/fitsio.h"
+
+#include <vector>
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing into a FITS file (DO NOT USE)
+class FitsWriter : public AnyDataObj {
+protected:
+  FitsWriter(string fname,int lp=0);
+  FitsWriter(const char* cfname,int lp=0);
+  FitsWriter(string fname,bool update,int lp=0);
+  FitsWriter(const char* cfname,bool update,int lp=0);
+  virtual ~FitsWriter();
+
+public:
+  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);
+  //! Write a long long value in Fits header.
+  void WriteKey(const char *keyname,LONGLONG val,char* comment=NULL);
+  //! Write a string value in Fits header.
+  void WriteKey(const char *keyname,string val,char* comment=NULL);
+  //! Write a character string value in Fits header.
+  inline void WriteKey(const char *keyname,char* val,char* comment=NULL)
+                      {string dum=val; WriteKey(keyname,dum,comment);}
+  //! Set debug level
+  inline void SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+
+  //! Return the number of overflows managed by cfitsio
+  inline LONGLONG GetNOverFlow(void) {return NOverFlow;}
+
+  //! Return the c-fitsio file pointer
+  inline fitsfile * GetFitsPtr() { return FitsPtr; }
+protected:
+  struct KeyDouble   {string keyname; double   val; string comment;};
+  struct KeyLong     {string keyname; long     val; string comment;};
+  struct KeyLongLong {string keyname; LONGLONG val; string comment;};
+  struct KeyString   {string keyname; string   val; string comment;};
+
+  void cr_or_upd_fits(const char *cfname,bool update,int lp);
+
+  void writekeys(void);
+  void printerrorwrite(const char* type,int col,LONGLONG row,int sta);
+  void printerror(int sta) const;
+
+  string FitsFN,ExtName;
+  bool Update;
+  int HduType;
+  unsigned short DbgLevel;
+  fitsfile *FitsPtr;
+  LONGLONG NOverFlow;
+
+  vector<struct KeyDouble>   DoubleKey;
+  vector<struct KeyLong>     LongKey;
+  vector<struct KeyLongLong> LongLongKey;
+  vector<struct KeyString>   StringKey;
+};
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing a FITS ASCII or BINARY table
+class FitsABTWriter : public FitsWriter {
+public:
+  FitsABTWriter(string fname,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(const char* cfname,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(string fname,bool update,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(const char* cfname,bool update,int hdutype=BINARY_TBL,int lp=0);
+  virtual ~FitsABTWriter();
+
+  //! 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;}
+
+  //! 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);}
+
+  void Write(int col,LONGLONG row,int_1 val);
+  void Write(int col,LONGLONG row,uint_1 val);
+  void Write(int col,LONGLONG row,int_2 val);
+  void Write(int col,LONGLONG row,uint_2 val);
+  void Write(int col,LONGLONG row,int_4 val);
+  void Write(int col,LONGLONG row,uint_4 val);
+  void Write(int col,LONGLONG row,int_8 val);
+  void Write(int col,LONGLONG row,float val);
+  void Write(int col,LONGLONG row,double val);
+  LONGLONG Write(int col,LONGLONG row,TVector<uint_2>& val);
+  LONGLONG Write(int col,LONGLONG row,TVector<int_4>& val);
+  LONGLONG Write(int col,LONGLONG row,TVector<int_8>& val);
+  LONGLONG Write(int col,LONGLONG row,TVector<float>& val);
+  LONGLONG Write(int col,LONGLONG row,TVector<double>& val);
+
+  //! 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:
+  int addcol(const char* label,const char* tform,const char* tunit,int datatype);
+  void createtbl(void);
+
+  bool FirstTime;
+  vector<string> Label;
+  vector<string> TForm;
+  vector<string> TUnit;
+};
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing a FITS Image
+class FitsImg2DWriter : public FitsWriter {
+public:
+  FitsImg2DWriter(string fname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(const char* cfname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(string fname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(const char* cfname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  virtual ~FitsImg2DWriter();
+
+  void Write(TMatrix<uint_2>& data);
+  void Write(TMatrix<int_4>& data);
+  void Write(TMatrix<float>& data);
+  void Write(TMatrix<double>& data);
+
+  //! Print to os
+  virtual void   Print(ostream& os) const;
+  //! Print to stdout
+  inline  void   Print(void) const {Print(cout);}
+
+protected:
+  void createimg(void);
+
+  int BitPix;
+  LONGLONG Naxis[2];
+  bool FirstTime;
+};
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing a FITS Image
+class FitsImg3DWriter : public FitsWriter {
+public:
+  FitsImg3DWriter(string fname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg3DWriter(const char* cfname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg3DWriter(string fname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg3DWriter(const char* cfname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  virtual ~FitsImg3DWriter();
+
+  void Write(TArray<uint_2>& data);
+  void Write(TArray<int_4>& data);
+  void Write(TArray<float>& data);
+  void Write(TArray<double>& data);
+
+  //! Print to os
+  virtual void   Print(ostream& os) const;
+  //! Print to stdout
+  inline  void   Print(void) const {Print(cout);}
+
+protected:
+  void createimg(void);
+
+  int BitPix;
+  LONGLONG Naxis[3];
+  bool FirstTime;
+};
+
+} // namespace SOPHYA
+#endif    /* FABTWRITER_H_SEEN */
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fboloread.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fboloread.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fboloread.cc	(revision 3445)
@@ -0,0 +1,247 @@
+/* Lecteur Fits de bolometre */
+#include "sopnamsp.h"
+#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(LONGLONG 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(LONGLONG i=0, istep=1000; i<fbr.GetNbLine(); i+=istep) {
+    LONGLONG 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
+ LONGLONG 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;
+   LONGLONG 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_Nov2007/SophyaExt/FitsIOServer/fboloread.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fboloread.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fboloread.h	(revision 3445)
@@ -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>
+#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(LONGLONG n,bool usebuffer=true)
+                {return GetCol(ColAlpha,n,usebuffer);}
+  //! return Delta value for row "n" into double
+  inline double GetDelta(LONGLONG n,bool usebuffer=true)
+                {return GetCol(ColDelta,n,usebuffer);}
+  //! return Bolo value for row "n" into double
+  inline double GetBolo(LONGLONG n,bool usebuffer=true)
+                {return GetCol(ColBolo,n,usebuffer);}
+  //! return Flag value for row "n" into double
+  inline double GetFlag(LONGLONG n,bool usebuffer=true)
+         {if(!IsFlag()) return 0.; return GetCol(ColFlag,n,usebuffer);}
+  //! return SNum value for row "n" into double
+  inline double GetSNum(LONGLONG n,bool usebuffer=true)
+                {return GetCol(ColSNum,n,usebuffer);}
+  //! return column "col" value for row "n" into double
+  inline double GetCol(int col,LONGLONG 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 LONGLONG GetAlpha(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+  inline LONGLONG GetAlpha(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+  inline LONGLONG GetAlpha(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+
+  //! return Delta values for rows [n1,n2] into TVector
+  inline LONGLONG GetDelta(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+  inline LONGLONG GetDelta(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+  inline LONGLONG GetDelta(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+
+  //! return Bolo values for rows [n1,n2] into TVector
+  inline LONGLONG GetBolo(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+  inline LONGLONG GetBolo(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+  inline LONGLONG GetBolo(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+
+  //! return Flag values for rows [n1,n2] into TVector
+  inline LONGLONG GetFlag(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+              {if(!IsFlag()) return 0; return GetCol(ColFlag,n1,n2,data);}
+  inline LONGLONG GetFlag(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+              {if(!IsFlag()) return 0; return GetCol(ColFlag,n1,n2,data);}
+  inline LONGLONG GetFlag(LONGLONG n1,LONGLONG 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 LONGLONG GetSNum(LONGLONG n1,LONGLONG n2,TVector<double>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+  inline LONGLONG GetSNum(LONGLONG n1,LONGLONG n2,TVector<float>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+  inline LONGLONG GetSNum(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+
+  //! return column "col" values for rows [n1,n2] into TVector
+  inline LONGLONG GetCol(int col,LONGLONG n1,LONGLONG 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 LONGLONG GetCol(int col,LONGLONG n1,LONGLONG 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 LONGLONG GetCol(int col,LONGLONG n1,LONGLONG 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 LONGLONG 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);
+
+  LONGLONG 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_Nov2007/SophyaExt/FitsIOServer/fbtntintf.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fbtntintf.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fbtntintf.cc	(revision 3445)
@@ -0,0 +1,299 @@
+/* Interface Fits BINARY/ASCII Table     cmv 21/05/2001 */
+#include "sopnamsp.h"
+#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_rowsll(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_coltypell(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();
+
+}
+
+/////////////////////////////////////////////////
+sa_size_t FitsBTNtuIntf::NbLines() const
+{
+ return NBline;
+}
+
+sa_size_t FitsBTNtuIntf::NbColumns() const
+{
+ return NBcol;
+}
+
+r_8 * FitsBTNtuIntf::GetLineD(sa_size_t 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++;
+   LONGLONG 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);
+   }
+ }
+
+ sa_size_t 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(sa_size_t n, sa_size_t 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_Nov2007/SophyaExt/FitsIOServer/fbtntintf.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fbtntintf.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fbtntintf.h	(revision 3445)
@@ -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>
+#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 sa_size_t NbLines() const ;
+  virtual sa_size_t NbColumns() const ;
+  virtual r_8 * GetLineD(sa_size_t  n) const ;
+  virtual r_8 GetCell( sa_size_t n, sa_size_t  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;
+  LONGLONG NBline;
+  int  NBcol;
+  r_8 NulVal;
+  int_4 BuffLen, BuffSens;
+  mutable uint_8 NFitsRead;
+  mutable LONGLONG LineDeb, LineFin;
+  vector<string> ColName;
+  bool* ColReadable;
+  double **Buffer;
+  mutable r_8 * mRet;
+};
+
+} // namespace SOPHYA
+#endif    /* FBTNTINTF_H_SEEN */
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.cc	(revision 3445)
@@ -0,0 +1,84 @@
+// Classe d'initialisation du module FitsIOServer
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "fiosinit.h"
+#include "fitsmanager.h"
+#include "fitshdtable.h"
+#include "fitsarrhand.h"
+
+#include "fitsntuple.h"
+#include "fitsspherehealpix.h"
+#include "fitsspherethetaphi.h"
+#include "fitslocalmap.h"
+#include "fitshistos.h"
+#include "fitsgenedata.h"
+
+
+#include <iostream> 
+
+/*! 
+  \class SOPHYA::FitsIOServerInitiator
+  \ingroup FitsIOServer
+  Perform registration of fits handlers.
+  \sa SOPHYA::FitsManager
+ */
+int FitsIOServerInitiator::FgInit = 0;
+
+// Module version number - 2.0 , Jul 2006
+// Module version number - 2.1 , Fev 2007 (version ll (LONGLONG) de cfitsio)
+#define MOD_VERS   2.1
+
+FitsIOServerInitiator::FitsIOServerInitiator()
+  : SophyaInitiator()
+{
+  FitsIOServerInitiator::FgInit++;
+  if (FitsIOServerInitiator::FgInit > 1)  return;
+
+//   Enregistrement des classes FitsHandler
+  //DBG   cout << " ---- FitsIOServerInitiator / DEBUG ---- debut RegisterHandler " << endl;
+  FitsManager::RegisterHandler(new FitsArrayHandler<int_2> , 1, "TArray<int_2>");
+  FitsManager::RegisterHandler(new FitsArrayHandler<int_4> , 1, "TArray<int_4> ");
+  FitsManager::RegisterHandler(new FitsArrayHandler<r_4> , 1, "TArray<r_4>");
+  FitsManager::RegisterHandler(new FitsArrayHandler< r_8 > , 1, "TArray<r_8>");
+
+  FitsManager::RegisterHandler(new FitsHandler<BaseDataTable>, 1, "DataTable");
+
+  // Enregistrement des classes heritant de FitsIOHandler
+  FitsManager::RegisterHandler(new FITS_NTuple, 0, "NTuple");
+  FitsManager::RegisterHandler(new FitsHandler<Histo>, 0, "Histo");
+  FitsManager::RegisterHandler(new FitsHandler<Histo2D>, 0, "Histo2D");
+  FitsManager::RegisterHandler(new FitsHandler<GeneralFitData>, 0, "GeneralFitData");
+  
+  FitsManager::RegisterHandler(new FITS_SphereHEALPix<r_4> , 0, "SphereHEALPix<r_4>");
+  FitsManager::RegisterHandler(new FITS_SphereHEALPix<r_8> , 0, "SphereHEALPix<r_8>");
+  FitsManager::RegisterHandler(new FITS_SphereHEALPix<int_4> , 0, "SphereHEALPix<int_4>");
+
+  FitsManager::RegisterHandler(new FITS_SphereThetaPhi<r_4> , 0, "SphereThetaPhi<r_4>");
+  FitsManager::RegisterHandler(new FITS_SphereThetaPhi<r_8> , 0, "SphereThetaPhi<r_8>");
+  FitsManager::RegisterHandler(new FITS_SphereThetaPhi<int_4> , 0, "SphereThetaPhi<int_4>");
+
+  FitsManager::RegisterHandler(new FITS_LocalMap<r_4> , 0, "LocalMap<r_4>");
+  FitsManager::RegisterHandler(new FITS_LocalMap<r_8> , 0, "LocalMap<r_8>");
+  FitsManager::RegisterHandler(new FITS_LocalMap<int_4> , 0, "LocalMap<int_4>");
+
+  //DBG  cout << " ---- FitsIOServerInitiator / DEBUG ---- ListHandlers() : " << endl;
+  //DBG  FitsManager::ListHandlers();
+
+  SophyaInitiator::RegisterModule("FitsIOServer", MOD_VERS);  // Module name and version number registration
+}
+
+FitsIOServerInitiator::~FitsIOServerInitiator()
+{
+  FitsIOServerInitiator::FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques  
+// #if !defined(Darwin)
+// Probleme rencontre de nouveau en Juillet 2006 sur MacOS :
+// La presence de l'objet statique fait planter les progs linkes libextsophya.dylib
+// static FitsIOServerInitiator s_fios_init_;
+// #endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fiosinit.h	(revision 3445)
@@ -0,0 +1,27 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module FitsIOServer
+
+#ifndef FITSIOSERVERINIT_H_SEEN
+#define FITSIOSERVERINIT_H_SEEN
+
+
+// Classe d''initialisation pour les modules de PEIDA++
+#include "sophyainit.h"
+
+namespace SOPHYA {  
+
+class FitsIOServerInitiator : public SophyaInitiator {
+private:
+  static int FgInit;
+public:
+  			FitsIOServerInitiator();
+  virtual		~FitsIOServerInitiator();
+};
+
+#define FitsIOServerInit() FitsIOServerInitiator fitsiosrvinit 
+
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsarrhand.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsarrhand.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsarrhand.h	(revision 3445)
@@ -0,0 +1,124 @@
+#ifndef FITSARRHAND_H
+#define FITSARRHAND_H
+
+#include "machdefs.h"
+#include <string>
+#include "tarray.h"
+#include "tvector.h"
+
+#include "fitshandler.h"
+#include "fitsblkrw.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for array objects
+*/
+
+template <class T>
+class FitsArrayHandler : public FitsHandlerInterface {
+public :
+  FitsArrayHandler() { dobj=NULL; ownobj=true; }
+  FitsArrayHandler(TArray< T > & obj) { dobj = &obj; ownobj=false; }
+  virtual   ~FitsArrayHandler() { if (ownobj && dobj) delete dobj; }
+  virtual   AnyDataObj* DataObj() { return(dobj); }
+
+  virtual   int         CheckHandling(AnyDataObj & o) 
+  {  
+    if ( (typeid(o) == typeid(TArray<T>)) ||
+	 (typeid(o) == typeid(TMatrix<T>)) ||
+	 (typeid(o) == typeid(TVector<T>)) )  return 2;
+    TArray<T> * po = dynamic_cast< TArray<T> * >(& o); 
+    if (po == NULL) return 0;
+    else return 1;
+  }
+
+  virtual   void        SetDataObj(AnyDataObj & o) 
+  {  
+    TArray<T> * po = dynamic_cast< TArray<T> * >(& o); 
+    if (po == NULL)  {
+      string msg = "FitsHandler<T>::SetDataObj() Wrong object type: " ;
+      msg += typeid(o).name(); 
+      throw TypeMismatchExc(msg);    
+    }
+    if (ownobj && dobj) delete dobj;  dobj = po; ownobj = false; 
+  }
+
+  virtual int         CheckReadability(FitsInOutFile& is)
+  {
+    if (is.CurrentHDUType() != IMAGE_HDU)  return 0;
+    T x = 0;
+    LONGLONG naxes[BASEARRAY_MAXNDIMS];
+    int naxis=BASEARRAY_MAXNDIMS;
+    int imgtyp = is.GetImageHDUInfo(naxis, naxes);
+    if (naxis < 1) return 0;
+    if (FitsTypes::ImageType(x) == imgtyp)  return 2;
+    else return 1;
+  }
+
+  virtual FitsHandlerInterface* Clone() 
+    { return new FitsArrayHandler< T >(); }
+
+  inline operator T&() { return(*dobj); }
+
+  //----- Ecriture
+  virtual void     Write(FitsInOutFile& os)
+    {
+      if ( dobj == NULL) 
+	throw NullPtrError("FitsArrayHandler<T>::Write() dobj=NULL ");
+      LONGLONG naxes[BASEARRAY_MAXNDIMS] = {0,0,0,0,0};
+      for(int_4 id=0; id<dobj->NbDimensions(); id++) 
+	naxes[id] = dobj->Size(id);
+      T x = 0;
+      os.CreateImageHDU(FitsTypes::ImageType(x), dobj->NbDimensions(), naxes);
+      os.WriteHeaderRecords(dobj->Info());
+      MuTyV mtv;
+      mtv = "SOPHYA::TArray<T>";
+      os.WriteKey("SOPCLSNM",mtv," Object class name "); 
+      FitsBlockRW<T>::WriteImageData(os, dobj->Data(), dobj->Size());
+    }
+
+  //----- Lecture
+  virtual void     Read(FitsInOutFile& is)
+    {
+      LONGLONG naxes[BASEARRAY_MAXNDIMS];
+      int naxis=BASEARRAY_MAXNDIMS;
+      is.GetImageHDUInfo(naxis, naxes);
+      if ( dobj == NULL) {
+	if (naxis == 1) dobj = new TVector<T>;
+	else if (naxis == 2) { 
+	  if ( (naxes[0] == 1) || (naxes[1] == 1) )  
+	    dobj = new TVector<T>;  
+	  else dobj = new TMatrix<T>;
+	}
+	else dobj = new TArray<T>;
+	ownobj = true;
+      }
+      sa_size_t sz[BASEARRAY_MAXNDIMS];
+      if (naxis > BASEARRAY_MAXNDIMS) naxis = BASEARRAY_MAXNDIMS;
+      for(int_4 id=0; id<naxis; id++) sz[id] = naxes[id];
+      dobj->SetSize(naxis, sz, 1, false);
+      FitsBlockRW<T>::ReadImageData(is, dobj->Data(), dobj->Size());
+      is.GetHeaderRecords(dobj->Info());
+    }
+
+protected :
+  TArray<T>  * dobj;
+  bool ownobj;       // True si dobj obtenu par new
+};
+
+
+template <class T>
+inline FitsInOutFile& operator << (FitsInOutFile& os, TArray<T> const & obj)
+{ FitsArrayHandler<T> fio(const_cast< TArray<T> &>(obj));  fio.Write(os);  return os; }
+
+template <class T>
+inline FitsInOutFile& operator >> (FitsInOutFile& is, TArray<T> & obj)
+{ FitsArrayHandler<T> fio(obj); fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.cc	(revision 3445)
@@ -0,0 +1,269 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsautoreader.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/FitsIOServer/fitsblkrw.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsblkrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsblkrw.h	(revision 3445)
@@ -0,0 +1,195 @@
+#ifndef FITSBLKRW_H
+#define FITSBLKRW_H
+
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Template class with static methods for handling bloc data 
+  read from / write to fits filesz
+*/
+
+template <class T>
+class FitsBlockRW {
+public:
+//! Write image HDU data to a fits file 
+static void WriteImageData(FitsInOutFile& fios, const T * d, size_t sz, 
+			   LONGLONG * fpixel=NULL)
+{
+  int status = 0;
+  LONGLONG fpix[5] = {1,1,1,1,1};
+  if (fpixel == NULL) fpixel = fpix;
+  T * ncd = const_cast<T *>(d);
+  fits_write_pixll(fios.FitsPtr(), FitsTypes::DataType(d[0]), fpixel,
+		 sz, ncd, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::WriteImageData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+}
+
+//! Read image HDU data from a fits file 
+static void ReadImageData(FitsInOutFile& fios,  T * d, size_t sz, 
+			  LONGLONG * fpixel=NULL)
+{
+  int status = 0;
+  LONGLONG fpix[5] = {1,1,1,1,1};
+  if (fpixel == NULL) fpixel = fpix;
+  int anynul = 0;
+  fits_read_pixll(fios.FitsPtr(), FitsTypes::DataType(d[0]), fpixel,
+		 sz, NULL, d, &anynul, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::ReadImageData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+
+}
+
+
+/*! 
+  Write binary/ascii HDU data to a fits file. 
+  See cfitsio function fits_write_col() for more detail.
+  \param colnum : table column number (starting from 1)
+  \param firstrow : the write operation starting row (starting from 1)
+  \param firstelem : the firstelem (for vector type columns)
+  \param d : pointer to data to be written
+  \param sz : number of data elements to be written
+*/
+static void WriteColumnData(FitsInOutFile& fios, int colnum, LONGLONG firstrow,
+			    LONGLONG firstelem, const T * d, size_t sz)
+{
+  int status = 0;
+  T * ncd = const_cast<T *>(d);
+  fits_write_col(fios.FitsPtr(), FitsTypes::DataType(d[0]), colnum,
+		 firstrow, firstelem, sz, ncd, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::WriteColumnData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+  return;
+}
+
+/*! 
+  Read binary/ascii HDU data from a fits file. 
+  See cfitsio function fits_read_col() for more detail.
+  \param colnum : table column number (starting from 1)
+  \param firstrow : the read operation starting point (row) (starting from 1)
+  \param firstelem : the firstelem (for vector type columns)
+  \param d : pointer to data to be written
+  \param sz : number of data elements to be read
+*/
+static void ReadColumnData(FitsInOutFile& fios, int colnum, LONGLONG firstrow,
+			   LONGLONG firstelem, T * d, size_t sz)
+{
+  int status = 0;
+  int anynul = 0;
+  fits_read_col(fios.FitsPtr(), FitsTypes::DataType(d[0]), colnum,
+		 firstrow, firstelem, sz, NULL, d, &anynul, &status);
+  if ( status ) {
+    fits_report_error(stderr, status);
+    char buff[32];
+    fits_get_errstatus(status, buff);
+    string msg = "FitsBlockRW<T>::ReadColumnData() Error: " ;
+    msg += buff;
+    throw FitsIOException(msg);
+  }
+  return;
+}
+
+
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class FitsBlockRW<std::string> {
+public:
+//! Write image HDU with string data type not supported (throws exception) 
+static void WriteImageData(FitsInOutFile& fios, const std::string * d, size_t sz, 
+			   LONGLONG * fpixel=NULL)
+{
+  throw FitsIOException(
+    "FitsBlockRW<string>::WriteImageData() string data type Unsupported for image HDU");
+}
+//! Read image HDU with string data type not supported (throws exception) 
+static void ReadImageData(FitsInOutFile& fios,  std::string * d, size_t sz, 
+			  LONGLONG * fpixel=NULL)
+{
+  throw FitsIOException(
+    "FitsBlockRW<string>::ReadImageData() string data type Unsupported for image HDU");
+}
+
+//! Write character string data to binary/ascii HDU data in a fits file. 
+static void WriteColumnData(FitsInOutFile& fios, int colnum, LONGLONG firstrow,
+			    LONGLONG firstelem, const std::string * d, size_t sz)
+{
+  int status = 0;
+  char sbuff[1024];
+  char * cp[4] = {sbuff, sbuff+256, sbuff+512, sbuff+768};
+  //cout << " --- Getting in WriteColumnData<string>() colnum=" << colnum << endl;
+  for(size_t kk=0; kk<sz; kk++) {
+    strncpy(sbuff, d[kk].c_str(), 1023);
+    //    char * cp = const_cast<char *>(d[kk].c_str());
+    sbuff[1023] = '\0';
+    status = 0;
+    //cout <<"DBG-Write2Fits : appel a fits_write_col() kk=" << kk << " / sz=" << sz << endl;
+    fits_write_col(fios.FitsPtr(), FitsTypes::DataType(sbuff), colnum,
+		   firstrow+kk, firstelem, 1, cp, &status);
+    if ( status ) {
+      fits_report_error(stderr, status);
+      char buff[32];
+      fits_get_errstatus(status, buff);
+      string msg = "FitsBlockRW<std::string>::WriteColumnData() Error: " ;
+      msg += buff;
+      sprintf(buff," kk=%ld",kk);  msg += buff;
+      throw FitsIOException(msg);
+    }
+  }
+  return;
+}
+
+
+//! Read character string data to binary/ascii HDU data in a fits file. 
+static void ReadColumnData(FitsInOutFile& fios, int colnum, LONGLONG firstrow,
+			   LONGLONG firstelem, std::string * d, size_t sz)
+{
+  int status = 0;
+  int anynul = 0;
+  char sbuff[1024];
+  char * cp[4] = {sbuff, sbuff+256, sbuff+512, sbuff+768};
+  //  cout << " --- Getting in ReadColumnData<string>() colnum=" << colnum << endl;
+  for(size_t kk=0; kk<sz; kk++) {
+    //    cout <<"DBG-ReadFrFits : appel a fits_read_col() kk=" << kk << " / sz=" << sz << endl;
+    fits_read_col(fios.FitsPtr(), FitsTypes::DataType(sbuff), colnum,
+		 firstrow+kk, firstelem, 1, NULL, cp, &anynul, &status);
+    sbuff[1023] = '\0'; d[kk] = sbuff;
+    if ( status ) {
+      fits_report_error(stderr, status);
+      char buff[32];
+      fits_get_errstatus(status, buff);
+      string msg = "FitsBlockRW<std::string>::ReadColumnData() Error: " ;
+      msg += buff;
+      sprintf(buff," kk=%ld",kk);  msg += buff;
+      throw FitsIOException(msg);
+    }
+  }
+  return;
+}
+
+};  // Fin classe   FitsBlockRW<std::string>
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.cc	(revision 3445)
@@ -0,0 +1,173 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsbntbllineRW.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/FitsIOServer/fitsfile.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsfile.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsfile.cc	(revision 3445)
@@ -0,0 +1,2576 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include "fitsfile.h"
+#include "pexceptions.h"
+#include "strutil.h"
+#include "anydataobj.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);
+}
+
+void FitsIOHandler::Read(FitsInOutFile& is) 
+{
+  FitsInFile fis(is);
+  fis.ReadHeader(fis.CurrentHDU());
+  ReadFromFits(fis);
+}
+
+  /*! \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);
+  WriteToFits(of);
+}
+
+void FitsIOHandler::Write(FitsInOutFile& os) 
+{
+  FitsOutFile fos(os);
+  WriteToFits(fos);
+}
+
+
+FitsFile::FitsFile()
+  : FitsInOutFile()
+{
+  InitNull();
+}
+
+FitsFile::FitsFile(FitsInOutFile const& fios)
+  : FitsInOutFile(fios)
+{
+  InitNull();
+  hdunum_ = fios.CurrentHDU();
+}
+
+
+/*RzDel 
+FitsFile::~FitsFile()
+{
+  //  Close fait par le destructeur de FitsInOutFile - Reza , Dec 2005
+  //  int status = 0;
+  //  if( fptr_ != NULL)
+  //    fits_close_file(fptr_,&status);
+  // 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()
+  : FitsFile()
+
+{
+  InitNull();
+}
+
+FitsInFile::FitsInFile(string const & flnm)
+  : FitsFile()
+{
+  InitNull();
+  Open(flnm.c_str(), Fits_RO);
+  /*RZDEL
+   int status = 0;
+   fits_open_file(&fptr_,flnm.c_str(),READONLY,&status);
+   if( status ) printerror( status );
+  */
+}
+
+FitsInFile::FitsInFile(const char * flnm)
+  : FitsFile()
+{
+  InitNull();
+  Open(flnm, Fits_RO);
+  /*RZDEL
+  int status = 0;
+   fits_open_file(&fptr_,flnm,READONLY,&status);
+   if( status ) printerror( status );
+  */
+}
+
+FitsInFile::FitsInFile(FitsInOutFile const& fios)
+  : FitsFile(fios)
+
+{
+  InitNull();
+  if (mode_ == Fits_Create)
+    throw FitsIOException("FitsInFile::FitsInFile(FitsInOutFile const& fios) newly created fits file");
+}
+
+
+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;
+	}
+    }
+}
+
+/*! 
+Get the NoLine-th float 'line'  from the current BINTABLE extension on FITS file,
+*/
+void FitsInFile::GetBinTabLine(int NoLine, double* ddata) 
+{
+  int status= 0;
+  int    anynul;
+  double dnull= fnull_;
+  long nels=1;
+  int ncol;
+  for (ncol=0; ncol<nbcols_; ncol++)
+    {
+      fits_read_col(fptr_, TDOUBLE, ncol+1,NoLine+1,1,1,&dnull,&ddata[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()
+  : FitsFile()
+{
+  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)
+  : FitsFile()
+{
+  InitNull();
+  openoutputfitsfile(flnm.c_str(), wrm);
+}
+
+FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
+  : FitsFile()
+{
+  InitNull();
+  openoutputfitsfile(flnm, wrm);
+}
+
+FitsOutFile::FitsOutFile(FitsInOutFile const& fios)
+  : FitsFile(fios)
+{
+  InitNull(); 
+  if (mode_ == Fits_RO)
+    throw FitsIOException("FitsOutFile::FitsOutFile(FitsInOutFile const& ) ReadOnly Fits file");
+}
+
+FitsOutFile::~FitsOutFile()
+{
+  if (dvlToPrimary_ != NULL) delete dvlToPrimary_;
+}
+
+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");
+	throw FitsIOException("FitsOutFile::openoutputfitsfile()/fits movabs error");
+	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");
+	    throw FitsIOException("FitsOutFile::openoutputfitsfile()/fits open Error ");
+	  }
+	  else  cout << "  WARNING : file " << flnm << " is overwritten " << endl;
+	  break;
+	}
+      case unknown : 
+	printerror(status, " file seems already to exist");
+	throw FitsIOException("FitsOutFile::openoutputfitsfile()/fits open Error - existing file");
+	break;
+      }
+    }
+  }
+  fname_ = flnm;
+  if ( wrm == append ) mode_ = Fits_RW;
+  else mode_ = Fits_Create;
+  ownfptr = true;
+}
+
+
+
+/*! \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_Nov2007/SophyaExt/FitsIOServer/fitsfile.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsfile.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsfile.h	(revision 3445)
@@ -0,0 +1,440 @@
+#ifndef FITSFILE_H
+#define FITSFILE_H
+
+#include "ndatablock.h"
+#include "dvlist.h"
+#include "fitsinoutfile.h" 
+#include "fitshandler.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 FitsHandlerInterface {
+
+
+ public:
+
+   virtual ~FitsIOHandler() {}
+   void   Read(char flnm[],int hdunum= 0);
+   void   Write(char flnm[]) ;
+
+   //Implementation par defaut de l'interface FitsHandlerInterface
+   virtual AnyDataObj* DataObj() { return NULL; }
+   virtual int         CheckHandling(AnyDataObj & o) { return 0; }
+   virtual void        SetDataObj(AnyDataObj & o) { return; }
+   virtual int         CheckReadability(FitsInOutFile& is) { return 0; }
+   virtual FitsHandlerInterface* Clone() { return NULL; }
+
+   virtual void   Read(FitsInOutFile& ifts);
+   virtual void   Write(FitsInOutFile& ofts) ;
+
+   virtual void   Read(FitsInFile& ifts, int hdunum=0);
+
+ 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 FitsInOutFile {
+
+ 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();
+   FitsFile(FitsInOutFile const& fios);
+   // RzDel 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() 
+  {
+    hdutype_= FitsExtensionType_NULL; 
+    hdunum_ = 0; 
+    fits_status_ = 0; imageOnPrimary_ = true;
+  }
+inline fitsfile* fitsfilePtr() const {return fptr_;}
+
+
+   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(FitsInOutFile const& fios);
+   //   virtual ~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   GetBinTabLine(int NoLine, double* ddata) ;
+ 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(FitsInOutFile const& fios);
+   virtual ~FitsOutFile();
+   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_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.cc	(revision 3445)
@@ -0,0 +1,209 @@
+#include "machdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "generaldata.h"
+
+#include "fitsblkrw.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<GeneralFitData>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM"; 
+  string clsnm = is.KeyValue(key);
+  if( clsnm == "SOPHYA::GeneralFitData") return 2;
+  return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<GeneralFitData>::CheckHandling(AnyDataObj & o) 
+{  
+ if (typeid(o) == typeid(GeneralFitData)) return 2;
+ GeneralFitData * po = dynamic_cast< GeneralFitData * >(& o); 
+ if (po != NULL) return 2;
+ return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<GeneralFitData>::Write(FitsInOutFile& os)
+{
+  if(dobj==NULL)   
+    throw NullPtrError("FitsHandler<GeneralFitData>::Write() NULL dobj pointer ");
+
+  //--- Le type d'objet et son pointeur
+  GeneralFitData* gd = dynamic_cast< GeneralFitData *> (dobj);
+  long nvar = gd->mNVar;
+  if(nvar<=0)
+    throw NullPtrError("FitsHandler<GeneralFitData>::Write() no variables ");
+
+  //--- Les noms de colonnes
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  // La variable Y et son Erreur
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("y");
+  tunit.push_back("");
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("ey");
+  tunit.push_back("");
+  // Le flag de validite
+  if(tbltyp==ASCII_TBL) tform.push_back("I9"); else tform.push_back("J");
+  colnames.push_back("ok");
+  tunit.push_back("");
+  // Les variables X
+  for(int i=0;i<nvar;i++) {
+    char str[16]; sprintf(str,"x%d",i);
+    if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+    colnames.push_back(str);
+    tunit.push_back("");
+  }
+  // Les erreurs sur les variables X
+  if(gd->HasXErrors()) {
+    for(int i=0;i<nvar;i++) {
+      char str[16]; sprintf(str,"ex%d",i);
+      if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+      colnames.push_back(str);
+      tunit.push_back("");
+    }
+  }
+
+  //--- On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(),extname,colnames,tform,tunit);
+
+  //--- Ecriture des donnees des colonnes
+  long n = gd->mNDataAlloc;
+  if(n>0) {
+    // Y
+    FitsBlockRW<r_8>::WriteColumnData(os,1,1,1,gd->mF,n);
+    // EY
+    FitsBlockRW<r_8>::WriteColumnData(os,2,1,1,gd->mErr,n);
+    // Le flag de validite
+    int_4 *ival = new int_4[n];
+    for(int_4 i=0;i<n;i++) ival[i] =  gd->mOK[i];
+    FitsBlockRW<int_4>::WriteColumnData(os,3,1,1,ival,n);
+    delete [] ival;
+    // les variables X
+    r_8 *val = new r_8[n];
+    for(int k=0;k<nvar;k++) {
+      for(int_4 i=0;i<n;i++) val[i] = gd->mXP[nvar*i+k];
+      FitsBlockRW<r_8>::WriteColumnData(os,4+k,1,1,val,n);
+    }
+    // les erreurs sur les variables X
+    if(gd->HasXErrors()) {
+      for(int k=0;k<nvar;k++) {
+        for(int_4 i=0;i<n;i++) val[i] = gd->mErrXP[nvar*i+k];
+        FitsBlockRW<r_8>::WriteColumnData(os,4+nvar+k,1,1,val,n);
+      }
+    }
+    delete [] val;
+  }
+
+  //--- Ecriture des clefs fits
+  MuTyV mtv;
+
+  mtv = "SOPHYA::GeneralFitData";
+  os.WriteKey("SOPCLSNM",mtv," SOPHYA class name");
+
+  mtv = "GeneralFitData";
+  os.WriteKey("CONTENT",mtv," name of SOPHYA object");
+
+  mtv = gd->mNVar;
+  os.WriteKey("NVAR",mtv," number of variables X");
+
+  mtv = gd->mNDataAlloc;
+  os.WriteKey("NALLOC",mtv," number of allocated data");
+  mtv = gd->mNData;
+  os.WriteKey("NDATA",mtv," number of filled data");
+  mtv = gd->mNDataGood;
+  os.WriteKey("NGOOD",mtv," number of good filled data");
+
+  mtv = (int_4)((gd->HasXErrors())? 1: 0);
+  os.WriteKey("HASXERR",mtv," erreurs sur X?");
+
+  return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<GeneralFitData>::Read(FitsInOutFile& is)
+{
+ int hdutyp = is.CurrentHDUType();
+ if( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() Not a binary or ascii table HDU");
+
+  //--- Nb de lignes et de colonnes 
+  vector<string> colnames; vector<int> coltypes; vector<LONGLONG> repcnt, width;
+  is.GetColInfo(colnames,coltypes,repcnt,width);
+  long ncol = colnames.size();
+  if(ncol<=0)
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() bad number of table columns");
+  int_8 nbrows = is.GetNbRows();
+  if(nbrows<=0)
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() number of rows is zero, no reading");
+
+  //--- Lecture entete FITS
+  DVList dvl; is.GetHeaderRecords(dvl,true,false);
+
+  int_4 nvar = dvl.GetI("NVAR",-1);
+  if(nvar<=0)
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() number of variables is zero, no reading");
+
+  int_4 ndatalloc = dvl.GetI("NALLOC",-1);
+  if(ndatalloc<=0)
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() number of allocated data is zero, no reading");
+  int_4 ndata = dvl.GetI("NDATA",-1);
+  int_8 ndatagood = dvl.GetI("NGOOD",-1);
+
+  int_4 dum = dvl.GetI("HASXERR",0);
+  uint_2 ok_ex = (dum==0) ? 0: 1;
+
+  int mynvar = 3 + nvar + ((ok_ex>0)? nvar: 0);
+  if(ncol!=mynvar)
+    throw FitsIOException("FitsHandler<GeneralFitData>::Read() inconsistent header/mvar, no reading");
+
+  //--- Creation de l'objet
+  if(dobj == NULL) dobj = new GeneralFitData;
+  dobj->Alloc(nvar,ndatalloc,ok_ex);
+
+  //--- remplissage des variables privees restantes
+  dobj->mNData = ndata;
+  dobj->mNDataGood = ndatagood;
+
+  //--- remplissage de la structure de donnees
+  if(ndata>0) {
+    // Y
+    FitsBlockRW<r_8>::ReadColumnData(is,1,1,1,dobj->mF,ndata);
+    // EY
+    FitsBlockRW<r_8>::ReadColumnData(is,2,1,1,dobj->mErr,ndata);
+    // Le flag de validite
+    int_4 *ival = new int_4[ndata];
+    FitsBlockRW<int_4>::ReadColumnData(is,3,1,1,ival,ndata);
+    for(int_4 i=0;i<ndata;i++) dobj->mOK[i] = (uint_2)ival[i];
+    delete [] ival;
+    // les variables X
+    r_8 *val = new r_8[ndata];
+    for(int k=0;k<nvar;k++) {
+      FitsBlockRW<r_8>::ReadColumnData(is,4+k,1,1,val,ndata);
+      for(int_4 i=0;i<ndata;i++) dobj->mXP[nvar*i+k] = val[i];
+    }
+    // les erreurs sur les variables X
+    if(dobj->HasXErrors()) {
+      for(int k=0;k<nvar;k++) {
+        FitsBlockRW<r_8>::ReadColumnData(is,4+nvar+k,1,1,val,ndata);
+        for(int_4 i=0;i<ndata;i++) dobj->mErrXP[nvar*i+k] = val[i];
+      }
+    }
+    delete [] val;
+  }
+
+  return;
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsgenedata.h	(revision 3445)
@@ -0,0 +1,27 @@
+#ifndef FITSGENDATAHAND_H
+#define FITSGENDATAHAND_H
+
+#include "machdefs.h"
+#include <string>
+
+#include "generaldata.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for GeneralFitData objects
+*/
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, GeneralFitData const & obj)
+{ FitsHandler<GeneralFitData> fio(const_cast<GeneralFitData &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, GeneralFitData & obj)
+  { FitsHandler<GeneralFitData> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshandler.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshandler.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshandler.h	(revision 3445)
@@ -0,0 +1,110 @@
+#ifndef FITSHANDLER_H
+#define FITSHANDLER_H
+
+#include "machdefs.h"
+#include <string>
+#include <typeinfo>
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Interface definition for classes handling object storage retrieval in FITS Format 
+*/
+class FitsHandlerInterface {
+
+public:
+
+  virtual ~FitsHandlerInterface() {}
+  //! Return the real data object
+  virtual AnyDataObj* DataObj() = 0;       // Retourne l'objet reel 
+
+  /*! 
+    \brief Return a positive value if I/O for object \b o can be handled
+
+    - Rc= 0 -> Can NOT handle fits I/O operations for the object \b o 
+    - Rc= 1 -> Can handle fits I/O operations for the object \b o 
+    - Rc= 2 -> This is a specific handler for object \b o
+    - Rc > 2 -> Higher Rc values can be returned if needed 
+      (for subclasses with specific handlers)
+
+  */
+  virtual int         CheckHandling(AnyDataObj & o) = 0;
+  //! Read/write operation will use the object o
+  virtual void        SetDataObj(AnyDataObj & o) = 0;
+
+  //! 
+  /*! 
+    \brief Return a positive value if current HDU can be read by the handler
+
+    - Rc= 0 -> Can NOT read the current HDU 
+    - Rc= 1 -> Can read the current HDU (generic reader)
+    - Rc= 2 -> Can read the current HDU, as a specific reader
+    - Rc > 2 -> Higher Rc values can be returned if needed 
+      (when multiple specific handlers are registered) 
+
+  */
+  virtual int         CheckReadability(FitsInOutFile& is) = 0;
+  
+  //! Clone (duplicate) the handler class
+  virtual FitsHandlerInterface* Clone() = 0;
+
+  //! Perform the actual write operation to the output fits file
+  virtual void        Write(FitsInOutFile& os) = 0;
+  //! Perform the actual read operation from input fits file
+  virtual void        Read(FitsInOutFile& is) = 0;  
+};
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Generic implementation of FitsHandlerInterface 
+*/
+template <class T>
+class FitsHandler : public FitsHandlerInterface {
+
+public :
+	    FitsHandler() { dobj=NULL; ownobj=true; }
+	    FitsHandler(T & obj) { dobj = &obj; ownobj=false; }
+  virtual   ~FitsHandler() { if (ownobj && dobj) delete dobj; }
+
+  virtual   AnyDataObj* DataObj() { return(dobj); }
+  virtual   int         CheckHandling(AnyDataObj & o) 
+  {  
+    if (typeid(o) == typeid(T)) return 2;
+    T * po = dynamic_cast< T * >(& o); 
+    if (po == NULL) return 0;
+    else return 1;
+  }
+  virtual   void        SetDataObj(AnyDataObj & o) 
+  {  
+    T * po = dynamic_cast< T * >(& o); 
+    if (po == NULL)  {
+      string msg = "FitsHandler<T>::SetDataObj() Wrong object type: " ;
+      msg += typeid(o).name(); 
+      throw TypeMismatchExc(msg);    
+    }
+    if (ownobj && dobj) delete dobj;  dobj = po; ownobj = false; 
+  }
+
+  virtual int         CheckReadability(FitsInOutFile& is);
+    
+  virtual FitsHandlerInterface* Clone() 
+    { return new FitsHandler<T>() ; }
+
+  inline operator T&() { return(*dobj); }
+
+  virtual void        Read(FitsInOutFile& is);
+  virtual void        Write(FitsInOutFile& os);
+
+protected :
+  T * dobj;
+  bool ownobj;       // True si dobj obtenu par new
+};
+
+
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.cc	(revision 3445)
@@ -0,0 +1,385 @@
+#include "machdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "datatable.h"
+#include "fitsblkrw.h"
+#include "fitshandler.h"
+#include "swfitsdtable.h"
+
+namespace SOPHYA {
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<BaseDataTable>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM"; 
+  string clsnm = is.KeyValue(key);
+  if ( (clsnm == "SOPHYA::DataTable") || (clsnm == "SOPHYA::SwFitsDataTable") )
+    return 2;
+  else return 1;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<BaseDataTable>::Write(FitsInOutFile& os)
+{
+  
+  if (dobj == NULL)   
+    throw NullPtrError("FitsHandler<DataTable>::Write() NULL dobj pointer ");
+
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
+
+  int tbltyp = os.GetDef_TableType();
+  if ( swfdt && (tbltyp == ASCII_TBL) )
+    throw FitsIOException("FitsHandler<DataTable>::Write() ASCII_TBL not supported for SwFitsDataTable");
+
+  // On ne reecrit pas la definition d'une SwFitsDataTable dans son fichier de swap
+  if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) && swfdt->NRows() )  return;
+
+  string strcoltag;
+  long strwidth = os.GetDef_StrColWidth(); 
+  if (strwidth < 1) strwidth = 16;
+  char buff[32];
+  if (tbltyp == ASCII_TBL) 
+    sprintf(buff, "A%ld",strwidth);
+  else 
+    sprintf(buff, "%ldA",strwidth);
+  strcoltag = buff;
+
+  vector<string> colnames, tform, tunit;
+  for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+    bool fgoknm = true;
+    bool fgoktun = true;
+    switch ( dobj->GetColumType(k) ) {
+    case BaseDataTable::IntegerField :
+      if (tbltyp == ASCII_TBL) tform.push_back("I9");
+      else tform.push_back("J");
+      break;
+    case BaseDataTable::LongField :
+      if (tbltyp == ASCII_TBL) tform.push_back("I12");
+      else tform.push_back("K");
+      break;
+    case BaseDataTable::FloatField :
+      if (tbltyp == ASCII_TBL) tform.push_back("E12.5");
+      else tform.push_back("E");
+      break;
+    case BaseDataTable::DoubleField :
+    case BaseDataTable::DateTimeField :
+      if (tbltyp == ASCII_TBL) tform.push_back("D15.8");
+      else tform.push_back("D");
+      if (dobj->GetColumType(k) == BaseDataTable::DateTimeField ) {
+	tunit.push_back("Days (DateTimeField)");
+	fgoktun = false;
+      }
+      break;
+    case BaseDataTable::ComplexField :
+      if (tbltyp == ASCII_TBL) { 
+	cout << "FitsHandler<BaseDataTable>::Write()/Warning ComplexField not supported for ASCII_TBL " 
+	     << endl;
+	fgoknm = false;
+      }
+      else   tform.push_back("C");
+      break;
+    case BaseDataTable::DoubleComplexField :
+      if (tbltyp == ASCII_TBL) {
+	cout << "FitsHandler<BaseDataTable>::Write()/Warning DoubleComplexField not supported for ASCII_TBL " 
+	     << endl;
+	fgoknm = false;
+      }
+      else   tform.push_back("M");
+      break;
+    case BaseDataTable::StringField :
+      tform.push_back(strcoltag);
+      break;
+    default:
+      throw IOExc("FitsHandler<BaseDataTable>::Write() unknown column type ");
+      break;
+    }
+    if (fgoknm) {
+      colnames.push_back(dobj->GetColumName(k));
+      if (fgoktun) tunit.push_back("");
+    }
+  }
+
+  // On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(), extname, colnames, tform, tunit);
+
+  // On n'ecrit pas les donnees d'une table SwFitsDataTable ds son fichier de swap 
+  if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) )  return;
+
+  // Ecriture des donnees des colonnes
+  for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) { 
+    sa_size_t icol = 0;
+    sa_size_t sz = dobj->SegmentSize();
+    sa_size_t iseg = l/sz;
+    if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
+    for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+      sa_size_t sk = dobj->mNames[k].ser;
+      //DBG cout << "DBG-A k= " << k << " nom=" << dobj->mNames[k].nom << " ser=" << sk
+      //DBG   << " type=" << dobj->GetColumType(k) << endl;
+      switch ( dobj->GetColumType(k) ) {
+      case BaseDataTable::IntegerField :
+	icol++;
+	FitsBlockRW<int_4>::WriteColumnData(os, icol, l+1, 1, 
+					    dobj->mIColsP[sk]->GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::LongField :
+	icol++;
+	FitsBlockRW<int_8>::WriteColumnData(os, icol, l+1, 1, 
+					    dobj->mLColsP[sk]->GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::FloatField :
+	icol++;
+	FitsBlockRW<r_4>::WriteColumnData(os, icol, l+1, 1, 
+					  dobj->mFColsP[sk]->GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	icol++;
+	FitsBlockRW<r_8>::WriteColumnData(os, icol, l+1, 1, 
+					  dobj->mDColsP[sk]->GetCstSegment(iseg), sz);
+	break;
+      case BaseDataTable::ComplexField :
+	if (tbltyp == BINARY_TBL) { 
+	  icol++;
+	  FitsBlockRW< complex<r_4> >::WriteColumnData(os, icol, l+1, 1, 
+						       dobj->mYColsP[sk]->GetCstSegment(iseg), sz);
+	}
+	break;
+      case BaseDataTable::DoubleComplexField :
+	if (tbltyp == BINARY_TBL) { 
+	  icol++;
+	  FitsBlockRW< complex<r_8> >::WriteColumnData(os, icol, l+1, 1, 
+						       dobj->mZColsP[sk]->GetCstSegment(iseg), sz);
+	}
+	break;
+      case BaseDataTable::StringField :
+	icol++;
+	FitsBlockRW<std::string>::WriteColumnData(os, icol, l+1, 1, 
+						  dobj->mSColsP[sk]->GetCstSegment(iseg), sz);
+	break;
+      default:
+	break;
+      }
+    }
+  }
+
+  // Ecriture de SegmentSize et autre elements de DVList  
+  os.WriteHeaderRecords(dobj->Info());
+  MuTyV mtv = dobj->SegmentSize();
+  os.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
+  mtv = "SOPHYA::DataTable";
+  os.WriteKey("SOPCLSNM",mtv," Object class name "); 
+}
+
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<BaseDataTable>::Read(FitsInOutFile& is)
+{
+ 
+  int hdutyp = is.CurrentHDUType();
+  if ( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<DataTable>::Read() Not a binary or ascii table HDU");
+
+  // Determination de la taille de segment 
+  sa_size_t segsz = is.GetNbRows() / 64; // Taille de segment par defaut 
+  if (segsz > 2048) segsz = 2048;
+  string key = "SEGMSIZE";
+  bool knex = false;
+  string ssegsz = is.KeyValue(key, knex);
+  bool fgsss = false; 
+  if (!knex && (ssegsz.length() > 0))  { segsz = atoi(ssegsz.c_str());  fgsss = true; }
+  if (segsz < 16) segsz = 16;
+
+  // Nb de lignes et de colonnes 
+  vector<string> colnames;
+  vector<int> coltypes;
+  vector<LONGLONG> repcnt, width;
+  vector<sa_size_t> colpos;
+  is.GetColInfo(colnames, coltypes, repcnt, width);
+  int_8 nbrows = is.GetNbRows();
+
+  if (dobj == NULL) { // On cree la table si besoin 
+    /*
+      Reza, Sep06 : On ne cree pas automatiquement un SwFitsDataTable - 
+      En effet, on ne peut garantir que l'objet FitsInOutFile is reste 
+      valide pendant toute la duree de vie de l'objet SwFitsDataTable
+
+    string key = "SOPCLSNM"; 
+    string clsnm = is.KeyValue(key);
+        if ( (clsnm == "SOPHYA::SwFitsDataTable") || (nbrows*colnames.size() < 10000000) )
+      dobj = new DataTable(segsz);
+    else { 
+      dobj = new SwFitsDataTable(segsz);
+      // dobj = new SwFitsDataTable(is, segsz, false);
+      // Reza, Sep2006: Ce constructeur de SwFitsDataTable lit l'entete 
+      // et initialise donc l'objet SwFitsDataTable  -> return
+      // return;
+    }
+    */
+    dobj = new DataTable(segsz);
+  }
+  else { 
+    dobj->Clear();  // On efface la table sinon 
+    if (fgsss)  dobj->mSegSz = segsz;
+  }
+
+  // Type reel de table
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
+
+  vector<int_8> swpos;
+  segsz = dobj->mSegSz;
+  int_8 swp = 1;
+  while (swp < nbrows) {
+    swpos.push_back(swp); swp += segsz;
+  }
+  // Initialize the fits swap stream for SwFitsDataTable if necessary
+  if (swfdt)  {
+    if ( swfdt->FitsSwapFile().FitsPtr() != is.FitsPtr() ) {
+      //      swfdt->FitsSwapFile().Close(); 
+      //      swfdt->FitsSwapFile().Open(is.FileName().c_str(), FitsInOutFile::Fits_RO);
+      //      swfdt->FitsSwapFile().MoveAbsToHDU(is.CurrentHDU());
+      swfdt->FitsSwapFile().ShareFitsPtr(is); 
+    }
+  }
+
+  // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment 
+  for(sa_size_t k=0; k<colnames.size(); k++) { 
+    string ocolnm = colnames[k];
+    if (dobj->CheckCorrectColName(colnames[k]) ) 
+      cout << "FitsHandler<BaseDataTable>::Read()/Warning Column name changed for col[" 
+	   << k << "] " << ocolnm << " -> " << colnames[k] << endl;
+
+    switch ( coltypes[k] ) {
+    case TBYTE :
+    case TSHORT :
+    case TUSHORT :
+    case TINT :
+      if (swfdt) 
+	swfdt->AddColRd(BaseDataTable::IntegerField, colnames[k], k+1, &swpos);
+      else dobj->AddIntegerColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TUINT:
+    case TLONG :
+    case TULONG :
+#ifdef TLONGLONG
+    case TLONGLONG :
+#endif 
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::LongField, colnames[k], k+1, &swpos);     
+      else dobj->AddLongColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TFLOAT :
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::FloatField, colnames[k], k+1, &swpos);     
+      else dobj->AddFloatColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TDOUBLE :
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::DoubleField, colnames[k], k+1, &swpos);     
+      else dobj->AddDoubleColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TCOMPLEX :
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::ComplexField, colnames[k], k+1, &swpos);     
+      else dobj->AddComplexColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TDBLCOMPLEX :
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::DoubleComplexField, colnames[k], k+1, &swpos);     
+      else dobj->AddDoubleComplexColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    case TSTRING :
+      if (swfdt)       
+	swfdt->AddColRd(BaseDataTable::StringField, colnames[k], k+1, &swpos);     
+      else dobj->AddStringColumn(colnames[k]);
+      colpos.push_back(k+1);
+      break;
+    default:
+      cout << "FitsHandler<BaseDataTable>::Read() NOT handled field type " 
+	   << coltypes[k] << endl;
+      break;
+    }
+  }
+
+  // ------- Mise a jour des champs Nb d'entrees, nb segments ...
+  dobj->mNEnt = is.GetNbRows();
+  // Lecture DVList  (=entete FITS) 
+  is.GetHeaderRecords(dobj->Info());
+
+  // On ne doit pas lire les donnees de la table pour un SwFitsDataTable
+  if (swfdt) {
+    swfdt->mNSeg = swpos.size();
+    return;
+  }
+
+  while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
+    dobj->Extend();
+  //DBG  cout << " DBG2 -- dobj->mNSeg = " << dobj->NbSegments() << " SegSize=" 
+  //DBG   << dobj->SegmentSize() << " NEntry=" << dobj->NEntry() << endl;
+
+  // Lecture des donnees des colonnes
+  for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) { 
+    sa_size_t icol = 0;
+    sa_size_t sz = dobj->SegmentSize();
+    sa_size_t iseg = l/sz;
+    if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
+    for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+      sa_size_t sk = dobj->mNames[k].ser;
+      icol = colpos[k];
+      //      cout << " DBG-3 , k=" << k << " icol=" << icol << endl;
+      switch ( dobj->GetColumType(k) ) {
+      case BaseDataTable::IntegerField :
+	FitsBlockRW<int_4>::ReadColumnData(is, icol, l+1, 1, 
+					    dobj->mIColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::LongField :
+	FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1, 
+					   dobj->mLColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::FloatField :
+	FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1, 
+					 dobj->mFColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1, 
+					 dobj->mDColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::ComplexField :
+	FitsBlockRW< complex<r_4> >::ReadColumnData(is, icol, l+1, 1, 
+						    dobj->mYColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::DoubleComplexField :
+	FitsBlockRW< complex<r_8> >::ReadColumnData(is, icol, l+1, 1, 
+						    dobj->mZColsP[sk]->GetSegment(iseg), sz);
+	break;
+      case BaseDataTable::StringField :
+	FitsBlockRW<std::string>::ReadColumnData(is, icol, l+1, 1, 
+						 dobj->mSColsP[sk]->GetSegment(iseg), sz);
+	break;
+      default:
+	break;
+      }
+    }
+  }
+
+}
+
+
+} // FIN namespace SOPHYA 
+
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshdtable.h	(revision 3445)
@@ -0,0 +1,30 @@
+#ifndef FITSDTABLEHAND_H
+#define FITSDTABLEHAND_H
+
+#include "machdefs.h"
+#include <string>
+#include "datatable.h"
+
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for DataTable objects
+*/
+
+
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, BaseDataTable const & obj)
+{ FitsHandler<BaseDataTable> fio(const_cast<BaseDataTable &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, BaseDataTable & obj)
+  { FitsHandler<BaseDataTable> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.cc	(revision 3445)
@@ -0,0 +1,305 @@
+#include "machdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "histerr.h"
+#include "hist2err.h"
+
+#include "fitsblkrw.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////// Histo , HProf , HistoErr ////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<HistoErr>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM";
+  string clsnm = is.KeyValue(key);
+  if(clsnm == "SOPHYA::HistoErr") return 2;
+  return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<HistoErr>::CheckHandling(AnyDataObj & o) 
+{  
+ if (typeid(o) == typeid(HistoErr)) return 2;
+ HistoErr * po = dynamic_cast< HistoErr * >(& o); 
+ if (po != NULL) return 2;
+ return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<HistoErr>::Write(FitsInOutFile& os)
+{
+  if(dobj==NULL)   
+    throw NullPtrError("FitsHandler<HistoErr>::Write() NULL dobj pointer ");
+
+  //--- Le type d'objet et son pointeur
+  HistoErr* he = dynamic_cast< HistoErr *> (dobj);
+
+  //--- Les noms de colonnes
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  // les valeurs du bin
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("val");
+  tunit.push_back("");
+  // Les erreurs
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("e2");
+  tunit.push_back("");
+  // Le nombre d'entrees dans le bin
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("nb");
+  tunit.push_back("");
+
+  //--- On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(),extname,colnames,tform, tunit);
+
+  // Ecriture des donnees des colonnes
+  int n = he->NBins();
+  if(n>0) {
+    FitsBlockRW<r_8>::WriteColumnData(os,1,1,1,&(he->data_(0)),n);
+    FitsBlockRW<r_8>::WriteColumnData(os,2,1,1,&(he->err2_(0)),n);
+    FitsBlockRW<r_8>::WriteColumnData(os,3,1,1,&(he->ndata_(0)),n);
+  }
+
+  // Ecriture des clefs fits
+  MuTyV mtv;
+
+  mtv = "SOPHYA::HistoErr";
+  os.WriteKey("SOPCLSNM",mtv," SOPHYA class name");
+
+  mtv = "HistoErr";
+  os.WriteKey("CONTENT",mtv," name of SOPHYA object");
+
+  mtv = he->NBins();
+  os.WriteKey("NBIN",mtv," number of bins");
+
+  mtv = he->XMin();
+  os.WriteKey("XMIN",mtv," absc of beginning of 1srt bin");
+
+  mtv = he->XMax();
+  os.WriteKey("XMAX",mtv," absc of end of last bin");
+
+  mtv = he->BinWidth();
+  os.WriteKey("WBIN",mtv," bin width");
+  
+  mtv = he->mMean;
+  os.WriteKey("NMEAN",mtv," number of Mean/Variance calls");
+
+  return;
+}
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<HistoErr>::Read(FitsInOutFile& is)
+{
+ int hdutyp = is.CurrentHDUType();
+ if( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<HistoErr>::Read() Not a binary or ascii table HDU");
+
+  //--- Nb de lignes et de colonnes 
+  vector<string> colnames;
+  vector<int> coltypes;
+  vector<LONGLONG> repcnt, width;
+  is.GetColInfo(colnames,coltypes,repcnt,width);
+  long ncol = colnames.size();
+  if(ncol<=0)
+    throw FitsIOException("FitsHandler<HistoErr>::Read() bad number of table columns");
+  long nbrows = is.GetNbRows();
+  if(nbrows<=0)
+    throw FitsIOException("FitsHandler<HistoErr>::Read() number of rows is zero, no reading");
+
+  //--- Lecture entete FITS
+  string key = "SOPCLSNM"; string clsnm = is.KeyValue(key);
+  DVList dvl; is.GetHeaderRecords(dvl,true,false);
+
+  int_4 nbin = dvl.GetI("NBIN",-1);
+  if(nbin<=0 && nbin!=nbrows)
+    throw FitsIOException("FitsHandler<HistoErr>::Read() number of bins is zero or bad, no reading");
+
+  r_8 xmin = dvl.GetD("XMIN",-1.);
+  r_8 xmax = dvl.GetD("XMAX",+1.);
+
+  //--- Creation de l'objet si necessaire
+  if(dobj == NULL) {
+    if(clsnm == "SOPHYA::HistoErr") dobj = new HistoErr;
+  }
+
+  //--- Type de l'histo
+  HistoErr* he = dynamic_cast< HistoErr *> (dobj);
+
+  //--- Allocation pour histo
+  if(he && (clsnm=="SOPHYA::HistoErr")) {
+    if(ncol<3)
+      throw FitsIOException("FitsHandler<HistoErr>::Read() wrong number of columns for HistoErr");
+    he->CreateOrResize(xmin,xmax,nbin);
+  } else {
+    throw FitsIOException("FitsHandler<HistoErr>::Read() No assocaition classe/fits_header");
+  }
+
+  //--- remplissage des variables d'entete
+  he->mMean = dvl.GetI("NMEAN",0);
+
+  //--- remplissage de l'histo
+  FitsBlockRW<r_8>::ReadColumnData(is,1,1,1,&(he->data_(0)),nbin);
+  FitsBlockRW<r_8>::ReadColumnData(is,2,1,1,&(he->err2_(0)),nbin);
+  FitsBlockRW<r_8>::ReadColumnData(is,3,1,1,&(he->ndata_(0)),nbin);
+
+  return;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Histo2DErr ////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo2DErr>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM"; 
+  string clsnm = is.KeyValue(key);
+  if( clsnm == "SOPHYA::Histo2DErr") return 2;
+  return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo2DErr>::CheckHandling(AnyDataObj & o) 
+{  
+ if (typeid(o) == typeid(Histo2DErr)) return 2;
+ Histo2DErr * po = dynamic_cast< Histo2DErr * >(& o); 
+ if (po != NULL) return 2;
+ return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo2DErr>::Write(FitsInOutFile& os)
+{
+  if(dobj==NULL)   
+    throw NullPtrError("FitsHandler<Histo2DErr>::Write() NULL dobj pointer ");
+
+  //--- Le type d'objet et son pointeur
+  Histo2DErr* he2 = dynamic_cast< Histo2DErr *> (dobj);
+
+  //--- Les noms de colonnes
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  // les valeurs du bin
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("val");
+  tunit.push_back("");
+  // Les erreurs
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("e2");
+  tunit.push_back("");
+  // Les nombres d'entrees
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("nb");
+  tunit.push_back("");
+
+  //--- On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(),extname,colnames,tform, tunit);
+
+  // Ecriture des donnees des colonnes
+  long n = he2->NBinX()*he2->NBinY();
+  if(n>0) {
+    FitsBlockRW<r_8>::WriteColumnData(os,1,1,1,&(he2->data_(0,0)),n);
+    FitsBlockRW<r_8>::WriteColumnData(os,2,1,1,&(he2->err2_(0,0)),n);
+    FitsBlockRW<r_8>::WriteColumnData(os,3,1,1,&(he2->ndata_(0,0)),n);
+  }
+
+  // Ecriture des clefs fits
+  MuTyV mtv;
+
+  mtv = "SOPHYA::Histo2DErr";
+  os.WriteKey("SOPCLSNM",mtv," SOPHYA class name");
+
+  mtv = "Histo2DErr";
+  os.WriteKey("CONTENT",mtv," name of SOPHYA object");
+
+  mtv = he2->NBinX();
+  os.WriteKey("NBINX",mtv," number of bins in X");
+  mtv = he2->NBinY();
+  os.WriteKey("NBINY",mtv," number of bins in Y");
+  mtv = he2->NBinX()*he2->NBinY();
+  os.WriteKey("NBINXY",mtv," (i,j): fits_row=i*NY+j 0<=i<NX 0<=j<NY");
+
+  mtv = he2->XMin();
+  os.WriteKey("XMIN",mtv," absc of beginning of 1srt bin in X");
+  mtv = he2->XMax();
+  os.WriteKey("XMAX",mtv," absc of end of last bin in X");
+  mtv = he2->YMin();
+  os.WriteKey("YMIN",mtv," absc of beginning of 1srt bin in Y");
+  mtv = he2->YMax();
+  os.WriteKey("YMAX",mtv," absc of end of last bin in Y");
+
+  mtv = he2->WBinX();
+  os.WriteKey("WBINX",mtv," bin width in X");
+  mtv = he2->WBinY();
+  os.WriteKey("WBINY",mtv," bin width in Y");
+  
+  mtv = he2->mMean;
+  os.WriteKey("NMEAN",mtv," number of Mean/Variance calls");
+
+  return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo2DErr>::Read(FitsInOutFile& is)
+{
+ int hdutyp = is.CurrentHDUType();
+ if( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<Histo2DErr>::Read() Not a binary or ascii table HDU");
+
+  //--- Nb de lignes et de colonnes 
+  vector<string> colnames; vector<int> coltypes; vector<LONGLONG> repcnt, width;
+  is.GetColInfo(colnames,coltypes,repcnt,width);
+  long ncol = colnames.size();
+  if(ncol<=0)
+    throw FitsIOException("FitsHandler<Histo2DErr>::Read() bad number of table columns");
+  long nbrows = is.GetNbRows();
+  if(nbrows<=0)
+    throw FitsIOException("FitsHandler<Histo2DErr>::Read() number of rows is zero, no reading");
+
+  //--- Lecture entete FITS
+  DVList dvl; is.GetHeaderRecords(dvl,true,false);
+
+  int_4 nbinx = dvl.GetI("NBINX",-1);
+  int_4 nbiny = dvl.GetI("NBINY",-1);
+  int_8 nbinxy = nbinx*nbiny;
+  if(nbinx<=0 || nbiny<=0 || nbinxy!=nbrows)
+    throw FitsIOException("FitsHandler<Histo2DErr>::Read() number of bins is zero or bad, no reading");
+
+  r_8 xmin = dvl.GetD("XMIN",-1.);
+  r_8 xmax = dvl.GetD("XMAX",1.);
+  r_8 ymin = dvl.GetD("YMIN",-1.);
+  r_8 ymax = dvl.GetD("YMAX",1.);
+
+  //--- Creation de l'objet
+  if(dobj == NULL) dobj = new Histo2DErr;
+  dobj->CreateOrResize(xmin,xmax,nbinx,ymin,ymax,nbiny);
+
+  //--- remplissage des variables d'entete
+  dobj->mMean = dvl.GetI("NMEAN",0);
+
+  //--- remplissage de l'histo
+  FitsBlockRW<r_8>::ReadColumnData(is,1,1,1,&(dobj->data_(0,0)),nbinxy);
+  FitsBlockRW<r_8>::ReadColumnData(is,2,1,1,&(dobj->err2_(0,0)),nbinxy);
+  FitsBlockRW<r_8>::ReadColumnData(is,3,1,1,&(dobj->ndata_(0,0)),nbinxy);
+
+  return;
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshisterr.h	(revision 3445)
@@ -0,0 +1,40 @@
+#ifndef FITSHISTERRHAND_H
+#define FITSHISTERRHAND_H
+
+#include "machdefs.h"
+#include <string>
+
+#include "histerr.h"
+#include "hist2err.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for HistErr objects
+*/
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, HistoErr const & obj)
+{ FitsHandler<HistoErr> fio(const_cast<HistoErr &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, HistoErr & obj)
+  { FitsHandler<HistoErr> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for Histo2DErr objects
+*/
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, Histo2DErr const & obj)
+{ FitsHandler<Histo2DErr> fio(const_cast<Histo2DErr &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, Histo2DErr & obj)
+  { FitsHandler<Histo2DErr> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.cc	(revision 3445)
@@ -0,0 +1,546 @@
+#include "machdefs.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "histos.h"
+#include "hisprof.h"
+#include "histos2.h"
+
+#include "fitsblkrw.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+///////////////////////// Histo , HProf ////////////////////////
+////////////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM";
+  string clsnm = is.KeyValue(key);
+  if ( (clsnm == "SOPHYA::Histo")
+     || (clsnm == "SOPHYA::HProf") ) return 2;
+  return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo>::CheckHandling(AnyDataObj & o) 
+{  
+ if (typeid(o) == typeid(Histo)) return 2;
+ Histo * po = dynamic_cast< Histo * >(& o); 
+ if (po != NULL) return 2;
+ return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo>::Write(FitsInOutFile& os)
+{
+  if(dobj==NULL)   
+    throw NullPtrError("FitsHandler<Histo>::Write() NULL dobj pointer ");
+
+  //--- Le type d'objet et son pointeur
+  Histo*    h  = dynamic_cast< Histo *> (dobj);
+  HProf*    hp = dynamic_cast< HProf *> (dobj);
+
+  //--- Les noms de colonnes
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  // les valeurs du bin
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("val");
+  tunit.push_back("");
+  // Les erreurs
+  if(h->mErr2) {
+    if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+    colnames.push_back("e2");
+    tunit.push_back("");
+  }
+  // Le nombre d'entrees dans le bin
+  if(hp!=NULL) {
+    if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+    colnames.push_back("nb");
+    tunit.push_back("");
+  }
+
+  //--- On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(),extname,colnames,tform, tunit);
+
+  // Ecriture des donnees des colonnes
+  int n = h->NBins();
+  if(n>0) {
+    if(hp) hp->UpdateHisto();
+    FitsBlockRW<r_8>::WriteColumnData(os,1,1,1,h->mData,n);
+    if(h->mErr2) FitsBlockRW<r_8>::WriteColumnData(os,2,1,1,h->mErr2,n);
+    if(hp!=NULL) FitsBlockRW<r_8>::WriteColumnData(os,3,1,1,hp->mSumW,n);
+  }
+
+  // Ecriture des clefs fits
+  MuTyV mtv;
+
+  mtv = "SOPHYA::Histo";
+  if(hp) mtv = "SOPHYA::HProf";
+  os.WriteKey("SOPCLSNM",mtv," SOPHYA class name");
+
+  mtv = "Histo";
+  if(hp) mtv = "HProf";
+  os.WriteKey("CONTENT",mtv," name of SOPHYA object");
+
+  mtv = h->mBins;
+  os.WriteKey("NBIN",mtv," number of bins");
+
+  mtv = h->mMin;
+  os.WriteKey("XMIN",mtv," absc of beginning of 1srt bin");
+
+  mtv = h->mMax;
+  os.WriteKey("XMAX",mtv," absc of end of last bin");
+
+  mtv = h->binWidth;
+  os.WriteKey("WBIN",mtv," bin width");
+
+  mtv = h->mUnder;
+  os.WriteKey("UNDER",mtv," number of bins");
+
+  mtv = h->mOver;
+  os.WriteKey("OVER",mtv," underflow");
+
+  mtv = h->nHist;
+  os.WriteKey("NHIST",mtv," entries weighted somme");
+
+  double x = h->nEntries; mtv = x;
+  os.WriteKey("NENTRIES",mtv," number of entries");
+
+  int_4 haserr =(h->mErr2) ? 1: 0;
+  mtv = haserr;
+  os.WriteKey("HASERR2",mtv," square errors associated");
+
+  if(hp) {
+    int_4 ok = (hp->mOk)? 1: 0;
+    mtv = ok;
+    os.WriteKey("UPDOK",mtv," update status flag");
+
+    mtv = (int_4)hp->mOpt;
+    os.WriteKey("SIGOPT",mtv," sigma statistic flag");
+
+    mtv = hp->mYMin;
+    os.WriteKey("YMIN",mtv," sum low limit");
+
+    mtv = hp->mYMax;
+    os.WriteKey("YMAX",mtv," sum high limit");
+  }
+  
+  return;
+}
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo>::Read(FitsInOutFile& is)
+{
+ int hdutyp = is.CurrentHDUType();
+ if( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<Histo>::Read() Not a binary or ascii table HDU");
+
+  //--- Nb de lignes et de colonnes 
+  vector<string> colnames;
+  vector<int> coltypes;
+  vector<LONGLONG> repcnt, width;
+  is.GetColInfo(colnames,coltypes,repcnt,width);
+  long ncol = colnames.size();
+  if(ncol<=0)
+    throw FitsIOException("FitsHandler<Histo>::Read() bad number of table columns");
+  long nbrows = is.GetNbRows();
+  if(nbrows<=0)
+    throw FitsIOException("FitsHandler<Histo>::Read() number of rows is zero, no reading");
+
+  //--- Lecture entete FITS
+  string key = "SOPCLSNM"; string clsnm = is.KeyValue(key);
+  DVList dvl; is.GetHeaderRecords(dvl,true,false);
+
+  int_4 nbin = dvl.GetI("NBIN",-1);
+  if(nbin<=0 && nbin!=nbrows)
+    throw FitsIOException("FitsHandler<Histo>::Read() number of bins is zero or bad, no reading");
+
+  r_8 xmin = dvl.GetD("XMIN",-1.);
+  r_8 xmax = dvl.GetD("XMAX",+1.);
+
+  //--- Creation de l'objet si necessaire
+  if(dobj == NULL) {
+    if(clsnm == "SOPHYA::Histo") dobj = new Histo;
+    else if(clsnm == "SOPHYA::HProf") dobj = new HProf;
+  }
+
+  //--- Type de l'histo
+  Histo*    h  = dynamic_cast< Histo *> (dobj);
+  HProf*    hp = dynamic_cast< HProf *> (dobj);
+
+  //--- Allocation pour histo
+  if(hp&& (clsnm=="SOPHYA::HProf")) {
+    if(ncol<3)
+      throw FitsIOException("FitsHandler<Histo>::Read() wrong number of columns for HProf");
+    r_8 ymin = dvl.GetD("YMIN",1.);
+    r_8 ymax = dvl.GetD("YMAX",-1.);
+    hp->CreateOrResize(xmin,xmax,nbin,ymin,ymax);
+  } else if(h && clsnm == "SOPHYA::Histo" ) {
+    h->CreateOrResize(xmin,xmax,nbin);
+    int_4 haserr2 = dvl.GetI("HASERR2",0);
+    if(ncol>1 && haserr2>0) h->Errors();
+  } else {
+    throw FitsIOException("FitsHandler<Histo>::Read() No assocaition classe/fits_header");
+  }
+
+  //--- remplissage des variables d'entete
+  h->mUnder = dvl.GetD("UNDER",0.);
+  h->mOver = dvl.GetD("OVER",0.);
+  h->nHist = dvl.GetD("NHIST",0.);
+  double x = dvl.GetD("NENTRIES",0.); h->nEntries = uint_8(x);
+
+  if(hp) {
+    int_4 ok = dvl.GetI("UPDOK",0); hp->mOk = (ok)? true : false;
+    hp->mOpt = (uint_2)dvl.GetI("SIGOPT",0);
+    hp->mYMin = dvl.GetD("YMIN",1.);
+    hp->mYMax = dvl.GetD("YMAX",-1.);
+  }
+
+  //--- remplissage de l'histo
+  FitsBlockRW<r_8>::ReadColumnData(is,1,1,1,h->mData,nbin);
+  if(h->mErr2) FitsBlockRW<r_8>::ReadColumnData(is,2,1,1,h->mErr2,nbin);
+  if(hp) FitsBlockRW<r_8>::ReadColumnData(is,3,1,1,hp->mSumW,nbin);
+
+  return;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////// Histo2D  ////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo2D>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM"; 
+  string clsnm = is.KeyValue(key);
+  if( clsnm == "SOPHYA::Histo2D") return 2;
+  return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+int FitsHandler<Histo2D>::CheckHandling(AnyDataObj & o) 
+{  
+ if (typeid(o) == typeid(Histo2D)) return 2;
+ Histo2D * po = dynamic_cast< Histo2D * >(& o); 
+ if (po != NULL) return 2;
+ return 0;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo2D>::Write(FitsInOutFile& os)
+{
+  if(dobj==NULL)   
+    throw NullPtrError("FitsHandler<Histo2D>::Write() NULL dobj pointer ");
+
+  //--- Le type d'objet et son pointeur
+  Histo2D* h2 = dynamic_cast< Histo2D *> (dobj);
+
+  //--- Les noms de colonnes
+  int tbltyp = os.GetDef_TableType();
+  vector<string> colnames, tform, tunit;
+  // les valeurs du bin
+  if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+  colnames.push_back("val");
+  tunit.push_back("");
+  // Les erreurs
+  if(h2->mErr2) {
+    if(tbltyp==ASCII_TBL) tform.push_back("D15.8"); else tform.push_back("D");
+    colnames.push_back("e2");
+    tunit.push_back("");
+  }
+
+  //--- On cree la table  
+  string extname = os.NextExtensionName();
+  os.CreateTable(os.GetDef_TableType(),extname,colnames,tform, tunit);
+
+  // Ecriture des donnees des colonnes
+  long n = h2->mNxy;
+  if(n>0) {
+    FitsBlockRW<r_8>::WriteColumnData(os,1,1,1,h2->mData,n);
+    if(h2->mErr2) FitsBlockRW<r_8>::WriteColumnData(os,2,1,1,h2->mErr2,n);
+  }
+
+  // Ecriture des clefs fits
+  MuTyV mtv;
+
+  mtv = "SOPHYA::Histo2D";
+  os.WriteKey("SOPCLSNM",mtv," SOPHYA class name");
+
+  mtv = "Histo2D";
+  os.WriteKey("CONTENT",mtv," name of SOPHYA object");
+
+  mtv = h2->mNx;
+  os.WriteKey("NBINX",mtv," number of bins in X");
+  mtv = h2->mNy;
+  os.WriteKey("NBINY",mtv," number of bins in Y");
+  mtv = h2->mNxy;
+  os.WriteKey("NBINXY",mtv," number of elements");
+
+  mtv = h2->mXmin;
+  os.WriteKey("XMIN",mtv," absc of beginning of 1srt bin in X");
+  mtv = h2->mXmax;
+  os.WriteKey("XMAX",mtv," absc of end of last bin in X");
+  mtv = h2->mYmin;
+  os.WriteKey("YMIN",mtv," absc of beginning of 1srt bin in Y");
+  mtv = h2->mYmax;
+  os.WriteKey("YMAX",mtv," absc of end of last bin in Y");
+
+  mtv = h2->mWBinx;
+  os.WriteKey("WBINX",mtv," bin width in X");
+  mtv = h2->mWBiny;
+  os.WriteKey("WBINY",mtv," bin width in Y");
+
+  for(int i=0;i<3;i++) for(int j=0;j<3;j++) {
+    char str[16]; sprintf(str,"OUT%1d%1d",i,j);
+    mtv = h2->mOver[i][j];
+    os.WriteKey(str,mtv," under/over X/Y");
+  }
+
+  mtv = h2->nHist;
+  os.WriteKey("NHIST",mtv," entries weighted somme");
+
+  mtv = h2->nEntries;
+  os.WriteKey("NENTRIES",mtv," number of entries");
+
+  int_4 haserr =(h2->mErr2) ? 1: 0;
+  mtv = haserr;
+  os.WriteKey("HASERR2",mtv," square errors associated");
+
+
+
+  //-------------------------------------------------------------
+  //------ Gestion des Histo1D de projx/y bandx/t slicex/y ------
+  //-------------------------------------------------------------
+
+  int_4 nrel = 0;
+  if(h2->HProjX()) {nrel++; mtv=nrel; os.WriteKey("PROJX",mtv," relative HDU with HProjX");}
+  if(h2->HProjY()) {nrel++; mtv=nrel; os.WriteKey("PROJY",mtv," relative HDU with HProjY");}
+  if(h2->NSliX()>0) {
+    mtv=h2->NSliX(); os.WriteKey("NSLICEX",mtv," number of SliX");
+    nrel++;
+    mtv=nrel; os.WriteKey("SLICEX",mtv," relative HDU with first SliX");
+    nrel += h2->NSliX()-1;
+  }
+  if(h2->NSliY()>0) {
+    mtv=h2->NSliY(); os.WriteKey("NSLICEY",mtv," number of SliY");
+    nrel++;
+    mtv=nrel; os.WriteKey("SLICEY",mtv," relative HDU with first SliY");
+    nrel += h2->NSliY()-1;
+  }
+  if(h2->NBandX()>0) {
+    mtv=h2->NBandX(); os.WriteKey("NBANDEX",mtv," number of BandX");
+    nrel++;
+    mtv=nrel; os.WriteKey("BANDEX",mtv," relative HDU with first BandX");
+    nrel += h2->NBandX()-1;
+    for(int i=0;i<h2->NBandX();i++) {
+      char str[32]; r_8 vmin,vmax;
+      h2->GetBandX(i,vmin,vmax);
+      sprintf(str,"BXL%d",i);
+      mtv = vmin; os.WriteKey(str,mtv," low Y limit for BandX");
+      sprintf(str,"BXH%d",i);
+      mtv = vmax; os.WriteKey(str,mtv," high Y limit for BandX");
+    }
+  }
+  if(h2->NBandY()>0) {
+    mtv=h2->NBandY(); os.WriteKey("NBANDEY",mtv," number of BandY");
+    nrel++;
+    mtv=nrel; os.WriteKey("BANDEY",mtv," relative HDU with first BandY");
+    nrel += h2->NBandY()-1;
+    for(int i=0;i<h2->NBandY();i++) {
+      char str[32]; r_8 vmin,vmax;
+      h2->GetBandY(i,vmin,vmax);
+      sprintf(str,"BYL%d",i);
+      mtv = vmin; os.WriteKey(str,mtv," low X limit for BandY");
+      sprintf(str,"BYH%d",i);
+      mtv = vmax; os.WriteKey(str,mtv," high X limit for BandY");
+    }
+  }
+  mtv=nrel; os.WriteKey("NH1ASS",mtv," number of associated Histo1D");
+
+  if(h2->HProjX()) {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HProjX()))); fio.Write(os);}
+  if(h2->HProjY()) {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HProjY()))); fio.Write(os);}
+  if(h2->NSliX()>0) for(int i=0;i<h2->NSliX();i++)
+    {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HSliX(i)))); fio.Write(os);}
+  if(h2->NSliY()>0) for(int i=0;i<h2->NSliY();i++)
+    {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HSliY(i)))); fio.Write(os);}
+  if(h2->NBandX()>0) for(int i=0;i<h2->NBandX();i++)
+    {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HBandX(i)))); fio.Write(os);}
+  if(h2->NBandY()>0) for(int i=0;i<h2->NBandY();i++)
+    {FitsHandler<Histo> fio(const_cast<Histo &>(*(h2->HBandY(i)))); fio.Write(os);}
+
+  return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void FitsHandler<Histo2D>::Read(FitsInOutFile& is)
+{
+ int hdutyp = is.CurrentHDUType();
+ if( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
+    throw FitsIOException("FitsHandler<Histo2D>::Read() Not a binary or ascii table HDU");
+
+  //--- Nb de lignes et de colonnes 
+  vector<string> colnames; vector<int> coltypes; vector<LONGLONG> repcnt, width;
+  is.GetColInfo(colnames,coltypes,repcnt,width);
+  long ncol = colnames.size();
+  if(ncol<=0)
+    throw FitsIOException("FitsHandler<Histo2D>::Read() bad number of table columns");
+  long nbrows = is.GetNbRows();
+  if(nbrows<=0)
+    throw FitsIOException("FitsHandler<Histo2D>::Read() number of rows is zero, no reading");
+
+  //--- Lecture entete FITS
+  DVList dvl; is.GetHeaderRecords(dvl,true,false);
+
+  int_4 nbinx = dvl.GetI("NBINX",-1);
+  int_4 nbiny = dvl.GetI("NBINY",-1);
+  int_8 nbinxy = nbinx*nbiny;
+  if(nbinx<=0 || nbiny<=0 || nbinxy!=nbrows)
+    throw FitsIOException("FitsHandler<Histo2D>::Read() number of bins is zero or bad, no reading");
+
+  r_8 xmin = dvl.GetD("XMIN",-1.);
+  r_8 xmax = dvl.GetD("XMAX",1.);
+  r_8 ymin = dvl.GetD("YMIN",-1.);
+  r_8 ymax = dvl.GetD("YMAX",1.);
+
+  //--- Creation de l'objet
+  if(dobj == NULL) dobj = new Histo2D;
+  dobj->CreateOrResize(xmin,xmax,nbinx,ymin,ymax,nbiny);
+  int_4 haserr2 = dvl.GetI("HASERR2",0);
+  if(ncol>1 && haserr2>0) dobj->Errors();
+
+  //--- remplissage des variables d'entete
+  dobj->nHist = dvl.GetD("NHIST",0.);
+  dobj->nEntries = dvl.GetI("NENTRIES",0);
+
+  for(int i=0;i<3;i++) for(int j=0;j<3;j++) {
+    char str[16]; sprintf(str,"OUT%1d%1d",i,j);
+    dobj->mOver[i][j] = dvl.GetD(str,0.);
+  }
+
+  //--- remplissage de l'histo
+  FitsBlockRW<r_8>::ReadColumnData(is,1,1,1,dobj->mData,nbinxy);
+  if(dobj->mErr2) FitsBlockRW<r_8>::ReadColumnData(is,2,1,1,dobj->mErr2,nbinxy);
+
+
+
+  //-------------------------------------------------------------
+  //------ Gestion des Histo1D de projx/y bandx/t slicex/y ------
+  //-------------------------------------------------------------
+
+  int_4 nh1ass = dvl.GetI("NH1ASS",-1);
+  if(nh1ass<=0) return;
+  int hducur = is.CurrentHDU();
+
+  try {  // ProjX
+    int_4 ipr = dvl.GetI("PROJX",-1);
+    is.MoveAbsToHDU(hducur+ipr);
+    dobj->SetProjX();
+    Histo *h = dobj->HProjX();
+    FitsHandler<Histo> fio(*h); fio.Read(is);
+    if(h->NBins()!=dobj->NBinX())
+      throw FitsIOException("unmatched bin number");
+  } catch (...) {
+    dobj->DelProjX();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading PROJX"<<endl;
+  }
+
+  try {  // ProjY
+    int_4 ipr = dvl.GetI("PROJY",-1);
+    is.MoveAbsToHDU(hducur+ipr);
+    dobj->SetProjY();
+    Histo *h = dobj->HProjY();
+    FitsHandler<Histo> fio(*h); fio.Read(is);
+    if(h->NBins()!=dobj->NBinY())
+      throw FitsIOException("unmatched bin number");
+  } catch (...) {
+    dobj->DelProjY();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading PROJY"<<endl;
+  }
+
+  try {  // SliX
+    int_4 nb = dvl.GetI("NSLICEX",-1);
+    int_4 ipr = dvl.GetI("SLICEX",-1);
+    dobj->SetSliX(nb);
+    for(int i=0;i<nb;i++) {
+      is.MoveAbsToHDU(hducur+ipr+i);
+      Histo *h = dobj->HSliX(i);
+      FitsHandler<Histo> fio(*h); fio.Read(is);
+      if(h->NBins()!=dobj->NBinX())
+        throw FitsIOException("unmatched bin number");
+    }
+  } catch (...) {
+    dobj->DelSliX();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading SLICEX"<<endl;
+  }
+
+  try {  // SliY
+    int_4 nb = dvl.GetI("NSLICEY",-1);
+    int_4 ipr = dvl.GetI("SLICEY",-1);
+    dobj->SetSliY(nb);
+    for(int i=0;i<nb;i++) {
+      is.MoveAbsToHDU(hducur+ipr+i);
+      Histo *h = dobj->HSliY(i);
+      FitsHandler<Histo> fio(*h); fio.Read(is);
+      if(h->NBins()!=dobj->NBinY())
+        throw FitsIOException("unmatched bin number");
+    }
+  } catch (...) {
+    dobj->DelSliY();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading SLICEY"<<endl;
+  }
+
+  try {  // BandeX
+    int_4 nb = dvl.GetI("NBANDEX",-1);
+    int_4 ipr = dvl.GetI("BANDEX",-1);
+    for(int i=0;i<nb;i++) {
+      char str[32];
+      sprintf(str,"BXL%d",i); r_8 vmin = dvl.GetD(str,0.);
+      sprintf(str,"BXH%d",i); r_8 vmax = dvl.GetD(str,0.);
+      dobj->SetBandX(vmin,vmax);
+      is.MoveAbsToHDU(hducur+ipr+i);
+      Histo *h = dobj->HBandX(i);
+      FitsHandler<Histo> fio(*h); fio.Read(is);
+      if(h->NBins()!=dobj->NBinX())
+        throw FitsIOException("unmatched bin number");
+    }
+  } catch (...) {
+    dobj->DelBandX();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading BANDEX"<<endl;
+  }
+
+  try {  // BandeY
+    int_4 nb = dvl.GetI("NBANDEY",-1);
+    int_4 ipr = dvl.GetI("BANDEY",-1);
+    for(int i=0;i<nb;i++) {
+      char str[32];
+      sprintf(str,"BYL%d",i); r_8 vmin = dvl.GetD(str,0.);
+      sprintf(str,"BYH%d",i); r_8 vmax = dvl.GetD(str,0.);
+      dobj->SetBandY(vmin,vmax);
+      is.MoveAbsToHDU(hducur+ipr+i);
+      Histo *h = dobj->HBandY(i);
+      FitsHandler<Histo> fio(*h); fio.Read(is);
+      if(h->NBins()!=dobj->NBinY())
+        throw FitsIOException("unmatched bin number");
+    }
+  } catch (...) {
+    dobj->DelBandY();
+    cout<<"FitsHandler<Histo2D>::Read: Error reading BANDEY"<<endl;
+  }
+
+  return;
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitshistos.h	(revision 3445)
@@ -0,0 +1,40 @@
+#ifndef FITSHISTOHAND_H
+#define FITSHISTOHAND_H
+
+#include "machdefs.h"
+#include <string>
+
+#include "histos.h"
+#include "histos2.h"
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for Histo/HProf objects
+*/
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, Histo const & obj)
+{ FitsHandler<Histo> fio(const_cast<Histo &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, Histo & obj)
+  { FitsHandler<Histo> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+/*! 
+  \ingroup FitsIOServer
+  \brief FITS I/O handler for Histo2D objects
+*/
+
+inline FitsInOutFile& operator << (FitsInOutFile& os, Histo2D const & obj)
+{ FitsHandler<Histo2D> fio(const_cast<Histo2D &>(obj));  fio.Write(os);  return os; }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& is, Histo2D & obj)
+  { FitsHandler<Histo2D> fio(obj); is.SkipEmptyFirstHDU();
+  fio.Read(is); is.MoveToNextHDU(); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.cc	(revision 3445)
@@ -0,0 +1,674 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "segdatablock.h"
+#include "fitsinoutfile.h"
+#include "strutil.h"
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+string FitsTypes::ImageTypeToTypeString(int ityp)
+{
+  switch (ityp) {
+  case BYTE_IMG :
+    return "uint_1";
+    break;
+  case SHORT_IMG :
+    return "int_2";
+    break;
+  case LONG_IMG :
+    return "int_4";
+    break;
+  case FLOAT_IMG :
+    return "r_4";
+    break;
+  case DOUBLE_IMG :
+    return "r_8";
+    break;
+  default:
+    return "???" ;
+    break;
+  }
+  return "";
+}
+string FitsTypes::DataTypeToTypeString(int ityp)
+{
+  switch (ityp) {
+  case TBYTE :
+    return "uint_1";
+    break;
+  case TSHORT :
+    return "int_2";
+    break;
+  case TUSHORT :
+    return "uint_2";
+    break;
+  case TINT :
+    if (sizeof(int) == 4)  return "int_4";
+    else if (sizeof(int) == 8)  return "int_8";
+    else if (sizeof(int) == 2)  return "int_2";
+    break;
+  case TUINT :
+    if (sizeof(int) == 4)  return "uint_4";
+    else if (sizeof(int) == 8)  return "uint_8";
+    else if (sizeof(int) == 2)  return "uint_2";
+    break;
+  case TLONG :
+    if (sizeof(long) == 4)  return "int_4";
+    else if (sizeof(long) == 8)  return "int_8";
+    else if (sizeof(long) == 2)  return "int_2";
+    break;
+  case TULONG :
+    if (sizeof(long) == 4)  return "uint_4";
+    else if (sizeof(long) == 8)  return "uint_8";
+    else if (sizeof(long) == 2)  return "uint_2";
+    break;
+#ifdef TLONGLONG
+  case TLONGLONG :
+    return "int_8";
+    break;
+#endif
+  case TFLOAT :
+    return "r_4";
+    break;
+  case TDOUBLE :
+    return "r_8";
+    break;
+  case TCOMPLEX : 
+    return "complex< r_4 >";
+    break;
+  case TDBLCOMPLEX : 
+    return "complex< r_8 >";
+    break;
+  case TSTRING : 
+    return "string";
+    break;
+  default:
+    return "???" ;
+    break;
+  }
+  return "";
+}
+
+/*! 
+  \class SOPHYA::FitsInOutFile
+  \ingroup FitsIOServer
+  \brief  Wrapper class for cfitsio library functions 
+*/
+
+/*-- Methode --*/
+//! Default constructor - The file should be opened subsequently using Open
+FitsInOutFile::FitsInOutFile()
+{
+  fptr_ = NULL;
+  mode_ = Fits_RO;
+  SetDef_BinTable();
+  SetDef_StrColWidth();
+}
+
+/*-- Methode --*/
+//! Constructor with specification of file name and access mode
+FitsInOutFile::FitsInOutFile(string const & name, FitsIOMode mode)
+{
+  //  cout << " DBG - FitsInOutFile(string name= " << name << ")" << endl;
+  fptr_ = NULL;
+  ownfptr = true;
+  SetDef_BinTable();
+  SetDef_StrColWidth();
+  Open(name.c_str(), mode);
+}
+
+/*-- Methode --*/
+//! Constructor with specification of file name and access mode
+FitsInOutFile::FitsInOutFile(const char * name, FitsIOMode mode)
+{
+  //  cout << " DBG - FitsInOutFile(char* name= " << name << ")" << endl;
+  fptr_ = NULL;
+  ownfptr = true;
+  SetDef_BinTable();
+  SetDef_StrColWidth();
+  Open(name, mode);
+}
+
+/*! \brief Copy constructor 
+  \warning The fits file pointer is owned by the original FitsInOutFile object and 
+  should not be closed as long as the new object is being used.
+*/
+FitsInOutFile::FitsInOutFile(FitsInOutFile const& fios)
+{
+  fptr_ = fios.fptr_;
+  fname_ = fios.fname_;
+  mode_ = fios.mode_;
+  ownfptr = false;
+  SetDef_BinTable();
+  SetDef_StrColWidth();
+}
+
+/* -- Fonction utilitaire pour verifier fichier ouvert (pointeur non null) -- */
+static inline void CheckFitsPtr(fitsfile* fptr) {
+  if (fptr == NULL) throw  FitsIOException("FitsInOutFile/Error - NULL fitsfile pointer ");
+  return;
+}
+/* -- Fonction utilitaire pour verifier le code d'erreur fitsio -- */
+static inline bool FitsCheckStatus(int st, char * emsg = NULL) {
+  if (st) {
+    fits_report_error(stderr, st);
+    if (emsg) {
+      char buff[FLEN_ERRMSG];
+      fits_get_errstatus(st, buff);
+      string msg = emsg;
+      msg += buff;
+      throw FitsIOException(msg);
+    }
+    else return true;
+  }
+  else return false;
+}
+
+/*-- Methode --*/
+//! Destructor - Closes the fits file (if opened)
+FitsInOutFile::~FitsInOutFile()
+{
+  Close();
+}
+
+/*-- Methode --*/
+//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file) 
+void FitsInOutFile::Open(const char* name, FitsIOMode mode)
+{
+  if (fptr_ != NULL) 
+    throw  FitsIOException("FitsInOutFile::Open() /Error - file already opened ");
+  int status = 0;
+  fptr_ = NULL;
+  switch ( mode ) {
+  case Fits_RO :
+    fits_open_file(&fptr_, name, READONLY, &status);
+    break;
+  case Fits_RW :
+    fits_open_file(&fptr_, name, READWRITE, &status);
+    break;
+  case Fits_Create :
+    fits_create_file(&fptr_, name, &status);
+    break;
+  }
+  FitsCheckStatus(status, "FitsInOutFile::Open() Error: ");
+  fname_ = name;
+  mode_ = mode;
+  ownfptr = true;
+  return;
+}
+
+/*-- Methode --*/
+//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file) 
+void FitsInOutFile::Close()
+{
+  if (fptr_ == NULL) return;
+  if (ownfptr == false) {
+    fptr_ = NULL; return;
+  }
+  int status = 0;
+  if (mode_ == Fits_Create) {
+    status = 0;
+    int hdutyp;
+    fits_movabs_hdu(FitsPtr() , 1, &hdutyp, &status);
+    status = 0;
+    float sfv = Version();
+    fits_write_key(FitsPtr(), TFLOAT, "SOPHYAFV", &sfv, 
+		   "SOPHYA FitsIOServer module version", &status);
+    fits_write_date(FitsPtr(), &status);
+    status = 0;
+    fits_write_comment(FitsPtr(), "------------- SOPHYA  (http://www.sophya.org) -------------", &status);
+    fits_write_comment(FitsPtr(), " (C) LAL/IN2P3-CNRS Orsay , (C) DAPNIA/CEA Saclay (FRANCE)", &status);
+    fits_write_comment(FitsPtr(), "-----------------------------------------------------------", &status);
+  }
+  MoveAbsToHDU(1);
+  status = 0;
+  if (fptr_) fits_close_file(fptr_, &status);
+  if (status) {
+    cerr << " FitsInOutFile::Close - Error closing fits file !" << endl;
+    fits_report_error(stderr, status);
+  }
+}
+
+/*! \brief Closes the current fits file and uses \b fios file for subsequent operations.
+  \warning The fits file pointer is owned by the original FitsInOutFile object and 
+  should not be closed as long as the current object (this) is being used.
+*/
+
+void FitsInOutFile::ShareFitsPtr(FitsInOutFile const& fios)
+{
+  Close();
+  fptr_ = fios.fptr_;
+  fname_ = fios.fname_;
+  mode_ = fios.mode_;
+  ownfptr = false;
+}
+
+/*-- Methode --*/
+float FitsInOutFile::cfitsioVersion() 
+{
+  float ver;
+  fits_get_version(&ver);
+  return ver;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::NbHDUs()  const
+{
+  int status = 0;
+  int nbhdu = 0;
+  fits_get_num_hdus(FitsPtr() , &nbhdu, &status);
+  FitsCheckStatus(status, "FitsInOutFile::NbHDUs() Error: ");
+  return nbhdu;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::CurrentHDU()  const
+{
+  int status = 0;
+  int curhdu = 0;
+  fits_get_hdu_num(FitsPtr() , &curhdu);
+  return curhdu;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::CurrentHDUType()  const
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::CurrentHDUType() Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+string FitsInOutFile::CurrentHDUTypeStr()  const
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
+  if ( FitsCheckStatus(status, "FitsInOutFile::CurrentHDUTypeStr() Error: ") ) 
+    return "Unknown";
+  else { 
+    if (hdutyp == IMAGE_HDU) return "IMAGE_HDU";
+    else if (hdutyp == BINARY_TBL) return "BINARY_TBL";
+    else if (hdutyp == ASCII_TBL) return "ASCII_TBL";
+    else return "Unknown";
+  }
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveAbsToHDU(int hdunum)
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_movabs_hdu(FitsPtr() , hdunum, &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::MoveAbsToHDU Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveRelToHDU(int hdunum)
+{
+  int status = 0;
+  int hdutyp = 0;
+  fits_movrel_hdu(FitsPtr() , hdunum, &hdutyp, &status);
+  FitsCheckStatus(status, "FitsInOutFile::MoveRelToHDU Error: ");
+  return hdutyp;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::MoveToNextHDU()
+{
+  if (CurrentHDU() < NbHDUs()) 
+    return MoveRelToHDU(1);
+  else return -1;
+}
+
+/*-- Methode --*/
+/*! 
+  Skip HDU 1 if NAXIS=0 (no data), on a file opened for reading.
+  return true if moved to HDU No 2
+*/
+bool FitsInOutFile::SkipEmptyFirstHDU()
+{
+  if (fptr_ == NULL) return false;
+  if (mode_ == Fits_Create) return false;
+  if (CurrentHDU() != 1) return false;
+  int naxis = 2;
+  LONGLONG naxes[2];
+  GetImageHDUInfo(naxis, naxes);
+  if ((naxis == 0) &&  (NbHDUs() > 1)) {
+    MoveRelToHDU(1);
+    return true; 
+  }
+  return false; 
+}
+
+/*-- Methode --*/
+void FitsInOutFile::CreateImageHDU(int bitpix, int naxis, LONGLONG* naxes)
+{
+  int status = 0;
+  fits_create_imgll(fptr_, bitpix, naxis, naxes, &status);
+  FitsCheckStatus(status,"FitsInOutFile::CreateImageHDU() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+ /*!
+   See cfitsio function fits_get_img_param() for more information 
+   naxis : input=max naxes dimension / out=image dimension 
+   Rc : return the image type (bitpix) 
+ */
+int FitsInOutFile::GetImageHDUInfo(int& naxis, LONGLONG* naxes) const
+{
+  int status = 0;
+  int maxdim = naxis;
+  int bitpix = 0;
+  fits_get_img_paramll(fptr_, maxdim, &bitpix, &naxis, naxes, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetImageHDUInfo() Error: ");
+  return bitpix;
+}
+
+/*-- Methode --*/
+LONGLONG FitsInOutFile::GetNbRows()  const
+{
+  int status = 0;
+  LONGLONG nbrow = 0;
+  fits_get_num_rowsll(FitsPtr() , &nbrow, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetNbRows() Error: " );
+  return nbrow;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::GetNbCols()  const
+{
+  int status = 0;
+  int nbcol = 0;
+  fits_get_num_cols(FitsPtr() , &nbcol, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetNbCols() Error: ");
+  return nbcol;
+}
+
+/*-- Methode --*/
+/*!
+  Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
+  \param extname : extension name. NextExtensionName() will be used if extname == NULL or extname == "".
+  \param ncols : Number of columns
+  \param ttype : Column names 
+  \param tform : Column data types J / V / K / E / D ...
+  \param tunit : Column units
+*/
+void FitsInOutFile::CreateTable(int tbltyp, const char * extname, int ncols, 
+				char * ttype[], char * tform[], 
+				char * tunit[], long ininr)
+{
+  int status = 0;
+
+  char * extn;
+  if ( (extname != NULL) && (extname[0] != '\0') )  extn = const_cast<char *>(extname);
+  else extn = const_cast<char *>(next_extname_.c_str());
+
+  fits_create_tbl(FitsPtr(), tbltyp, ininr, ncols, ttype, 
+		  tform, tunit, extn, &status);
+  next_extname_ = "";
+  FitsCheckStatus(status, "FitsInOutFile::CreateTable() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+/*!
+  Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
+  number of columns specified by colnames.size()
+  \param extname : extension name
+  \param colnames : Column names 
+  \param tform : Column data types J / V / K / E / D ...
+  \param tunit : Column units
+*/
+void FitsInOutFile::CreateTable(int tbltyp, const string & extname, 
+				  const vector<string> & colnames, 
+				  const vector<string> & tform, 
+				  const vector<string> & tunit, 
+				  long ininr)
+{
+  if ( (colnames.size() != tform.size() ) || 
+       (colnames.size() != tunit.size() ) )
+    throw SzMismatchError("FitsInOutFile::CreateTable(): different sizes for colnames,tform,tunit");
+  
+  // On utilise les SegDataBlock<T> pour eviter d'avoir a gerer les new/delete
+  // en plus avec les exceptions ...
+  size_t kk;
+  int ncols = colnames.size();
+
+  SegDataBlock<const char *> colnm(colnames.size(), 1);
+  for(kk=0; kk<colnames.size(); kk++) colnm[kk] = colnames[kk].c_str();
+  SegDataBlock<const char *> tfm(tform.size(), 1);
+  for(kk=0; kk<tform.size(); kk++) tfm[kk] = tform[kk].c_str();
+  SegDataBlock<const char *> tun(tunit.size(), 1);
+  for(kk=0; kk<tunit.size(); kk++) tun[kk] = tunit[kk].c_str();
+       
+  CreateTable(tbltyp, const_cast<char *>(extname.c_str()), ncols, 
+	      const_cast<char **>(colnm.GetSegment(0)), 
+	      const_cast<char **>(tfm.GetSegment(0)), 
+	      const_cast<char **>(tun.GetSegment(0)), 
+	      ininr);
+}
+
+/*-- Methode --*/
+/*!
+  Return number of columns in table (See fits_get_colname and fits_get_coltype for more information)
+  \param colnames : Column names
+  \param coltypes : Column data types ( TSTRING / TSHORT / TFLOAT / ... )
+  \param repcnt : Repeat count (for columns with vector data)
+  \param width : The width (in bytes) of a single element in a column 
+  
+*/
+long FitsInOutFile::GetColInfo(vector<string> & colnames, 
+				 vector<int> & coltypes,
+				 vector<LONGLONG> & repcnt,
+				 vector<LONGLONG> & width)
+{
+
+  int status = 0;
+
+  colnames.clear();
+  coltypes.clear();
+  width.clear();
+  repcnt.clear();
+
+  int colnum, typecode;
+  LONGLONG repeat, colw;   // $CHECK$ LONGLONG ???
+  int ncols = 0;
+  char colname[128];  // longueur max d'un nom de colonne
+
+  while (status != COL_NOT_FOUND) {
+    fits_get_colname(FitsPtr(), CASEINSEN, "*", colname, &colnum, &status);
+    if (status == COL_NOT_FOUND)  break;
+    if ( (status != COL_NOT_UNIQUE) && (status != 0) ) {
+      char buff[32];
+      fits_get_errstatus(status, buff);
+      string msg = "FitsInOutFile::GetColInfo() Error(1): " ;
+      msg += buff;
+      throw FitsIOException(msg);
+    }
+    int sta2 = 0;
+    fits_get_coltypell(FitsPtr(), colnum, &typecode, &repeat, &colw, &sta2); // $CHECK$ LONGLONG ???fits_get_coltypell
+    FitsCheckStatus(sta2, "FitsInOutFile::GetColInfo() Error(2): ");
+
+    colnames.push_back(colname);
+    coltypes.push_back(typecode);
+    repcnt.push_back(repeat);
+    width.push_back(colw);
+    if (status == 0)  break;
+  }
+  return colnames.size();
+}
+
+/*-- Methode --*/
+void FitsInOutFile::InsertColumn(int numcol, const char* colname, const char* fmt)
+{
+  int status = 0;
+  fits_insert_col(FitsPtr(), numcol, const_cast<char *>(colname), 
+		  const_cast<char *>(fmt), &status);
+  FitsCheckStatus(status, "FitsInOutFile::AddColumn() Error: ");
+
+  return;
+}
+
+/*-- Methode --*/
+/*!
+  Return the value associated to the keyword \b key in the header as a string.
+  If the keyword is not found in the fits header, an empty string is returned 
+  and the \b nosk flag is set to true.
+*/
+string FitsInOutFile::KeyValue(string const & key, bool& nosk)
+{
+  nosk = false;
+  int status = 0;
+  char value[FLEN_VALUE], comm[FLEN_COMMENT];
+  fits_read_key(FitsPtr(), TSTRING, const_cast<char *>(key.c_str()), value, comm, &status);
+  if (status == KEY_NO_EXIST) {
+    nosk = true;
+    return "";
+  }
+  FitsCheckStatus(status, "FitsInOutFile::KeyValue() Error: ");
+  return value;
+}
+
+/*-- Methode --*/
+/*!
+  Read the current fits header information as pairs of '(keyword,value)' appended
+  to the DVList object \b dvl.
+  \param dvl : DVList object containing filled with (keyword,value) pairs.
+  \param stripkw : if true (default), remove leading and trailing spaces from keyword
+  \param keepstkey : if true , keep keys of type TYP_STRUC_KEY 
+*/
+int FitsInOutFile::GetHeaderRecords(DVList& dvl, bool stripkw, bool keepstkey)
+{
+  int status = 0;
+  int nkeys = 0;
+  fits_get_hdrspace(FitsPtr(), &nkeys, NULL, &status);
+  FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(1): ");
+ 
+  char record[FLEN_CARD], value[FLEN_VALUE], comm[FLEN_COMMENT];
+  string comment;
+  int nok = 0;
+  for(int kk=1; kk<=nkeys; kk++) {
+    status = 0;
+    fits_read_record(FitsPtr(), kk, record, &status);
+    FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(2): ");
+    int kclas = fits_get_keyclass(record);
+    if ( (!keepstkey && (kclas ==  TYP_STRUC_KEY))
+	 || (kclas == TYP_NULL_KEY) ) continue;
+    int len = 0;
+    status = 0;
+    fits_get_keyname(record, value, &len, &status);
+    if (status) continue;
+    if (stripkw) strip(value, 'B', ' ');
+    string keyname = value;
+    status = 0;
+    fits_parse_value(record, value, comm, &status);
+    if (status) continue;
+    if (kclas == TYP_COMM_KEY) {
+      if (comment.length() > 0) comment += '\n';
+      comment += value;
+      continue;
+    } 
+    char ktyp;
+    status = 0;
+    fits_get_keytype(value, &ktyp, &status);
+    if (status) continue;
+    switch (ktyp) {
+    case 'C' :
+    case 'L' :   // Il faudra traiter le cas des nb complexes
+    case 'X' :   // idem pour les valeurs logiques
+      dvl.SetS(keyname, value);
+      break;
+    case 'I' :
+      dvl.SetI(keyname, atoi(value));
+      break;
+    case 'F' :
+      dvl.SetD(keyname, atof(value));
+      break;
+    }
+    if (strlen(comm) > 0) {
+      string scom = comm;
+      dvl.SetComment(keyname, scom);
+    }
+    nok++;
+  }
+  if (comment.length() > 0)  dvl.Comment() = comment; 
+  return nok;
+}
+
+/*-- Methode --*/
+void FitsInOutFile::WriteKey(const char * kname, MuTyV const & mtv, 
+			     const char *comment)
+{
+  CheckFitsPtr(FitsPtr()); 
+  char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], sval[FLEN_VALUE];
+  LONGLONG lval;
+  double dval;
+  string s;
+  
+  keyname[0] = '\0';
+  strncpy(keyname, kname, FLEN_KEYWORD); keyname[FLEN_KEYWORD-1] = '\0';
+  comm[0] = '\0';
+  if (comm != NULL) 
+    strncpy(comm, comment, FLEN_COMMENT); comm[FLEN_COMMENT-1] = '\0';
+  int status = 0;
+  switch (mtv.Type()) {
+  case MuTyV::MTVInteger :
+    lval = mtv.GetIntPart();
+    fits_write_key(FitsPtr(), TLONGLONG, keyname, &lval, comm, &status);
+    break;
+  case MuTyV::MTVFloat : 
+    dval = mtv.GetRealPart();
+    fits_write_key(FitsPtr(), TDOUBLE, keyname, &dval, comm, &status);
+    break;
+  case MuTyV::MTVString : 
+    strncpy(sval, mtv.GetStringPointer()->c_str(), FLEN_VALUE);  
+    keyname[FLEN_VALUE-1] = '\0';
+    fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
+    break;
+  default :
+    s = (string)mtv;
+    strncpy(sval, s.c_str(), FLEN_VALUE);  
+    keyname[FLEN_VALUE-1] = '\0';
+    fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
+    break;
+  }
+  FitsCheckStatus(status, "FitsInOutFile::WriteKey() Error: ");
+  return;
+}
+
+/*-- Methode --*/
+int FitsInOutFile::WriteHeaderRecords(DVList & dvl)
+{
+
+  CheckFitsPtr(FitsPtr()); 
+  int status = 0;
+  DVList::ValList::const_iterator it;
+  for(it = dvl.Begin(); it != dvl.End(); it++)  
+    WriteKey( (*it).first, (*it).second.elval, (*it).second.elcomm);
+  // Ecriture commentaires
+  return 0;
+
+}
+
+/*-- Methode --*/
+void FitsInOutFile::Print(ostream& os, int lev) const
+{
+  string mode;
+  if (mode_ == Fits_Create)  mode = "Create";
+  else if (mode_ == Fits_RO)  mode = "ReadOnly";
+  else mode = "ReadWrite";
+  os << " FitsInOutFile(FileName= " << fname_  << " Mode=" 
+     << mode  << ") fitsioVers= " << cfitsioVersion() << endl;
+  os << " TotalNumberHDU= " << NbHDUs() << " CurrentHDU: Num= " 
+     << CurrentHDU() << " Type= " << CurrentHDUTypeStr() << endl;
+
+  return;
+}
+
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsinoutfile.h	(revision 3445)
@@ -0,0 +1,216 @@
+#ifndef FITSINOUTFILE_H
+#define FITSINOUTFILE_H
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "dvlist.h"
+#include "FitsIO/fitsio.h" 
+#include <complex> 
+
+
+
+namespace SOPHYA {
+
+  class FitsInOutFile;
+  //class FitsInStream;
+  //class FitsOutStream;
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Exception class used by  FITS file wrapper classes in FitsIOserver module
+*/
+class FitsIOException : public IOExc {
+  public:
+  explicit FitsIOException(const char * m) : IOExc(m) {}
+  explicit FitsIOException(const string& m) : IOExc(m) {}
+};
+
+
+/*! 
+  \ingroup FitsIOServer
+  \brief  for converting c/c++ types to FITS data types 
+*/
+class FitsTypes {
+public:
+ // Conversion de type en constante de type image FITS (XXX_IMG)
+ static int ImageType(uint_1 d) { return BYTE_IMG; }
+ static int ImageType(int_2  d) { return SHORT_IMG; }
+ static int ImageType(int_4  d) { return LONG_IMG; }
+ static int ImageType(r_4  d)   { return FLOAT_IMG; }
+ static int ImageType(r_8  d)   { return DOUBLE_IMG; }
+
+ // Conversion de type en constante datatype FITS 
+ static int DataType(uint_1 d) { return TBYTE; }
+ static int DataType(int_2  d) { return TSHORT; }
+ static int DataType(uint_2 d) { return TUSHORT; }
+
+ static int DataType(const int_4  d) 
+   { return (sizeof(long)==4) ? TLONG: TINT; }
+ static int DataType(const uint_4 d) 
+   { return (sizeof(long)==4) ? TULONG: TUINT; }
+
+#ifdef TLONGLONG
+ static int DataType(int_8 d) { return TLONGLONG; }
+#else 
+ static int DataType(int_8 d) 
+   { throw FitsIOException("FitsDataTypes: Unsupported data type int_8"); }
+#endif
+
+ static int DataType(r_4  d)   { return TFLOAT; }
+ static int DataType(r_8  d)   { return TDOUBLE; }
+
+ static int DataType(complex<r_4>  d)   { return TCOMPLEX; }
+ static int DataType(complex<r_8>  d)   { return TDBLCOMPLEX; }
+
+ static int DataType(char*  d)   { return TSTRING; }
+
+ // Conversion entre type FITS et chaine - exemple TFLOAT -> r_4 
+ static string ImageTypeToTypeString(int ityp);
+ static string DataTypeToTypeString(int ityp);
+};
+
+//------ Wrapper class for cfitsio library functions
+class FitsInOutFile {
+public :
+  //! File access mode (ReadOnly, ReadWrite, Create)
+ enum FitsIOMode { Fits_RO, Fits_RW, Fits_Create };
+
+                   FitsInOutFile(); 
+                   FitsInOutFile(string const & name, FitsIOMode mode);
+                   FitsInOutFile(const char* name, FitsIOMode mode);
+                   FitsInOutFile(FitsInOutFile const& fios); 
+ virtual           ~FitsInOutFile();
+
+
+ void              Open(const char* name, FitsIOMode mode);
+ void              Close();
+
+ void              ShareFitsPtr(FitsInOutFile const& fios);
+ 
+ inline fitsfile*  FitsPtr() const { return fptr_; }
+ static float      cfitsioVersion();
+ //! Return the SOPHYA FitsIOServer version 
+ static float      Version() { return 2.0; }
+
+ //! Return the file name as specified in the constructor (or Open) 
+ inline string     FileName() { return fname_; }
+
+ //---- Header manipulation methods
+ //! Return total number of HDU's in file
+ int               NbHDUs() const;
+ //! Return current HDU number - starting from 1 , not zero
+ int               CurrentHDU() const;
+ //! Return current HDU Type as IMAGE_HDU or BINARY_TBL or ASCII_TBL 
+ int               CurrentHDUType() const;
+ //! Return current HDU Type as a string IMAGE_HDU or BINARY_TBL or ASCII_TBL 
+ string            CurrentHDUTypeStr() const;
+ 
+ //! Move to HDU specified by hdnum - Returns the newly opened HDU type
+ int               MoveAbsToHDU(int hdunum);
+ //! Move to HDU specified by relhdu , relative to the current HDU - Returns the newly opened HDU type
+ int               MoveRelToHDU(int relhdu);
+ //! Move to the next HDU specified by relhdu. Returns the newly opened HDU type (<0 at EOF)
+ int               MoveToNextHDU();
+ //! Skip the first HDU if it contains no data. 
+ bool              SkipEmptyFirstHDU();
+
+ //---- IMAGE_HDU manipulation methods
+ //! Creates a new HDU of type image (see fits_create_img)
+ void              CreateImageHDU(int bitpix, int naxis, LONGLONG* naxes);
+ //! Get information about the current image HDU. - return the image type TBYTE,TINT ...
+ int               GetImageHDUInfo(int& naxis, LONGLONG* naxes) const;
+
+ //---- BINARY_TBL or ASCII_TBL 
+ //! Return number of rows in a table HDU
+ LONGLONG          GetNbRows() const;
+ //! Return number of columns in a table HDU
+ int               GetNbCols() const;
+ //! Creation of a new table - tbltyp = BINARY_TBL or ASCII_TBL
+ void              CreateTable(int tbltyp, const char * extname, int ncols, 
+			       char * colnames[], char * tform[], 
+			       char * tunit[], long ininr=0);
+ //! Creation of a new table - tbltyp = BINARY_TBL or ASCII_TBL
+ void              CreateTable(int tbltyp, const string & extname, 
+			       const vector<string> & colnames, 
+			       const vector<string> & tform, 
+			       const vector<string> & tunit, 
+			       long ininr=0);
+ //! Return number of columns, names, types and repeat count
+ long              GetColInfo(vector<string> & colnames, 
+			      vector<int> & coltypes,
+			      vector<LONGLONG> & repcnt,
+			      vector<LONGLONG> & width);
+
+ //! Defines the extension name for the next table creation 
+ inline void        SetNextExtensionName(string const & extname)
+   { next_extname_ = extname; }
+ //! Defines the extension name for the next table creation 
+ inline void        SetNextExtensionName(const char * extname)
+   { next_extname_ = extname; }
+ //! Return the default extension name 
+ inline string      NextExtensionName() const
+   { return next_extname_; }
+
+ //! Defines default table type for created tables as BINARY_TBL
+ inline void        SetDef_BinTable() { def_tbltype = BINARY_TBL; }
+ //! Defines default table type for created tables as ASCII_TBL
+ inline void        SetDef_AscTable() { def_tbltype = ASCII_TBL; }
+ //! Return default table type
+ inline int         GetDef_TableType() { return def_tbltype; }
+
+ //! Defines default column width for strings (Aw) 
+ inline void        SetDef_StrColWidth(long w=16) { def_strcolw = w; }
+ //! Return default column width for strings (Aw)
+ inline long        GetDef_StrColWidth() { return def_strcolw; } 
+
+ //! Insert (add) a new column
+ void              InsertColumn(int numcol, const char* colname, const char* fmt);
+ //! Insert (add) a new column
+ inline void       InsertColumn(int numcol, const string& colname, const char* fmt)
+   { InsertColumn(numcol, colname.c_str(), fmt); }
+
+
+ // Manipulation des informations de l'entete 
+ //! Retrieve a keyword value from the header 
+  inline string    KeyValue(string const & key)
+    { bool nosk; return KeyValue(key, nosk); }
+ //! Retrieve a keyword value from the header 
+  string           KeyValue(string const & key, bool& nosk);
+ //! Read header records and appends the information to dvl
+ int               GetHeaderRecords(DVList& dvl, 
+				    bool stripkw= true, bool keepstkey=false);
+ //! Appends a keyword to FITS header
+ void	           WriteKey(const char * kname, MuTyV const & val, 
+			    const char *comm=NULL);
+ inline void	   WriteKey(string const & kname, MuTyV const & val, string const & comm) 
+   { WriteKey(kname.c_str(), val, comm.c_str()); }
+ //! Write dvl information to fits header 
+ int               WriteHeaderRecords(DVList & dvl);
+
+ //! Prints information about the fits file on standard output stream (cout)
+ inline  void      Print(int lev=0) const  { Print(cout, lev); }  
+ //! Prints information about the fits file on stream os
+ virtual void      Print(ostream& os, int lev=0)  const;
+
+protected:
+ fitsfile *fptr_;     //  pointer to the FITS file, defined in fitsio.h 
+ string fname_;       //  File name as passed to creator
+ FitsIOMode mode_;    
+ bool ownfptr;        //  If true, owns the FitsPointer, which will be closed by the destructor
+
+ // Default extension name 
+ string next_extname_;
+ // Default table type 
+ int def_tbltype;
+ // default column width for strings 
+ long def_strcolw;
+};
+
+/*! Prints FITS file information on stream \b s ( fio.Print(s) ) */
+
+inline ostream& operator << (ostream& s, FitsInOutFile const & fio)
+  {  fio.Print(s);  return(s);  }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsioserver.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsioserver.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsioserver.h	(revision 3445)
@@ -0,0 +1,26 @@
+#ifndef FITSIOSERVER_SEEN
+#define FITSIOSERVER_SEEN
+
+// Fits wrapper and generic handlers (array/tables)
+#include "fitsinoutfile.h"
+#include "fitsarrhand.h"
+#include "fitshdtable.h"
+#include "fitshistos.h"
+#include "fitsmanager.h"
+
+// Old (Pre V2 ) wrappers and handlers
+#include "fitsfile.h"
+
+#include "fitsspherehealpix.h"
+#include "fitsntuple.h"
+// #include "fitsxntuple.h"
+#include "fitslocalmap.h"
+
+// Classes read/write utilitaires a la cmv 
+#include "fbtntintf.h"
+
+#include "fabtcolread.h"
+#include "fabtwriter.h"
+#include "fboloread.h"
+
+#endif // FITSIOSERVER_SEEN
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.cc	(revision 3445)
@@ -0,0 +1,286 @@
+#include "sopnamsp.h"
+#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>
+int FITS_LocalMap<T>::CheckHandling(AnyDataObj & o)
+{
+  if ( typeid(o) == typeid( LocalMap< T > ) ) return 2;
+  LocalMap<T> * po = dynamic_cast< LocalMap<T> * >(&o);
+  if (po == NULL) return 0;
+  else return 1;
+}
+
+template <class T>
+int FITS_LocalMap<T>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() !=  IMAGE_HDU ) return 0;
+  string key;
+  key = "Content";
+  string clsnm = is.KeyValue(key);
+  if (clsnm != "LocalMap") return 0;
+  
+  LONGLONG naxes[2];
+  int naxis=2;
+  int imgtyp = is.GetImageHDUInfo(naxis, naxes);
+  if (naxis != 2) return 0;
+
+  T x = 0;
+  if (imgtyp == FitsTypes::ImageType(x)) return 2 ;
+  else return 1;
+}
+
+template <class T>
+FitsHandlerInterface* FITS_LocalMap<T>::Clone()
+{
+  return new FITS_LocalMap<T>() ; 
+}
+
+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");
+  dvl["SOPCLSNM"]= "SOPHYA::LocalMap<T>";
+  dvl.SetComment("SOPCLSNM", "SOPHYA class name");
+  // On ecrit les dataBlocks 
+  vector<string> Noms;   
+  Noms.push_back(dvl.GetS("Content"));
+  //  string extname("SIMULATION");
+  string extname = os.NextExtensionName();
+
+  // 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)
+namespace SOPHYA {
+template class FITS_LocalMap<r_8>;
+template class FITS_LocalMap<r_4>;
+template class FITS_LocalMap<int_4>;
+}
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitslocalmap.h	(revision 3445)
@@ -0,0 +1,59 @@
+// 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_); }
+
+virtual int         CheckHandling(AnyDataObj & o) ;
+virtual int         CheckReadability(FitsInOutFile& is);
+virtual FitsHandlerInterface* Clone();
+
+protected :
+
+void ReadFromFits(FitsInFile& is);
+void WriteToFits(FitsOutFile& os) ;
+
+  LocalMap<T> * dobj_;
+  bool ownobj_;
+};
+//////////////////////////////////////////////////////////////////
+
+template <class T>
+inline FitsInOutFile& operator << (FitsInOutFile& fios, LocalMap<T> & lm)
+  { FITS_LocalMap<T> fih(&lm); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInOutFile& operator >> (FitsInOutFile& fiis, LocalMap<T> & lm)
+  { FITS_LocalMap<T> fih(&lm); fih.Read(fiis); 
+  fiis.MoveToNextHDU(); return (fiis); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.cc	(revision 3445)
@@ -0,0 +1,259 @@
+#include "machdefs.h"
+#include "sopnamsp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "fitsmanager.h"
+#include "fitshandler.h"
+
+struct hand_list_el {
+  FitsHandlerInterface * fhi;
+  int glev;
+  string desc;
+};
+
+typedef list<hand_list_el> HandlerList;
+
+static HandlerList * hlistp = NULL;
+
+static inline void ChkHLP() 
+{
+  if (hlistp == NULL) hlistp = new HandlerList;
+}
+/*!
+  Generic handlers (ImageHDU, TableHDU) will have a higher global priority level
+  than specific handlers. Use glev=0 for specific handlers and glev=1 for generic
+  handlers.  
+  \param fhi : handler object pointer (created by new) which will be kept in the 
+  handler list
+  \param glev : global priority level associated with the handler. Used when different
+  handlers return the same value for CheckHandling() or CheckReadability().
+  \param desc : classe name description associated with the handler
+*/
+int FitsManager::RegisterHandler(FitsHandlerInterface * fhi, int glev, string desc)
+{
+  ChkHLP(); 
+  if (fhi == NULL)
+    throw NullPtrError("FitsManager::RegisterHandler() fhi=NULL ");
+  HandlerList::iterator it;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    if (typeid(*((*it).fhi)) == typeid(*fhi)) 
+      throw DuplicateIdExc("FitsManager::RegisterHandler() Already registered handler");
+  }
+  hand_list_el hle;
+  hle.fhi = fhi;
+  hle.glev = glev;
+  hle.desc = desc;
+  hlistp->push_back(hle);
+  return hlistp->size();
+}
+
+int FitsManager::ListHandlers()
+{
+  ChkHLP(); 
+  int kk=0;
+  cout << "---- FitsManager::ListHandlers()  NbHandlers= " << hlistp->size()
+       << endl;
+  HandlerList::iterator it;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    kk++;
+    cout << kk << "- " << (*it).desc << " : " 
+	 << typeid(*((*it).fhi)).name() << " glev= " <<(*it).glev << endl;
+  }
+  return hlistp->size();
+}
+
+/*!
+  Return a NULL pointer if no handler is registered for object \b o .
+  The returned pointer should not be used directly and should NOT
+  be deleted. For read/write operations, the Clone() method should
+  be called on the returned object.
+*/
+FitsHandlerInterface* FitsManager::FindHandler(AnyDataObj & o)
+{
+  ChkHLP(); 
+  FitsHandlerInterface * fhi = NULL;
+  HandlerList::iterator it;
+  int hfg = 0;
+  int bhfg = 0;
+  int clev = 0;
+  int blev = 0;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    hfg = (*it).fhi->CheckHandling(o);
+    if (hfg < 1) continue;
+    if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) {
+      fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev;
+    }
+  }
+  return fhi ;
+}
+
+/*!
+  Throws an exception ( NotFoundExc ) if the write operation can not be performed. 
+*/
+void FitsManager::Write(FitsInOutFile& os, AnyDataObj & o)
+{
+  FitsHandlerInterface * fhi = FindHandler(o);
+  if (fhi == NULL) {
+    string msg = "FitsManager::Write()/FindHandler() Handler not found for ";
+    msg += typeid(o).name();
+    throw NotFoundExc(msg);
+  }
+  FitsHandlerInterface * fhi2 = fhi->Clone();
+  fhi2->SetDataObj(o);
+  fhi2->Write(os);
+  delete fhi2 ;
+  return;
+}
+
+/*!
+  Throws an exception ( NotFoundExc ) if the read operation can not be performed. 
+*/
+void FitsManager::Read(FitsInOutFile& is, AnyDataObj & o)
+{
+  FitsHandlerInterface * fhi = FindHandler(o);
+  if (fhi == NULL) {
+    string msg = "FitsManager::Read()/FindHandler() Handler not found for ";
+    msg += typeid(o).name();
+    throw NotFoundExc(msg);
+  }
+  FitsHandlerInterface * fhi2 = fhi->Clone();
+  fhi2->SetDataObj(o);
+  fhi2->Read(is);
+  delete fhi2;
+  return;
+}
+
+/*!
+  Return a NULL pointer if no handler is found capable of reading
+  the current HDU.
+  The returned pointer should not be used directly and should NOT
+  be deleted. For read/write operations, the Clone() method should
+  be called on the returned object.
+*/
+FitsHandlerInterface * FitsManager::FindReader(FitsInOutFile& is)
+{
+  ChkHLP(); 
+  FitsHandlerInterface * fhi = NULL;
+  HandlerList::iterator it;
+  int hfg = 0;
+  int bhfg = 0;
+  int blev = 0;
+  for(it = hlistp->begin(); it != hlistp->end(); it++) {
+    hfg = (*it).fhi->CheckReadability(is);
+    if (hfg < 1) continue;
+    if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) {
+      fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev;
+    }
+  }
+  return fhi;
+}
+
+/*!
+  Throws an exception ( NotFoundExc ) if the read operation can not be performed. 
+  In case of success, the calling function is responsible for deleting 
+  the returned FitsHandlerInterface object, when the correspondind data object
+  is not needed any more.
+*/
+FitsHandlerInterface * FitsManager::Read(FitsInOutFile& is)
+{
+  FitsHandlerInterface * fhi = FindReader(is);
+  if (fhi == NULL) {
+    string msg = "FitsManager::Read()/FindReader() Reader/Handler not found  ";
+    msg += is.FileName();
+    char buff[64];
+    sprintf(buff, " HDU= %d Type= %d", (int)(is.CurrentHDU()), 
+	    (int)(is.CurrentHDUType()) );
+    msg += buff;
+    throw NotFoundExc(msg);
+  }
+  FitsHandlerInterface * fhi2 = FindReader(is)->Clone();
+  fhi2->Read(is);
+  return fhi2;
+}
+
+/*!
+  \param filename : FITS file name to be scanned
+  \param os : infomation will be sent to formatted stream os
+  \param slev : scan level , bit 0 (1/3) print HDU keywords,
+  bit 2 (2,3) try to read HDU data using the appropraite handler
+  \param Rc : return number of scanned HDU's
+ */
+int FitsManager::ScanFile(string filename, ostream& os, int slev)
+{
+  FitsInOutFile is(filename, FitsInOutFile::Fits_RO);
+  os << "=== FitsManager::ScanFile( " << filename << " ) NbHDUs= " 
+     << is.NbHDUs() << endl;
+  int rc = 0;
+  for(int k=0; k<is.NbHDUs(); k++) {
+    os << " ------ HDU No " << is.CurrentHDU() << " Type= " 
+	 << is.CurrentHDUTypeStr() << endl;
+    int hdutyp = is.CurrentHDUType();
+    if (hdutyp == IMAGE_HDU) {
+      LONGLONG naxes[5] = {0,0,0,0,0};
+      int naxis=5;
+      int imgtyp = is.GetImageHDUInfo(naxis, naxes);
+      os << ">> IMAGE_HDU:  naxis= " << naxis << " : ";
+      for(int i=0; i<naxis; i++) {
+	if (i>0) os << " x " ;
+	os << naxes[i];
+      }
+      os << endl;
+    }
+    else {
+      vector<string> colnames;
+      vector<int> coltypes;
+      vector<LONGLONG> repcnt, width;
+      int ncols = is.GetColInfo(colnames, coltypes, repcnt, width);
+      if (hdutyp == BINARY_TBL) os << ">> BINARY_TBL :  NRows= " << is.GetNbRows();
+      else os << ">> ASCII_TBL :  NRows= " << is.GetNbRows();
+      os << " x NCols= " << ncols << endl;
+      for(int kk=0; kk<colnames.size(); kk++) {
+	os << "Col[" << kk+1 << "]  Name= " << colnames[kk] 
+	     << " Type= " << FitsTypes::DataTypeToTypeString(coltypes[kk])
+	     << " Repeat= " << repcnt[kk]
+	     << " W= " << width[kk] << endl;
+      }
+    }
+    // Fin the appropriate handler :
+    ChkHLP(); 
+    FitsHandlerInterface * fhi = NULL;
+    HandlerList::iterator it;
+    string hdesc;
+    int hfg = 0;
+    int bhfg = 0;
+    int blev = 0;
+    for(it = hlistp->begin(); it != hlistp->end(); it++) {
+      hfg = (*it).fhi->CheckReadability(is);
+      if (hfg < 1) continue;
+      if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) {
+	fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev; hdesc = (*it).desc; 
+      }
+    }
+    if (fhi == NULL) 
+      os << ">>> Warning : No handler found for this HDU ... " << endl;
+    else 
+      os << ">>> Reader/handler: " <<  hdesc << " : " 
+	 << typeid(*fhi).name() << " HandLevel= " << blev << ", "  << bhfg << endl;
+    if (fhi && (slev >= 2)) {
+      os << ">>> Trying to read HDU data using the handler ..." << endl;
+      FitsHandlerInterface* fhic = fhi->Clone();
+      fhic->Read(is);
+      os << " FitsHandler.Read() OK " << endl;
+    }
+    if ( (slev == 1) || (slev == 3) ) {
+      os << ">>>> HDU keywords list :  " <<  endl;
+      DVList dvl;
+      is.GetHeaderRecords(dvl);
+      os << dvl;
+    }
+    os << "               --------------------- " << endl;
+    is.MoveToNextHDU();
+    rc++;
+  }
+  os << "===================================================" << endl; 
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsmanager.h	(revision 3445)
@@ -0,0 +1,45 @@
+#ifndef FITSMANAGER_H
+#define FITSMANAGER_H
+
+#include "machdefs.h"
+#include <string>
+#include <iostream>
+#include "fitsinoutfile.h"
+
+namespace SOPHYA {
+
+class FitsHandlerInterface;
+
+/*! 
+  \ingroup FitsIOServer
+  \brief Top level FITS I/O operations and handler management.
+*/
+class FitsManager {
+ public:
+  //! Called once for each handler during init phase.
+  static int  RegisterHandler(FitsHandlerInterface * fhi, int glev=0, string desc="");
+  //! Print list of handlers on cout 
+  static int  ListHandlers();
+  //! Finds the appropriate handler and writes the object \b o to fits file \b os 
+  static void Write(FitsInOutFile& os, AnyDataObj & o);
+  //! Finds the appropriate handler and reads the object \b o from fits file \b is 
+  static void Read(FitsInOutFile& is, AnyDataObj & o);
+  //! Finds the appropriate reader for the current HDU and reads the data form \b is
+  static FitsHandlerInterface * Read(FitsInOutFile& is);
+  //! Scans the fits file and prints information about each HDU on formatted stream \b os
+  static int ScanFile(string filename, ostream& os, int slev=0);
+  //! Scans the fits file and prints information about each HDU on \b cout
+  static inline int ScanFile(string filename, int slev=0)
+    { return ScanFile(filename, cout, slev); }
+
+ protected:
+  //! Finds the appropriate handler for the object \b o in the list of registered handlers.
+  static FitsHandlerInterface* FindHandler(AnyDataObj & o);
+  //! Finds the appropriate reader for the current HDU in the list of registered handlers.
+  static FitsHandlerInterface* FindReader(FitsInOutFile& is);
+};
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsntuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsntuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsntuple.cc	(revision 3445)
@@ -0,0 +1,235 @@
+#include "sopnamsp.h"
+#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_;
+}
+
+int  FITS_NTuple::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
+  string key = "SOPCLSNM"; 
+  string clsnm = is.KeyValue(key);
+  if (clsnm == "SOPHYA::NTuple")  return 2;
+  key = "Content";
+  if (is.KeyValue(key) == "NTuple") return 2;
+  else return 1;
+}
+
+//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';
+    }
+  // Reza Dec 2006 : Colonnes du NTuple de type double par defaut 
+  for (k=0; k<nbcols;k++)
+    {
+      FitsFile::FitsDataType ss= is.ColTypeFromFits(k);
+      string type;
+      if ( (ss !=  FitsFile::FitsDataType_double) && (ss != FitsFile::FitsDataType_float) )
+	{
+	  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;
+	} 
+    }
+  bool fgdouble = true;
+  if ( is.ColTypeFromFits(0) == FitsFile::FitsDataType_float ) fgdouble = false;
+  if(dobj_ == NULL) 
+    { 
+      dobj_= new NTuple(nbcols,ColName,512,fgdouble);
+      ownobj_ = true;      
+    }
+  else 
+    {
+      dobj_->Clean();
+      (*dobj_) = NTuple(nbcols,ColName,512,fgdouble);
+    }
+  for (k=0; k<nbcols;k++) 
+    {
+      delete [] ColName[k];
+    }
+  delete [] ColName;
+
+  // Reza Dec 2006 : Colonnes du NTuple de type double par defaut 
+  double* dligne = NULL;
+  float* fligne = NULL;
+  if (fgdouble) dligne = new double[nbcols];
+  else fligne = new float[nbcols];
+
+  int firstln, lastln;
+  if (numberOfLinesToBeRead_ > 0) 
+    {
+      firstln = fistLineToBeRead_;
+      lastln = firstln + numberOfLinesToBeRead_;
+    }
+  else
+    {
+      firstln = 0;
+      lastln  = nbentries;
+    }
+  int numLigne;
+  if (fgdouble) 
+    for (numLigne=firstln; numLigne < lastln; numLigne++) {
+      is.GetBinTabLine(numLigne, dligne);
+      dobj_->Fill((r_8*)dligne);
+    }
+  else 
+    for (numLigne=firstln; numLigne < lastln; numLigne++) {
+      is.GetBinTabLine(numLigne, fligne);
+      dobj_->Fill((r_4*)fligne);
+    }
+  
+  if (dligne) delete [] dligne;
+  if (fligne) delete [] fligne;
+
+  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");
+  dvl["SOPCLSNM"]= "SOPHYA::NTuple";
+  dvl.SetComment("SOPCLSNM", "SOPHYA class name");
+  // extension name
+  // string extname("NTuple_Binary_tbl"); 
+  string extname = os.NextExtensionName();
+
+  vector<string> Noms(ncols);   
+  int k;
+  for (k=0; k< ncols; k++)
+    {
+      Noms[k]= dobj_->NomIndex(k);
+    }
+
+  // Gestion NTuple en double ou float / Reza Jan 2006
+  if (dobj_->mFgDouble) {    // NTuple avec colonnes double
+    string type(ncols, 'D');
+    vector<int> dummy;
+    // Reza 09/2006 : nentries -> 1  pour eviter les colonnes de type vecteur 
+    os.makeHeaderBntblOnFits(type,Noms, 1, ncols, &dvl, extname, dummy);
+    double* column =  new double[nentries];
+    for (k=0; k<ncols;k++)
+      {
+	int j;
+	for(j = 0; j < nentries; j++) column[j]= dobj_->GetCell(j,k);
+	os.PutColToFits(k, nentries, column);
+      }
+    delete [] column;
+  }
+  else {   // NTuple avec colonnes float
+    string type(ncols, 'E');
+    vector<int> dummy;
+    // Reza 09/2006 : nentries -> 1  pour eviter les colonnes de type vecteur 
+    os.makeHeaderBntblOnFits(type,Noms, 1, 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_Nov2007/SophyaExt/FitsIOServer/fitsntuple.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsntuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsntuple.h	(revision 3445)
@@ -0,0 +1,89 @@
+// 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; 
+  }    
+virtual   int         CheckHandling(AnyDataObj & o) 
+  {  
+    if (typeid(o) == typeid(NTuple)) return 2;
+    NTuple * po = dynamic_cast< NTuple * >(& o); 
+    if (po == NULL) return 0;
+    else return 1;
+  }
+
+virtual int         CheckReadability(FitsInOutFile& is);
+
+virtual FitsHandlerInterface* Clone() 
+    { return new FITS_NTuple() ; }
+
+/*!
+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 FitsInOutFile& operator << (FitsInOutFile& fios, NTuple & nt)
+  { FITS_NTuple fih(&nt); fih.Write(fios); return (fios); }
+
+inline FitsInOutFile& operator >> (FitsInOutFile& fiis, NTuple & nt)
+  { FITS_NTuple fih(&nt); fiis.SkipEmptyFirstHDU();
+  fih.Read(fiis); fiis.MoveToNextHDU(); return (fiis); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.cc	(revision 3445)
@@ -0,0 +1,343 @@
+#include "sopnamsp.h"
+#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>
+int FITS_SphereHEALPix<T>::CheckHandling(AnyDataObj & o)
+{
+  if ( typeid(o) == typeid( SphereHEALPix< T > ) ) return 2;
+  SphereHEALPix<T> * po = dynamic_cast< SphereHEALPix<T> * >(&o);
+  if (po == NULL) return 0;
+  else return 1;
+}
+
+template <class T>
+int FITS_SphereHEALPix<T>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() !=  BINARY_TBL ) return 0;
+  string key;
+  key = "PIXTYPE";
+  if ( is.KeyValue(key) != "HEALPIX")  return 0;
+
+  bool nosk = false;
+  key = "ORDERING";
+  is.KeyValue(key, nosk);
+  bool nosk2 = false;
+  key = "NSIDE";
+  is.KeyValue(key, nosk2);
+  if (nosk || nosk2) return 0;
+
+  vector<string> colnames; 
+  vector<int> coltypes;
+  vector<LONGLONG> repcnt, width;
+  long ncols = is.GetColInfo(colnames, coltypes, repcnt, width); 
+  if (ncols < 1) return 0;
+  T x = 0;
+  if (coltypes[0] == FitsTypes::DataType(x)) return 2 ;
+  else return 1;
+}
+
+template <class T>
+FitsHandlerInterface* FITS_SphereHEALPix<T>::Clone()
+{
+  return new FITS_SphereHEALPix<T>() ; 
+}
+
+
+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");
+  dvl["SOPCLSNM"]= "SOPHYA::SphereHEALPix<T>";
+  dvl.SetComment("SOPCLSNM", "SOPHYA class name");
+  
+  // On ecrit les dataBlocks 
+  vector<string> Noms;   
+  Noms.push_back(dvl.GetS("Content"));
+  //  string extname("SIMULATION");
+  string extname = os.NextExtensionName();
+
+  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 (is.CurrentHDUType() != BINARY_TBL )
+    throw FitsIOException("FITS_SphereHEALPix<T>::ReadFromFits Not a binary table HDU");
+
+  if(dobj_ == NULL) {
+    dobj_= new SphereHEALPix<T>;
+    ownobj_= true;      
+  }
+  int nbcols, nbentries;
+  //
+
+  nbcols = is.NbColsFromFits();
+  if (nbcols != 1) 
+    cout << "FITS_SphereHEALPix<T>::ReadFromFits()/Warning Fits::NbCols="
+	 << nbcols << " not equal 1" << endl;
+  
+  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.substr(0,4) != "RING" ) && (ordering.substr(0,6) != "NESTED" ) )  { 
+    cerr << "FITS_SphereHEALPix/Error Not supported ORDERING= " << ordering 
+	 << " != RING/NESTED " << endl; 
+    throw FitsIOException("FITS_SphereHEALPix/Error ordering != RING/NESTED ");
+  }
+
+  bool fgring = true;
+  if (ordering.substr(0,4) != "RING" )  fgring = false;
+
+  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,fgring);
+  // 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)
+namespace SOPHYA {
+template class FITS_SphereHEALPix<r_8>;
+template class FITS_SphereHEALPix<r_4>;
+template class FITS_SphereHEALPix<int_4>;
+}
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherehealpix.h	(revision 3445)
@@ -0,0 +1,64 @@
+#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);
+
+virtual int         CheckHandling(AnyDataObj & o) ;
+virtual int         CheckReadability(FitsInOutFile& is);
+virtual FitsHandlerInterface* Clone();
+
+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 FitsInOutFile& operator << (FitsInOutFile& fios, SphereHEALPix<T> & sph)
+  { FITS_SphereHEALPix<T> fih(&sph); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInOutFile& operator >> (FitsInOutFile& fiis, SphereHEALPix<T> & sph)
+  { FITS_SphereHEALPix<T> fih(&sph); fiis.SkipEmptyFirstHDU();
+  fih.Read(fiis); fiis.MoveToNextHDU(); return (fiis); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.cc	(revision 3445)
@@ -0,0 +1,332 @@
+#include "sopnamsp.h"
+#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>
+int FITS_SphereThetaPhi<T>::CheckHandling(AnyDataObj & o)
+{
+  if ( typeid(o) == typeid( SphereThetaPhi< T > ) ) return 2;
+  SphereThetaPhi<T> * po = dynamic_cast< SphereThetaPhi<T> * >(&o);
+  if (po == NULL) return 0;
+  else return 1;
+}
+
+template <class T>
+int FITS_SphereThetaPhi<T>::CheckReadability(FitsInOutFile& is)
+{
+  if (is.CurrentHDUType() !=  BINARY_TBL ) return 0;
+  string key;
+  key = "PIXTYPE";
+  if ( is.KeyValue(key) != "TETAFI")  return 0;
+  key = "Content";
+  if ( is.KeyValue(key) != "SphereThetaPhi")  return 0;
+  
+  vector<string> colnames; 
+  vector<int> coltypes;
+  vector<LONGLONG> repcnt, width;
+  long ncols = is.GetColInfo(colnames, coltypes, repcnt, width); 
+  if (ncols < 1) return 0;
+  T x = 0;
+  if (coltypes[0] == FitsTypes::DataType(x)) return 2 ;
+  else return 1;
+}
+
+template <class T>
+FitsHandlerInterface* FITS_SphereThetaPhi<T>::Clone()
+{
+  return new FITS_SphereThetaPhi<T>() ; 
+}
+
+
+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");
+  dvl["SOPCLSNM"]= "SOPHYA::SphereThetaPhi<T>";
+  dvl.SetComment("SOPCLSNM", "SOPHYA class name");
+  
+  // 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 extname = os.NextExtensionName();
+
+  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)
+namespace SOPHYA {
+template class FITS_SphereThetaPhi<r_8>;
+template class FITS_SphereThetaPhi<r_4>;
+template class FITS_SphereThetaPhi<int_4>;
+}
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsspherethetaphi.h	(revision 3445)
@@ -0,0 +1,68 @@
+#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);
+
+virtual int         CheckHandling(AnyDataObj & o) ;
+virtual int         CheckReadability(FitsInOutFile& is);
+virtual FitsHandlerInterface* Clone();
+
+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 FitsInOutFile& operator << (FitsInOutFile& fios, SphereThetaPhi<T> & sph)
+  { FITS_SphereThetaPhi<T> fih(&sph); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInOutFile& operator >> (FitsInOutFile& fiis, SphereThetaPhi<T> & sph)
+  { FITS_SphereThetaPhi<T> fih(&sph); fiis.SkipEmptyFirstHDU();
+  fih.Read(fiis); fiis.MoveToNextHDU(); return (fiis); }
+
+
+
+} // Fin du namespace
+
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsswapper.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsswapper.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsswapper.h	(revision 3445)
@@ -0,0 +1,102 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees swapable
+//          C. Magneville R. Ansari  Mai 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef FITSSWAPPER_H
+#define FITSSWAPPER_H
+
+
+#include "machdefs.h"
+#include "swsegdb.h"
+#include "fitsinoutfile.h"
+#include "fitsblkrw.h"
+
+#include "basedtable.h"
+
+/*!
+  \class SOPHYA::FITSDataSwapper
+  \ingroup FitsIOServer
+  Implementation of SOPHYA::DataSwapperInterface interface on FITS files
+  (FitsInOutFile) to be used with SOPHYA::SwSegDataBlock classes.
+*/
+
+namespace SOPHYA {
+
+template <class T> 
+class FITSDataSwapper : public DataSwapperInterface<T> {
+public:
+  FITSDataSwapper() 
+    : fcol(0) , rowos(1) , dtp(NULL)
+  {
+  }
+  FITSDataSwapper(FitsInOutFile & ios, int col, BaseDataTable* dt=NULL) 
+    : fios(ios) , fcol(col), rowos(1) , dtp(dt)
+  {
+  }
+
+  inline FitsInOutFile & InOutStream() { return fios; }
+
+  void SetInOutStream(FitsInOutFile & ios, int col) 
+  {
+    fios = ios;
+    fcol = col;
+    rowos = 1;
+    /*  On ne fait pas de check sur type HDU - Reza , 30/12/2005
+    if ( fios != NULL) {
+      fhdu = fios->CurrentHDU();
+      if (fios->CurrentHDUType() != BINARY_TBL)
+	throw FitsIOException("FITSDataSwapper<T>::SetInOutStream() CurrHDU not a BINARY_TBL");
+    }    */
+  }
+
+  // Operateur = , on recopie les pointeurs des streams 
+  FITSDataSwapper<T>& operator = (FITSDataSwapper<T> const & a)
+  {
+    fios = a.fios;
+    fcol = a.fcol;
+    rowos = a.rowos;
+    dtp = a.dtp;
+  }
+
+  virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false)
+  {
+    /* fios->MoveAbsToHDU(fhdu);  On suppose qu'on est sur le bon HDU - Reza 30/12/2005 */
+    LONGLONG row = rowos;
+    if (osw)  row = oswp;
+    if (dtp != NULL)
+       if ((row+sz-1) > dtp->NRows() )  sz = dtp->NRows()-row+1;
+    FitsBlockRW<T>::WriteColumnData(fios, fcol, row, 1, d, sz);
+    if (!osw) rowos += sz;
+    return row;
+  }
+
+  virtual void  ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz)
+  {
+    int_8 nrows = fios.GetNbRows();
+    size_t szi = sz;
+    if ((swp+sz-1) > nrows) sz = nrows-swp+1;  
+    FitsBlockRW<T>::ReadColumnData(fios, fcol, swp, 1, d, sz);
+    if (sz < szi) {
+      T zz = d[sz-1];
+      for(size_t k=sz; k<szi; k++)  d[k] = zz;
+    }
+  }
+
+  virtual DataSwapperInterface<T>* Clone()
+  {
+    FITSDataSwapper<T> * rsw = new FITSDataSwapper<T>(fios, fcol, dtp) ;
+    rsw->rowos = rowos;
+    rsw->dtp = dtp;    
+    return rsw;
+  }
+
+protected:
+  FitsInOutFile fios;
+  int fcol; 
+  LONGLONG rowos;
+  BaseDataTable* dtp;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.cc	(revision 3445)
@@ -0,0 +1,174 @@
+#include "sopnamsp.h"
+#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)
+namespace SOPHYA {
+template class FITS_TArray<r_8>;
+template class FITS_TArray<r_4>;
+template class FITS_TArray<int_4>;
+}
+#endif
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitstarray.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.cc	(revision 3445)
@@ -0,0 +1,399 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/fitsxntuple.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/FitsIOServer/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/objlist.list	(revision 3445)
@@ -0,0 +1,22 @@
+datacirclefits.o
+fabtcolread.o
+fabtwriter.o
+fboloread.o
+fbtntintf.o
+fiosinit.o
+fitsautoreader.o
+fitsbntbllineRW.o
+fitsfile.o
+fitsgenedata.o
+fitshdtable.o
+fitshisterr.o
+fitshistos.o
+fitsinoutfile.o
+fitslocalmap.o
+fitsmanager.o
+fitsntuple.o
+fitsspherehealpix.o
+fitsspherethetaphi.o
+fitstarray.o
+fitsxntuple.o
+swfitsdtable.o
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libextsophya.so
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/smakefile	(revision 3445)
@@ -0,0 +1,697 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libFitsIOServer.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datacirclefits.o $(SOPHYAOBJP)fabtcolread.o $(SOPHYAOBJP)fabtwriter.o $(SOPHYAOBJP)fboloread.o $(SOPHYAOBJP)fbtntintf.o $(SOPHYAOBJP)fiosinit.o $(SOPHYAOBJP)fitsautoreader.o $(SOPHYAOBJP)fitsbntbllineRW.o $(SOPHYAOBJP)fitsfile.o $(SOPHYAOBJP)fitsgenedata.o $(SOPHYAOBJP)fitshdtable.o $(SOPHYAOBJP)fitshisterr.o $(SOPHYAOBJP)fitshistos.o $(SOPHYAOBJP)fitsinoutfile.o $(SOPHYAOBJP)fitslocalmap.o $(SOPHYAOBJP)fitsmanager.o $(SOPHYAOBJP)fitsntuple.o $(SOPHYAOBJP)fitsspherehealpix.o $(SOPHYAOBJP)fitsspherethetaphi.o $(SOPHYAOBJP)fitstarray.o $(SOPHYAOBJP)fitsxntuple.o $(SOPHYAOBJP)swfitsdtable.o
+	rm -f $(SOPHYALIBP)libFitsIOServer.a
+ 
+$(SOPHYALIBP)libFitsIOServer.a : $(SOPHYAOBJP)datacirclefits.o $(SOPHYAOBJP)fabtcolread.o $(SOPHYAOBJP)fabtwriter.o $(SOPHYAOBJP)fboloread.o $(SOPHYAOBJP)fbtntintf.o $(SOPHYAOBJP)fiosinit.o $(SOPHYAOBJP)fitsautoreader.o $(SOPHYAOBJP)fitsbntbllineRW.o $(SOPHYAOBJP)fitsfile.o $(SOPHYAOBJP)fitsgenedata.o $(SOPHYAOBJP)fitshdtable.o $(SOPHYAOBJP)fitshisterr.o $(SOPHYAOBJP)fitshistos.o $(SOPHYAOBJP)fitsinoutfile.o $(SOPHYAOBJP)fitslocalmap.o $(SOPHYAOBJP)fitsmanager.o $(SOPHYAOBJP)fitsntuple.o $(SOPHYAOBJP)fitsspherehealpix.o $(SOPHYAOBJP)fitsspherethetaphi.o $(SOPHYAOBJP)fitstarray.o $(SOPHYAOBJP)fitsxntuple.o $(SOPHYAOBJP)swfitsdtable.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)datacirclefits.o: datacirclefits.cc \
+  $(SOPHYAINCP)sopnamsp.h datacirclefits.h \
+  $(SOPHYAINCP)datacirclebase.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacirclefits.cc
+ 
+$(SOPHYAOBJP)fabtcolread.o: fabtcolread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fabtcolread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fabtcolread.cc
+ 
+$(SOPHYAOBJP)fabtwriter.o: fabtwriter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fabtwriter.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fabtwriter.cc
+ 
+$(SOPHYAOBJP)fboloread.o: fboloread.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fboloread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fabtcolread.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fboloread.cc
+ 
+$(SOPHYAOBJP)fbtntintf.o: fbtntintf.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fbtntintf.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fbtntintf.cc
+ 
+$(SOPHYAOBJP)fiosinit.o: fiosinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h fitsmanager.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshdtable.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitshandler.h \
+  fitsarrhand.h $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tvector.h fitsblkrw.h fitsntuple.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  fitsspherethetaphi.h \
+  $(SOPHYAINCP)spherethetaphi.h fitslocalmap.h \
+  $(SOPHYAINCP)localmap.h fitshistos.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h fitsgenedata.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiosinit.cc
+ 
+$(SOPHYAOBJP)fitsautoreader.o: fitsautoreader.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsautoreader.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  fitstarray.h $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h fitsntuple.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ppersist.h fitsxntuple.h \
+  $(SOPHYAINCP)xntuple.h fitslocalmap.h \
+  $(SOPHYAINCP)localmap.h fbtntintf.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsautoreader.cc
+ 
+$(SOPHYAOBJP)fitsbntbllineRW.o: fitsbntbllineRW.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsbntbllineRW.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)utils.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbntbllineRW.cc
+ 
+$(SOPHYAOBJP)fitsfile.o: fitsfile.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsfile.cc
+ 
+$(SOPHYAOBJP)fitsgenedata.o: fitsgenedata.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsgenedata.cc
+ 
+$(SOPHYAOBJP)fitshdtable.o: fitshdtable.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  swfitsdtable.h $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swsegdb.h fitsswapper.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshdtable.cc
+ 
+$(SOPHYAOBJP)fitshisterr.o: fitshisterr.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hist2err.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshisterr.cc
+ 
+$(SOPHYAOBJP)fitshistos.o: fitshistos.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h fitsblkrw.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitshistos.cc
+ 
+$(SOPHYAOBJP)fitsinoutfile.o: fitsinoutfile.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)pexceptions.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsinoutfile.cc
+ 
+$(SOPHYAOBJP)fitslocalmap.o: fitslocalmap.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fitslocalmap.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitslocalmap.cc
+ 
+$(SOPHYAOBJP)fitsmanager.o: fitsmanager.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sopnamsp.h fitsmanager.h \
+  fitsinoutfile.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsmanager.cc
+ 
+$(SOPHYAOBJP)fitsntuple.o: fitsntuple.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsntuple.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsntuple.cc
+ 
+$(SOPHYAOBJP)fitsspherehealpix.o: fitsspherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsspherehealpix.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)tarray.h fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsspherehealpix.cc
+ 
+$(SOPHYAOBJP)fitsspherethetaphi.o: fitsspherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsspherethetaphi.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)anydataobj.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h \
+  $(SOPHYAINCP)tarray.h fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsspherethetaphi.cc
+ 
+$(SOPHYAOBJP)fitstarray.o: fitstarray.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitstarray.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitstarray.cc
+ 
+$(SOPHYAOBJP)fitsxntuple.o: fitsxntuple.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h fitsxntuple.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)dvlist.h fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsxntuple.cc
+ 
+$(SOPHYAOBJP)swfitsdtable.o: swfitsdtable.cc swfitsdtable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swsegdb.h fitsswapper.h \
+  $(SOPHYAINCP)machdefs.h fitsinoutfile.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h fitsblkrw.h \
+  fitshandler.h fitshdtable.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  swfitsdtable.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.cc	(revision 3445)
@@ -0,0 +1,490 @@
+#include "swfitsdtable.h"
+#include "fitshdtable.h"
+#include "pexceptions.h"
+#include "thsafeop.h"
+
+namespace SOPHYA { 
+
+/*!
+   \class SwFitsDataTable
+   \ingroup FitsIOServer
+   This class can be used to organize data in table (row-column) form.
+   Each column holds homogeneous data (same data type), while different
+   columns can be used for different data types 
+   (integer, float, string ...).
+   A Fits file binary table is used as swap space.
+
+   \warning 
+   - When creating a table, the output fits file (FitsInOutFile) must not be closed
+   (destroyed) before the SwFitsDataTable object is destroyed. The destructor writes
+   out any pending buffer to the fits file.
+   - It is not possible to make a complete (deep) copy of a SwFitsDataTable
+   Copy constructor and equal operator shares the data.
+   - The min/max values for column data are not updated when reading from a fits file.
+   In this case, the Show() method (or ostream& << operator) will compute min/max 
+   values. This operation will take some time for large tables.
+   - The SwFitsDataTable operation (AddRow()/GetRow() ) is NOT thread safe
+
+   \sa SOPHYA::MuTyV
+   \sa SOPHYA::DataTableRow
+   \sa SOPHYA::DataTable
+   \sa SOPHYA::SwSegDataBlock  SOPHYA::FitsDataSwapper
+
+   \code
+   #include "swfitsdtable.h"
+   // ...
+   {
+   // ---- Creation of the table
+   // Create the swap stream 
+   FitsInOutFile so("myswtable.fits", FitsInOutFile::Fits_Create);
+   SwFitsDataTable dt(so, 16, true);
+   // define table columns
+   dt.AddFloatColumn("X0_f");
+   dt.AddFloatColumn("X1_f");
+   dt.AddDoubleColumn("X0X0pX1X1_d");
+   // Fill the table
+   r_8 x[5];
+   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];
+     dt.AddLine(x);
+   }
+   // Printing table info
+   cout << dt ;
+   // The destructor will Swap out  data still in memory 
+   }
+   {
+   // ---- Accessing information from a previously created table
+   FitsInOutFile si("myswtable.fits", FitsInOutFile::Fits_ReadOnly);
+   // Position the fits file on the first extension (BinTable)
+   si.MoveAbsToHDU(2);  
+   SwFitsDataTable dt(si, 512, false);
+   // Printing table info 
+   cout << dt ;   
+   }
+   \endcode
+*/
+//! Default constructor with optional specification of block (or segment) size 
+SwFitsDataTable::SwFitsDataTable(sa_size_t segsz)
+  : BaseDataTable(segsz) , mFgCreate(false) , mFgDefDone(false)
+{
+}
+/*!
+  \brief Construcor with specification of the \b FitsInOutFile swap stream.
+  if fgcreate == true, creates an empty table (the fits file should then be 
+  opened for writing). 
+  if fgcreate == false , the table is initialized (read in) from the current HDU.
+*/
+SwFitsDataTable::SwFitsDataTable(FitsInOutFile & os, sa_size_t segsz, bool fgcreate)
+  : BaseDataTable(segsz) ,
+    mSwF(os) , mFgCreate(fgcreate) , mFgDefDone(false)
+{
+  if (!fgcreate) {   // Lecture de la table 
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Read(os);
+    mFgDefDone = true;
+  }
+}
+
+/*!
+  \brief Construcor with specification of the FITS file name, as a Read-only file.
+  The FITS file is opened and the table is initialized (read in) from HDU \b hdunum
+*/
+  SwFitsDataTable::SwFitsDataTable(string fitsname, int hdunum, sa_size_t segsz)
+  : BaseDataTable(segsz) ,
+    mSwF(fitsname, FitsInOutFile::Fits_RO) , mFgCreate(false) , mFgDefDone(true)
+{
+  // Lecture de la table 
+  FitsHandler<BaseDataTable> fio(*this);
+  mSwF.MoveAbsToHDU(hdunum);
+  fio.Read(mSwF);
+}
+
+//! copy constructor - shares the data (and copies the thread safety state)
+SwFitsDataTable::SwFitsDataTable(SwFitsDataTable const & a)
+  : BaseDataTable(a.SegmentSize()),
+    mSwF(a.mSwF) , mFgCreate(a.mFgCreate) , mFgDefDone(a.mFgDefDone)
+{
+  // Attention(Reza Nov07): le mFgDefDone doit etre en principe partage entre les objets 
+  Share(a);
+}
+//! Destructor - Deletes / closes the input PPF swap stream  
+SwFitsDataTable::~SwFitsDataTable()
+{
+  if (mFgCreate) { 
+    SwapOutAll();
+    // Ecriture de SegmentSize et autre elements de DVList  
+    mSwF.WriteHeaderRecords(Info());
+    MuTyV mtv = SegmentSize();
+    mSwF.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
+    mtv = "SOPHYA::SwFitsDataTable";
+    mSwF.WriteKey("SOPCLSNM",mtv," Object class name "); 
+  }
+}
+
+void SwFitsDataTable::Share(SwFitsDataTable const & a)
+{
+  // On recopie la taille de segment
+  mSegSz = a.SegmentSize();
+  if (a.NVar() == 0)  return;  // Table sans colonne 
+
+  // On copie la structure de table 
+  CopyStructure(a);
+  if (a.IsThreadSafe())  SetThreadSafe(true);
+  else SetThreadSafe(false);
+
+  //
+  // Update nombre d'entree, ...
+  mNEnt = a.mNEnt;
+  mNSeg = a.mNSeg;
+  if (a.mInfo)  mInfo = new DVList(*(a.mInfo));
+
+  // mis a jour des tableax min-max 
+  mMin = a.mMin;
+  mMax = a.mMax;
+  mMinMaxNEnt = a.mMinMaxNEnt;
+
+  // Et on partage les donnees des colonnes 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    sa_size_t ska = a.mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk] = a.mICols[ska];
+    break;
+    case LongField :
+      mLCols[sk] = a.mLCols[ska]; 
+      break;
+    case FloatField :
+      mFCols[sk] = a.mFCols[ska]; 
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk] = a.mDCols[ska]; 
+      break;
+    case ComplexField :
+      mYCols[sk] = a.mYCols[ska]; 
+      break;
+    case DoubleComplexField :
+      mZCols[sk] = a.mZCols[ska]; 
+      break;
+    case StringField :
+      mSCols[sk] = a.mSCols[ska]; 
+      break;
+    default:
+      throw ForbiddenError("SwFitsDataTable::Share() : unknown column type ");
+    break;
+    }
+  }  
+}
+void SwFitsDataTable::SwapOutAll() const
+{
+  if (NRows() < 1) return;
+  // Et on vide les buffers de swap 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk].SwapOutBuffer();
+    break;
+    case LongField :
+      mLCols[sk].SwapOutBuffer();
+      break;
+    case FloatField :
+      mFCols[sk].SwapOutBuffer();
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk].SwapOutBuffer();
+      break;
+    case ComplexField :
+      mYCols[sk].SwapOutBuffer();
+      break;
+    case DoubleComplexField :
+      mZCols[sk].SwapOutBuffer();
+      break;
+    case StringField :
+      mSCols[sk].SwapOutBuffer();
+      break;
+    default:
+      throw ForbiddenError("SwFitsDataTable::SwapOutAll() : unknown column type ");
+    break;
+    }
+  }  
+}
+
+void SwFitsDataTable::Clear()
+{
+  if ( (NVar() == 0) && (NEntry() == 0)) return;
+  mNEnt = 0;
+  mNSeg = 0;
+  if (mVarD) delete[] mVarD;
+  mVarD = NULL;
+  if (mVarMTV) delete[] mVarMTV;
+  mVarMTV = NULL;
+  mNames.clear();
+  if (mInfo) delete mInfo;
+  mInfo = NULL;
+  if (mThS) delete mThS;
+  mThS = NULL;
+  mFgCreate = mFgDefDone = false;
+
+  mMin.clear();
+  mMax.clear();
+  mMinMaxNEnt.clear();
+  mIColsP.clear();
+  mLColsP.clear();
+  mFColsP.clear();
+  mDColsP.clear();
+  mYColsP.clear();
+  mZColsP.clear();
+  mSColsP.clear();
+
+  mIColIdx.clear();
+  mLColIdx.clear();
+  mFColIdx.clear();
+  mDColIdx.clear();
+  mYColIdx.clear();
+  mZColIdx.clear();
+  mSColIdx.clear();
+
+  mICols.clear();
+  mLCols.clear();
+  mFCols.clear();
+  mDCols.clear();
+  mYCols.clear();
+  mZCols.clear();
+  mSCols.clear();
+
+}
+
+
+/*! 
+  Implements the action defined in the BaseDataTable interface.
+  In the current implementation, throws an exception (ParmError) 
+  if the table contains some data already.
+*/
+sa_size_t SwFitsDataTable::AddColumn(FieldType ft, string const & cnom)
+{
+  return AddColRd(ft, cnom, -1, NULL);
+}
+/*! 
+  Adds a column to the table. If swpos != NULL, the swapper is initialized 
+  for reading data from the fits file. This method can be called
+  by FitsHandler<BaseDataTable> with non zero swpos. 
+*/
+sa_size_t SwFitsDataTable::AddColRd(FieldType ft, string const & cnom, 
+				    int colidx, vector<int_8> const * swpos)
+{
+  if (NEntry() > 0) 
+    throw ParmError("SwFitsDataTable::AddColumn() Table contains already data ");
+  CheckColName(cnom);
+  sa_size_t ser; 
+  sa_size_t idx = NVar(); 
+  if (colidx < 1) colidx = idx+1; 
+
+  switch (ft) {
+  case IntegerField :
+  {
+    ser = mICols.size();
+    FITSDataSwapper<int_4> ISwapper(mSwF, colidx, this);
+    if (swpos)
+      mICols.push_back(SwSegDataBlock<int_4>(ISwapper, *swpos, mSegSz));
+    else 
+      mICols.push_back(SwSegDataBlock<int_4>(ISwapper, mSegSz));
+    mIColIdx.push_back(idx);
+    mIColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mICols.size(); kk++)
+      mIColsP[kk] = &(mICols[kk]);
+    break;
+  }
+  case LongField :
+  {
+    ser = mLCols.size();
+    FITSDataSwapper<int_8> LSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mLCols.push_back(SwSegDataBlock<int_8>(LSwapper, *swpos, mSegSz));
+    else 
+      mLCols.push_back(SwSegDataBlock<int_8>(LSwapper, mSegSz));
+    mLColIdx.push_back(idx);
+    mLColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mLCols.size(); kk++)
+      mLColsP[kk] = &(mLCols[kk]);
+    break;
+  }
+  case FloatField :
+  {
+    ser = mFCols.size();
+    FITSDataSwapper<r_4> FSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mFCols.push_back(SwSegDataBlock<r_4>(FSwapper, *swpos, mSegSz));
+    else
+      mFCols.push_back(SwSegDataBlock<r_4>(FSwapper, mSegSz));
+    mFColIdx.push_back(idx);
+    mFColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mFCols.size(); kk++)
+      mFColsP[kk] = &(mFCols[kk]);
+    break;
+  }
+  case DoubleField :
+  case DateTimeField :
+  {
+    ser = mDCols.size();
+    FITSDataSwapper<r_8> DSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mDCols.push_back(SwSegDataBlock<r_8>(DSwapper, *swpos, mSegSz));
+    else 
+      mDCols.push_back(SwSegDataBlock<r_8>(DSwapper, mSegSz));      
+    mDColIdx.push_back(idx);
+    mDColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mDCols.size(); kk++)
+      mDColsP[kk] = &(mDCols[kk]);
+    break;
+  }
+  case ComplexField :
+  {
+    ser = mYCols.size();
+    FITSDataSwapper< complex<r_4> > YSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mYCols.push_back(SwSegDataBlock< complex<r_4> >(YSwapper, *swpos, mSegSz));
+    else
+      mYCols.push_back(SwSegDataBlock< complex<r_4> >(YSwapper, mSegSz));
+    mYColIdx.push_back(idx);
+    mYColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mYCols.size(); kk++)
+      mYColsP[kk] = &(mYCols[kk]);
+    break;
+  }
+  case DoubleComplexField :
+  {
+    ser = mZCols.size();
+    FITSDataSwapper< complex<r_8> > ZSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mZCols.push_back(SwSegDataBlock< complex<r_8> >(ZSwapper, *swpos, mSegSz));
+    else
+      mZCols.push_back(SwSegDataBlock< complex<r_8> >(ZSwapper, mSegSz));
+    mZColIdx.push_back(idx);
+    mZColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mZCols.size(); kk++)
+      mZColsP[kk] = &(mZCols[kk]);
+    break;
+  }
+  case StringField :
+  {
+    ser = mSCols.size();
+    FITSDataSwapper< string > SSwapper(mSwF, colidx, this);
+    if (swpos)    
+      mSCols.push_back(SwSegDataBlock< string >(SSwapper, *swpos, mSegSz));
+    else 
+      mSCols.push_back(SwSegDataBlock< string >(SSwapper, mSegSz));
+    mSColIdx.push_back(idx);
+    mSColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mSCols.size(); kk++)
+      mSColsP[kk] = &(mSCols[kk]);
+    break;
+  }
+  default:
+    throw ParmError("SwFitsDataTable::AddColumn() unknown field type ");
+    break;
+  }
+  colst col;
+  col.nom = cnom;
+  col.type = ft;
+  col.ser = ser;
+  mNames.push_back(col);
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  mMin.push_back(9.E39);
+  mMax.push_back(-9.E39);
+  mMinMaxNEnt.push_back(0);
+
+  return NVar();
+}
+
+
+/*! 
+  \brief Writes table definition (column name/type) to the FITS file
+
+  It is not possible to add columns once the table definition is 
+  written to the fits file. Returns number of table columns.
+  Although AddRow() checks and perform this operation automatically,
+  it is advised to do it explicitely, before using an SwFitsDataTable
+  for filling in multi-thread programs.
+*/
+sa_size_t SwFitsDataTable::WriteTableDefinitionToFits()
+{
+  if (!mFgDefDone && (NRows() == 0)) {  
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Write(mSwF);
+    mFgDefDone = true;
+  }
+  return NVar();
+}
+
+//! Adds a line (or row to the table) with r_8* input data.
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow().
+  The table is also created on the FITS file at the first call to AddRow(), 
+  by calling WriteTableDefinitionToFits() , if not already done.
+*/
+sa_size_t SwFitsDataTable::AddRow(const r_8* data)
+{
+  if (mThS) mThS->lock();   // tread-safety
+  if (!mFgDefDone && (NRows() == 0)) { // On cree la definition de la table FITS au premier appel  
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Write(mSwF);
+    mFgDefDone = true;
+  }
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  for(sa_size_t k=0; k<NVar(); k++) {
+    double x = data[k];
+    if (x < mMin[k])  mMin[k] = x;
+    if (x > mMax[k])  mMax[k] = x;
+    mMinMaxNEnt[k]++;
+  }
+  if (mThS) mThS->unlock(); // tread-safety
+  return BaseDataTable::AddRow(data);
+}
+
+
+//! Adds a row (or line to the table) with input data as an array of MuTyV
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow().
+  The table is also created on the FITS file at the first call to AddRow() 
+*/
+sa_size_t SwFitsDataTable::AddRow(const MuTyV * data)
+{
+  if (mThS) mThS->lock();   // tread-safety
+  if (!mFgDefDone && (NRows() == 0)) { // On cree la definition de la table FITS au premier appel  
+    FitsHandler<BaseDataTable> fio(*this);
+    fio.Write(mSwF);
+    mFgDefDone = true;
+  }
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  for(sa_size_t k=0; k<NVar(); k++) {
+    double x = (double)data[k];
+    if (x < mMin[k])  mMin[k] = x;
+    if (x > mMax[k])  mMax[k] = x;
+    mMinMaxNEnt[k]++;
+  }
+  if (mThS) mThS->unlock();   // tread-safety
+  return BaseDataTable::AddRow(data);
+}
+
+//! Adds a row (or line) to the table with input data as DataTableRow object
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow().
+  The table is also created on the FITS file at the first call to AddRow() 
+*/
+sa_size_t SwFitsDataTable::AddRow(DataTableRow const& data)
+{
+  if ( data.Size() != NCols() )
+    throw SzMismatchError(" SwFitsDataTable::AddRow() - data.Size() != NCols() ");
+  return AddRow(data.MTVPtr());
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/FitsIOServer/swfitsdtable.h	(revision 3445)
@@ -0,0 +1,83 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Class DataTable  (Row-Column data table in memory) 
+//   R. Ansari -  Avril 2005
+//   (C)  LAL-IN2P3/CNRS    CEA-DAPNIA  
+
+#ifndef SWFITSDTABLE_H_SEEN
+#define SWFITSDTABLE_H_SEEN
+
+#include "basedtable.h"
+#include "swsegdb.h"
+#include "fitsswapper.h"
+
+#include "fitshandler.h"
+
+namespace SOPHYA {
+
+//! An implementation of BaseDataTable with using FITS files as swap space.
+class SwFitsDataTable : public BaseDataTable {
+public:
+  SwFitsDataTable(sa_size_t segsz=512);
+  SwFitsDataTable(FitsInOutFile & os, sa_size_t segsz=512, bool fgcreate=true); 
+  SwFitsDataTable(string fitsname, int hdunum=2, sa_size_t segsz=512); 
+  SwFitsDataTable(SwFitsDataTable const& a); 
+
+  virtual ~SwFitsDataTable();
+
+  virtual sa_size_t AddColumn(FieldType ft, string const & cnom);
+
+  virtual sa_size_t WriteTableDefinitionToFits();
+
+  // Filling data structures (adding lines)
+  virtual sa_size_t AddRow(const r_8* data);
+  virtual sa_size_t AddRow(const MuTyV * data);
+  virtual sa_size_t AddRow(DataTableRow const& data);
+
+   //! Equal (copy) operator - Copies the data and the structure from \b a   
+  inline  SwFitsDataTable& operator = (BaseDataTable const& a) 
+  { CopyMerge(a, true) ; return *this ; } 
+ //! Equal (copy) operator - Copies the structure and shares the data \b a   
+  inline SwFitsDataTable& operator = (SwFitsDataTable const& a) 
+  { Clear(); Share(a); return *this ; } 
+
+  //! Acces the FitsInOutFile swap stream
+  inline FitsInOutFile& FitsSwapFile() { return mSwF; } 
+  
+  //! Reset(Clear) the table content and structure
+  virtual void Clear();
+  /*! This method should be called in order to empty the swapout buffer, 
+     before saving object to PPF stream 
+  */
+  void SwapOutAll() const;
+
+  //  Pour la gestion I/O FITS
+  friend class FitsHandler<BaseDataTable> ; 
+
+protected:
+  void Share(SwFitsDataTable const & a);
+  // Methode pour utilisation par FitsHandler<BaseDataTable>
+  sa_size_t AddColRd(FieldType ft, string const & cnom, int colidx=-1, 
+		     vector<int_8> const * swpos=NULL);
+
+
+  // Donnees (SegDataBlock) et leurs swapper
+  std::vector< SwSegDataBlock<int_4> > mICols; 
+  std::vector< SwSegDataBlock<int_8> > mLCols; 
+  std::vector< SwSegDataBlock<r_4> > mFCols;
+  std::vector< SwSegDataBlock<r_8> > mDCols; 
+  std::vector< SwSegDataBlock< complex<r_4> > > mYCols;
+  std::vector< SwSegDataBlock< complex<r_8> > > mZCols;
+  std::vector< SwSegDataBlock<string> > mSCols;    
+ 
+  // In/Out swap file doit etre cree avant l'appel au constructeur
+  // et rester valide (non detruit) tant que l'objet SwFitsDataTable existe
+  FitsInOutFile mSwF;   
+  bool mFgCreate; // true -> creation de table, false -> lecture
+  bool mFgDefDone; // true -> Definition de bin-table effectuee 
+}; 
+
+  
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/IFFTW/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/Makefile	(revision 3445)
@@ -0,0 +1,40 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libIFFTW.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)fftw2server.o $(SOPHYAOBJP)fftw3server.o $(SOPHYAOBJP)fftwserver.o
+	rm -f $(SOPHYALIBP)libIFFTW.a
+ 
+$(SOPHYALIBP)libIFFTW.a : $(SOPHYAOBJP)fftwserver.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)fftwserver.o: fftwserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftwserver.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftw3server.cc \
+  $(SOPHYAINCP)FFTW/fftw3.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftwserver.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/IFFTW/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaExt/IFFTW/exclude
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/exclude	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/exclude	(revision 3445)
@@ -0,0 +1,2 @@
+fftw2server.cc
+fftw3server.cc
Index: /tags/V_Nov2007/SophyaExt/IFFTW/extlib_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/extlib_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/extlib_list	(revision 3445)
@@ -0,0 +1,2 @@
+fftw
+rfftw
Index: /tags/V_Nov2007/SophyaExt/IFFTW/extslb_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/extslb_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/extslb_list	(revision 3445)
@@ -0,0 +1,2 @@
+fftw
+rfftw
Index: /tags/V_Nov2007/SophyaExt/IFFTW/fftw2server.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/fftw2server.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/fftw2server.cc	(revision 3445)
@@ -0,0 +1,386 @@
+#include "FFTW/fftw.h"
+#include "FFTW/rfftw.h"
+
+
+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-- */
+//! Constructor - will always preserve input with FFTW2
+FFTWServer::FFTWServer(bool /*preserve_input*/)
+  : FFTServerInterface("FFTServer using FFTW package")
+  , ckR8("FFTWServer - ", true, false) ,
+  _preserve_input(true)
+
+{
+  _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> > & 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> > & 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 > & 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(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> > & 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, usoutsz);
+    //    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::FFTBackward( 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, 
+			       bool usz)
+{
+  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;
+  if (usz) {
+    if ( (out.NElts() != 2*n-1) && (out.NElts() != 2*n-2) )
+      throw SzMismatchError("FFTWServer::ReShapetoReal(..., true) - Wrong output array size ");
+    ncs = out.NElts();
+  }
+  else {
+    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(n-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_Nov2007/SophyaExt/IFFTW/fftw3server.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/fftw3server.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/fftw3server.cc	(revision 3445)
@@ -0,0 +1,411 @@
+#include "FFTW/fftw3.h"
+
+
+static void FillSizes4FFTW(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-- */
+//! Constructor - If preserve_input==true, input arrays will not be overwritten.
+FFTWServer::FFTWServer(bool preserve_input)
+#ifdef ALSO_FFTW_FLOAT_EXTSOP 
+  : FFTServerInterface("FFTServer using FFTW3 package (r_4 and r_8)") ,
+#else
+  : FFTServerInterface("FFTServer using FFTW3 package (r_8 only)") ,
+#endif
+  ckR8("FFTWServer - ", true, false),
+  ckR4("FFTWServer - ", true, false),
+ _preserve_input(preserve_input)  
+{
+}
+
+
+/* --Methode-- */
+FFTWServer::~FFTWServer()
+{
+}
+
+/* --Methode-- */
+FFTServerInterface * FFTWServer::Clone()
+{
+  return (new FFTWServer) ;
+}
+
+/* --Methode-- */
+void 
+FFTWServer::FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out)
+{
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftw_plan p = fftw_plan_dft_1d(in.Size(), (fftw_complex *)in.Data(), 
+			 (fftw_complex *)out.Data(), 
+			 FFTW_FORWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }
+  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];
+    FillSizes4FFTW(in, sz);
+    fftw_plan p = fftw_plan_dft(in.NbDimensions(), sz,
+		      (fftw_complex *)in.Data(), (fftw_complex *)out.Data(), 
+		      FFTW_FORWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }  
+  if(this->getNormalize()) out=out/complex<r_8>((double)in.Size(),0.);
+  return;
+}
+
+/* --Methode-- */
+void FFTWServer::FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out)
+{
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftw_plan p = fftw_plan_dft_1d(in.Size(), (fftw_complex *)in.Data(), 
+				   (fftw_complex *)out.Data(), 
+				   FFTW_BACKWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_8>, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(in, sz);
+    fftw_plan p = fftw_plan_dft(in.NbDimensions(), sz,
+				(fftw_complex *)in.Data(), (fftw_complex *)out.Data(), 
+				FFTW_BACKWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_8>, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }  
+
+  return;
+}
+
+
+void FFTWServer::FFTForward(TArray< r_8 > & in, TArray< complex<r_8> > & out)
+{  
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftw_plan p = fftw_plan_dft_r2c_1d(in.Size(), in.Data(), 
+				       (fftw_complex *)out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward(r_8, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+
+    
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward(r_8, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(in, sz);
+    fftw_plan p = fftw_plan_dft_r2c(in.NbDimensions(), sz, in.Data(),
+				    (fftw_complex *)out.Data(), FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward(r_8, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }
+  if(this->getNormalize()) out=out/complex<r_8>((double)in.Size(),0.);
+  return;
+
+}
+
+
+
+void FFTWServer::FFTBackward(TArray< complex<r_8> > & in, TArray< r_8 > & out,
+			     bool usoutsz)
+{
+  // ATTENTION dans les TF (Complex->Reel), c'est la taille logique de la TF
+  // qu'il faut indiquer lors de la creation des plans, cad taille tableau reel
+  int rank = ckR8.CheckResize(in, out, usoutsz);
+  bool share = (_preserve_input) ? false : true;
+  TArray< complex<r_8> > inp(in, share);
+  if (rank == 1) { // One dimensional transform 
+    fftw_plan p = fftw_plan_dft_c2r_1d(out.Size(), (fftw_complex *)inp.Data(), 
+			     out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward(r_8, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTBackward(r_8, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(out, sz);
+    fftw_plan p = fftw_plan_dft_c2r(out.NbDimensions(), sz, (fftw_complex *)inp.Data(), 
+				    out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward(r_8, complex<r_8> ) Error creating fftw_plan"); 
+    fftw_execute(p); 
+    fftw_destroy_plan(p);
+  }
+  return;
+}
+
+
+
+/* --Methode-- */
+void FFTWServer::ReShapetoReal(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa, 
+			       bool usz)
+{
+  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;
+  if (usz) {
+    if ( (out.NElts() != 2*n-1) && (out.NElts() != 2*n-2) )
+      throw SzMismatchError("FFTWServer::ReShapetoReal(..., true) - Wrong output array size ");
+    ncs = out.NElts();
+  }
+  else {
+    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(n-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.);
+
+}
+
+
+#ifdef ALSO_FFTW_FLOAT_EXTSOP 
+ /* ---------------------------------------------------------------------------
+   We define here single precision (float) version of FFTWServr methods 
+   Needs the libfftw3f.a , in addition to libfftw3.a   
+   --------------------------------------------------------------------------- */
+/* --Methode-- */
+void 
+FFTWServer::FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out)
+{
+  int rank = ckR4.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftwf_plan p = fftwf_plan_dft_1d(in.Size(), (fftwf_complex *)in.Data(), 
+			 (fftwf_complex *)out.Data(), 
+			 FFTW_FORWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_4>, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_4>, complex<r_4> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(in, sz);
+    fftwf_plan p = fftwf_plan_dft(in.NbDimensions(), sz,
+		      (fftwf_complex *)in.Data(), (fftwf_complex *)out.Data(), 
+		      FFTW_FORWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_4>, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }  
+  if(this->getNormalize()) out=out/complex<r_4>((double)in.Size(),0.);
+  return;
+}
+
+/* --Methode-- */
+void FFTWServer::FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out)
+{
+  int rank = ckR4.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftwf_plan p = fftwf_plan_dft_1d(in.Size(), (fftwf_complex *)in.Data(), 
+				   (fftwf_complex *)out.Data(), 
+				   FFTW_BACKWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_4>, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_4>, complex<r_4> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(in, sz);
+    fftwf_plan p = fftwf_plan_dft(in.NbDimensions(), sz,
+				(fftwf_complex *)in.Data(), (fftwf_complex *)out.Data(), 
+				FFTW_BACKWARD, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward( complex<r_4>, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }  
+
+  return;
+}
+
+
+void FFTWServer::FFTForward(TArray< r_4 > & in, TArray< complex<r_4> > & out)
+{  
+  int rank = ckR4.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    fftwf_plan p = fftwf_plan_dft_r2c_1d(in.Size(), in.Data(), 
+					 (fftwf_complex *)out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward(r_4, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+
+    
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward(r_4, complex<r_4> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(in, sz);
+    fftwf_plan p = fftwf_plan_dft_r2c(in.NbDimensions(), sz, in.Data(),
+				      (fftwf_complex *)out.Data(), FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTForward(r_4, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }
+  if(this->getNormalize()) out=out/complex<r_4>((double)in.Size(),0.);
+  return;
+
+}
+
+
+
+void FFTWServer::FFTBackward(TArray< complex<r_4> > & in, TArray< r_4 > & out,
+			     bool usoutsz)
+{
+  // ATTENTION dans les TF (Complex->Reel), c'est la taille logique de la TF
+  // qu'il faut indiquer lors de la creation des plans, cad taille tableau reel
+  int rank = ckR4.CheckResize(in, out, usoutsz);
+  bool share = (_preserve_input) ? false : true;
+  TArray< complex<r_4> > inp(in, share);
+  if (rank == 1) { // One dimensional transform 
+    fftwf_plan p = fftwf_plan_dft_c2r_1d(out.Size(), (fftwf_complex *)inp.Data(), 
+					 out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward(r_4, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTBackward(r_4, complex<r_4> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FillSizes4FFTW(out, sz);
+    fftwf_plan p = fftwf_plan_dft_c2r(out.NbDimensions(), sz, (fftwf_complex *)inp.Data(), 
+			  out.Data(), FFTW_ESTIMATE);  
+    if (p == NULL) 
+      throw ParmError("FFTWServer::FFTBackward(r_4, complex<r_4> ) Error creating fftwf_plan"); 
+    fftwf_execute(p); 
+    fftwf_destroy_plan(p);
+  }
+  return;
+}
+
+
+
+/* --Methode-- */
+void FFTWServer::ReShapetoReal(TArray< complex<r_4> > const & ina, TArray< r_4 > & outa, 
+			       bool usz)
+{
+  TVector< complex<r_4> > in(ina);
+  TVector< r_4> out(outa);
+  int n = in.NElts();
+  r_4 thr = FFTArrayChecker<r_4>::ZeroThreshold();
+  sa_size_t ncs;
+  if (usz) {
+    if ( (out.NElts() != 2*n-1) && (out.NElts() != 2*n-2) )
+      throw SzMismatchError("FFTWServer::ReShapetoReal(..., true) - Wrong output array size ");
+    ncs = out.NElts();
+  }
+  else {
+    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(n-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_4 > const & ina, TArray< complex<r_4> > & outa)
+{
+  TVector< r_4> in(ina);
+  TVector< complex<r_4> > 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_4> (in(0),0.);
+  for(int k=1; k<ncs; k++) 
+    out(k) = complex<r_4>(in(k), in(n-k));
+  if (n%2 == 0) out(ncs-1) = complex<r_4>(in(n/2), 0.);
+
+}
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.cc	(revision 3445)
@@ -0,0 +1,41 @@
+#include "sopnamsp.h"
+#include "fftwserver.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
+
+#ifdef FFTW_V2_EXTSOP
+#include "fftw2server.cc"
+#else
+#include "fftw3server.cc"
+#endif
+
Index: /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/fftwserver.h	(revision 3445)
@@ -0,0 +1,84 @@
+#ifndef  FFTWServer_H_SEEN
+#define  FFTWServer_H_SEEN
+
+#include "machdefs.h"
+#include "sspvflags.h"
+#include "fftservintf.h"
+
+
+// Classe implementant l'interface FFTServerInterface en 
+// utilisant FFTW 
+
+namespace SOPHYA {
+
+#ifdef FFTW_V2_EXTSOP
+class FFTWServerPlan;
+#endif
+
+class FFTWServer : public FFTServerInterface {
+ public:
+  FFTWServer(bool preserve_input=true);
+  virtual ~FFTWServer();
+
+  
+  virtual FFTServerInterface * Clone();
+
+  // Transforme unidimensionnelle , N-dimensionnel  (double precision - r_8)
+  virtual void FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+  virtual void FFTForward(TArray< r_8 > & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< r_8 > & out,
+			   bool usoutsz=false);
+
+// Methodes statiques pour reordonner les donnees en 1-D (double precision - r_8)
+  static void ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 > & out, bool usz);
+  static void ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out);
+
+#ifdef ALSO_FFTW_FLOAT_EXTSOP 
+ /* ---------------------------------------------------------------------------
+   Declare and compile single precision (float) version of FFTWServr methods 
+   Needs the libfftw3f.a , in addition to libfftw3.a   
+   --------------------------------------------------------------------------- */
+
+  // Transforme unidimensionnelle , N-dimensionnel  (single precision - r_4)
+  virtual void FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray< r_4 > & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< r_4 > & out,
+			   bool usoutsz=false);
+
+// Methodes statiques pour reordonner les donnees en 1-D (single precision - r_4)
+  static void ReShapetoReal(TArray< complex<r_4> > const & in, TArray< r_4 > & out, bool usz);
+  static void ReShapetoCompl(TArray< r_4 > const & in, TArray< complex<r_4> > & out);
+  
+#endif
+
+ protected:
+
+#ifndef FFTW_V2_EXTSOP    
+/*  For FFTW >= V3  */
+ FFTArrayChecker<r_8> ckR8;
+ FFTArrayChecker<r_4> ckR4;
+ bool _preserve_input; // if true, input arrays not overwritten
+
+#else
+/*  For FFTW  V2  */
+ FFTWServerPlan * _p1df;
+ FFTWServerPlan * _p1db;
+ FFTWServerPlan * _pndf;
+ FFTWServerPlan * _pndb;
+
+ FFTWServerPlan * _p1drf;
+ FFTWServerPlan * _p1drb;
+ FFTWServerPlan * _pndrf;
+ FFTWServerPlan * _pndrb;
+
+ FFTArrayChecker<r_8> ckR8;
+ bool _preserve_input; // if true, input arrays not overwritten
+
+#endif
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/IFFTW/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/objlist.list	(revision 3445)
@@ -0,0 +1,1 @@
+fftwserver.o
Index: /tags/V_Nov2007/SophyaExt/IFFTW/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libextsophya.so
Index: /tags/V_Nov2007/SophyaExt/IFFTW/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/IFFTW/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/IFFTW/smakefile	(revision 3445)
@@ -0,0 +1,40 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libIFFTW.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)fftw2server.o $(SOPHYAOBJP)fftw3server.o $(SOPHYAOBJP)fftwserver.o
+	rm -f $(SOPHYALIBP)libIFFTW.a
+ 
+$(SOPHYALIBP)libIFFTW.a : $(SOPHYAOBJP)fftwserver.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)fftwserver.o: fftwserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftwserver.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftw3server.cc \
+  $(SOPHYAINCP)FFTW/fftw3.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftwserver.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/LinAlg/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/Makefile	(revision 3445)
@@ -0,0 +1,40 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libLinAlg.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)intflapack.o
+	rm -f $(SOPHYALIBP)libLinAlg.a
+ 
+$(SOPHYALIBP)libLinAlg.a : $(SOPHYAOBJP)intflapack.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)intflapack.o: intflapack.cc \
+  $(SOPHYAINCP)sopnamsp.h intflapack.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)tmatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  intflapack.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/LinAlg/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaExt/LinAlg/intflapack.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/intflapack.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/intflapack.cc	(revision 3445)
@@ -0,0 +1,1225 @@
+#include <iostream>
+#include <math.h>
+#include "sopnamsp.h"
+#include "intflapack.h"
+#include "sspvflags.h"
+
+#include "tvector.h"
+#include "tmatrix.h"
+#include <typeinfo>
+
+#define GARDMEM 5
+
+/*************** Pour memoire  (Christophe) ***************
+Les dispositions memoires (FORTRAN) pour les vecteurs et matrices LAPACK:
+
+1./ --- REAL X(N):
+    if an array X of dimension (N) holds a vector x,
+    then X(i) holds "x_i" for i=1,...,N
+
+2./ --- REAL A(LDA,N):
+    if a two-dimensional array A of dimension (LDA,N) holds an m-by-n matrix A,
+    then A(i,j) holds "a_ij" for i=1,...,m et j=1,...,n  (LDA must be at least m).
+    Note that array arguments are usually declared in the software as assumed-size
+    arrays (last dimension *), for example: REAL A(LDA,*)
+    --- Rangement en memoire:
+                            | 11 12 13 14 |
+    Ex: Real A(4,4):    A = | 21 22 23 24 |
+                            | 31 32 33 34 |
+                            | 41 42 43 44 |
+        memoire: {11 21 31 41} {12 22 32 42} {13 23 33 43} {14 24 34 44}
+                 First indice (line) "i" varies then the second (column):
+                 (put all the first column, then put all the second column,
+                  ..., then put all the last column)
+***********************************************************/
+
+/*!
+   \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 LapackServer (Feb 2005) provides  
+  interfaces for the linear system solver, singular value 
+  decomposition (SVD), Least square solver and  
+  eigen value / eigen vector decomposition. 
+  Only arrays with BaseArray::FortranMemoryMapping 
+  can be handled by LapackServer. LapackServer can be instanciated 
+  for simple and double precision real or complex array types.
+  \warning The input array is overwritten in most cases.
+  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
+
+*/
+
+/*
+  Decembre 2005 : Suite portage AIX xlC 
+  On declare des noms en majuscule pour les routines fortran - 
+  avec ou sans underscore _ , suivant les systemes 
+*/
+#ifdef AIX
+
+#define ilaenv   ilaenv
+
+#define sgesv    sgesv
+#define dgesv    dgesv
+#define cgesv    cgesv 
+#define zgesv    zgesv
+
+#define ssysv    ssysv
+#define dsysv    dsysv
+#define csysv    csysv
+#define zsysv    zsysv
+
+#define sgels    sgels
+#define dgels    dgels
+#define cgels    cgels
+#define zgels    zgels
+
+#define sgelsd    sgelsd
+#define dgelsd    dgelsd
+#define cgelsd    cgelsd
+#define zgelsd    zgelsd
+
+#define sgesvd    sgesvd
+#define dgesvd    dgesvd
+#define cgesvd    cgesvd
+#define zgesvd    zgesvd
+
+#define sgesdd    sgesdd
+#define dgesdd    dgesdd
+#define cgesdd    cgesdd
+#define zgesdd    zgesdd
+
+#define ssyev     ssyev
+#define dsyev     dsyev
+#define cheev     cheev
+#define zheev     zheev
+
+#define sgeev     sgeev
+#define dgeev     dgeev
+#define cgeev     cgeev
+#define zgeev     zgeev
+
+#else 
+#define ilaenv   ilaenv_
+
+#define sgesv    sgesv_
+#define dgesv    dgesv_
+#define cgesv    cgesv_ 
+#define zgesv    zgesv_
+
+#define ssysv    ssysv_
+#define dsysv    dsysv_
+#define csysv    csysv_
+#define zsysv    zsysv_
+
+#define sgels    sgels_
+#define dgels    dgels_
+#define cgels    cgels_
+#define zgels    zgels_
+
+#define sgelsd    sgelsd_
+#define dgelsd    dgelsd_
+#define cgelsd    cgelsd_
+#define zgelsd    zgelsd_
+
+#define sgesvd    sgesvd_
+#define dgesvd    dgesvd_
+#define cgesvd    cgesvd_
+#define zgesvd    zgesvd_
+
+#define sgesdd    sgesdd_
+#define dgesdd    dgesdd_
+#define cgesdd    cgesdd_
+#define zgesdd    zgesdd_
+
+#define ssyev     ssyev_
+#define dsyev     dsyev_
+#define cheev     cheev_
+#define zheev     zheev_
+
+#define sgeev     sgeev_
+#define dgeev     dgeev_
+#define cgeev     cgeev_
+#define zgeev     zgeev_
+
+#endif
+////////////////////////////////////////////////////////////////////////////////////
+extern "C" {
+// Le calculateur de workingspace
+  int_4 ilaenv(int_4 *ispec,char *name,char *opts,int_4 *n1,int_4 *n2,int_4 *n3,int_4 *n4,
+                int_4 nc1,int_4 nc2);
+
+// 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);
+
+// Drivers pour resolution de systemes lineaires symetriques
+  void ssysv(char* uplo, int_4* n, int_4* nrhs, r_4* a, int_4* lda, 
+	      int_4* ipiv, r_4* b, int_4* ldb,
+              r_4* work, int_4* lwork, int_4* info);
+  void dsysv(char* uplo, int_4* n, int_4* nrhs, r_8* a, int_4* lda, 
+	      int_4* ipiv, r_8* b, int_4* ldb,
+              r_8* work, int_4* lwork, int_4* info);
+  void csysv(char* uplo, int_4* n, int_4* nrhs, complex<r_4>* a, int_4* lda, 
+	      int_4* ipiv, complex<r_4>* b, int_4* ldb,
+              complex<r_4>* work, int_4* lwork, int_4* info);
+  void zsysv(char* uplo, int_4* n, int_4* nrhs, complex<r_8>* a, int_4* lda, 
+	      int_4* ipiv, complex<r_8>* b, int_4* ldb,
+              complex<r_8>* work, int_4* lwork, 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 resolution de systemes au sens de Xi2 par SVD Divide & Conquer
+  void sgelsd(int_4* m,int_4* n,int_4* nrhs,r_4* a,int_4* lda, 
+	      r_4* b,int_4* ldb,r_4* s,r_4* rcond,int_4* rank,
+              r_4* work,int_4* lwork,int_4* iwork,int_4* info);
+  void dgelsd(int_4* m,int_4* n,int_4* nrhs,r_8* a,int_4* lda, 
+	      r_8* b,int_4* ldb,r_8* s,r_8* rcond,int_4* rank,
+              r_8* work,int_4* lwork,int_4* iwork,int_4* info);
+  void cgelsd(int_4* m,int_4* n,int_4* nrhs,complex<r_4>* a,int_4* lda, 
+	      complex<r_4>* b,int_4* ldb,r_4* s,r_4* rcond,int_4* rank,
+              complex<r_4>* work,int_4* lwork,r_4* rwork,int_4* iwork,int_4* info);
+  void zgelsd(int_4* m,int_4* n,int_4* nrhs,complex<r_8>* a,int_4* lda, 
+	      complex<r_8>* b,int_4* ldb,r_8* s,r_8* rcond,int_4* rank,
+              complex<r_8>* work,int_4* lwork,r_8* rwork,int_4* iwork,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,
+	       r_4* s, complex<r_4>* u, int_4* ldu, complex<r_4>* vt, int_4* ldvt, 
+	       complex<r_4>* work, int_4* lwork, r_4* rwork, int_4* info);
+  void zgesvd(char* jobu, char* jobvt, int_4* m, int_4* n, complex<r_8>* a, int_4* lda,
+	       r_8* s, complex<r_8>* u, int_4* ldu, complex<r_8>* vt, int_4* ldvt, 
+	       complex<r_8>* work, int_4* lwork, r_8* rwork, int_4* info);
+
+// Driver pour decomposition SVD Divide and Conquer
+  void sgesdd(char* jobz, 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* iwork, int_4* info);
+  void dgesdd(char* jobz, 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* iwork, int_4* info);
+  void cgesdd(char* jobz, int_4* m, int_4* n, complex<r_4>* a, int_4* lda,
+	       r_4* s, complex<r_4>* u, int_4* ldu, complex<r_4>* vt, int_4* ldvt, 
+	       complex<r_4>* work, int_4* lwork, r_4* rwork, int_4* iwork, int_4* info);
+  void zgesdd(char* jobz, int_4* m, int_4* n, complex<r_8>* a, int_4* lda,
+	       r_8* s, complex<r_8>* u, int_4* ldu, complex<r_8>* vt, int_4* ldvt, 
+	       complex<r_8>* work, int_4* lwork, r_8* rwork, int_4* iwork, int_4* info);
+
+// Driver pour eigen decomposition for symetric/hermitian matrices
+  void ssyev(char* jobz, char* uplo, int_4* n, r_4* a, int_4* lda, r_4* w,
+              r_4* work, int_4 *lwork, int_4* info);
+  void dsyev(char* jobz, char* uplo, int_4* n, r_8* a, int_4* lda, r_8* w,
+              r_8* work, int_4 *lwork, int_4* info);
+  void cheev(char* jobz, char* uplo, int_4* n, complex<r_4>* a, int_4* lda, r_4* w,
+              complex<r_4>* work, int_4 *lwork, r_4* rwork, int_4* info);
+  void zheev(char* jobz, char* uplo, int_4* n, complex<r_8>* a, int_4* lda, r_8* w,
+              complex<r_8>* work, int_4 *lwork, r_8* rwork, int_4* info);
+
+// Driver pour eigen decomposition for general squared matrices
+  void sgeev(char* jobl, char* jobvr, int_4* n, r_4* a, int_4* lda, r_4* wr, r_4* wi,
+              r_4* vl, int_4* ldvl, r_4* vr, int_4* ldvr, 
+              r_4* work, int_4 *lwork, int_4* info);
+  void dgeev(char* jobl, char* jobvr, int_4* n, r_8* a, int_4* lda, r_8* wr, r_8* wi,
+              r_8* vl, int_4* ldvl, r_8* vr, int_4* ldvr, 
+              r_8* work, int_4 *lwork, int_4* info);
+  void cgeev(char* jobl, char* jobvr, int_4* n,  complex<r_4>* a, int_4* lda, complex<r_4>* w,
+              complex<r_4>* vl, int_4* ldvl, complex<r_4>* vr, int_4* ldvr, 
+              complex<r_4>* work, int_4 *lwork, r_4* rwork, int_4* info);
+  void zgeev(char* jobl, char* jobvr, int_4* n,  complex<r_8>* a, int_4* lda, complex<r_8>* w,
+              complex<r_8>* vl, int_4* ldvl, complex<r_8>* vr, int_4* ldvr, 
+              complex<r_8>* work, int_4 *lwork, r_8* rwork, int_4* info);
+
+}
+
+//   -------------- Classe LapackServer<T> --------------
+
+////////////////////////////////////////////////////////////////////////////////////
+template <class T>
+LapackServer<T>::LapackServer(bool throw_on_error)
+  : Throw_On_Error(throw_on_error)
+{
+  SetWorkSpaceSizeFactor();
+}
+
+template <class T>
+LapackServer<T>::~LapackServer()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+template <class T>
+int_4 LapackServer<T>::ilaenv_en_C(int_4 ispec,char *name,char *opts,int_4 n1,int_4 n2,int_4 n3,int_4 n4)
+{
+ int_4 nc1 = strlen(name), nc2 = strlen(opts), rc=0;
+ rc = ilaenv(&ispec,name,opts,&n1,&n2,&n3,&n4,nc1,nc2);
+ //cout<<"ilaenv_en_C("<<ispec<<","<<name<<"("<<nc1<<"),"<<opts<<"("<<nc2<<"),"
+ //    <<n1<<","<<n2<<","<<n3<<","<<n4<<") = "<<rc<<endl;
+ return rc;
+}
+
+template <class T>
+int_4 LapackServer<T>::type2i4(void *val,int nbytes)
+// Retourne un entier contenant la valeur contenue dans val
+// - nbytes = nombre de bytes dans le contenu de val
+// ex: r_4 x = 3.4;              type2i4(&x,4) -> 3
+// ex: r_8 x = 3.4;              type2i4(&x,8) -> 3
+// ex: complex<r_4> x(3.4,7.8);  type2i4(&x,4) -> 3
+// ex: complex<r_8> x(3.4,7.8);  type2i4(&x,8) -> 3
+{
+  r_4* x4; r_8* x8; int_4 lw=0;
+  if(nbytes==4) {x4 = (r_4*)val; lw = (int_4)(*x4);}
+    else        {x8 = (r_8*)val; lw = (int_4)(*x8);}
+  return lw;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//! Interface to Lapack linear system solver driver s/d/c/zgesv().
+/*! Solve the linear system a * x = b using LU factorization.
+  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;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LinSolve_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//! Interface to Lapack linear system solver driver s/d/c/zsysv().
+/*! Solve the linear system a * x = b with a symetric matrix using LU factorization.
+  Input arrays should have FortranMemory mapping (column packed).
+  \param a : input matrix symetric , overwritten on output
+  \param b : input-output, input vector b, contains x on exit
+  \return : return code from lapack driver _sysv()
+ */
+template <class T>
+int LapackServer<T>::LinSolveSym(TArray<T>& a, TArray<T> & b)
+// --- REMARQUES DE CMV ---
+// 1./ contrairement a ce qui est dit dans la doc, il s'agit
+//     de matrices SYMETRIQUES complexes et non HERMITIENNES !!!
+// 2./ pourquoi les routines de LinSolve pour des matrices symetriques
+//     sont plus de deux fois plus lentes que les LinSolve generales sur OSF
+//     et sensiblement plus lentes sous Linux ???
+{
+  if ( ( a.NbDimensions() != 2 ) || ( b.NbDimensions() != 2 ) )
+    throw(SzMismatchError("LapackServer::LinSolveSym(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::LinSolveSym(a,b) a Not a square Array"));
+  if ( a.Size(rowa) !=  b.Size(rowb)) 
+    throw(SzMismatchError("LapackServer::LinSolveSym(a,b) RowSize(a <> b) "));
+
+  if (!a.IsPacked(rowa) || !b.IsPacked(rowb))
+     throw(SzMismatchError("LapackServer::LinSolveSym(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 = 0;
+  int_4* ipiv = new int_4[n];
+  int_4 lwork = -1;
+  T * work = NULL;
+  T wkget[2];
+
+  char uplo = 'U'; // char uplo = 'L';
+  char struplo[5]; struplo[0] = uplo; struplo[1] = '\0';
+
+  if (typeid(T) == typeid(r_4) ) {
+    ssysv(&uplo, &n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb,
+          (r_4 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
+    ssysv(&uplo, &n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb,
+          (r_4 *)work, &lwork, &info);
+  } else if (typeid(T) == typeid(r_8) )  {
+    dsysv(&uplo, &n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb,
+          (r_8 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
+    dsysv(&uplo, &n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb,
+          (r_8 *)work, &lwork, &info);
+  } else if (typeid(T) == typeid(complex<r_4>) )  {
+    csysv(&uplo, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv,
+	  (complex<r_4> *)b.Data(), &ldb,
+          (complex<r_4> *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
+    csysv(&uplo, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv,
+	  (complex<r_4> *)b.Data(), &ldb,
+          (complex<r_4> *)work, &lwork, &info);
+  } else if (typeid(T) == typeid(complex<r_8>) )  {
+    zsysv(&uplo, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv,
+	  (complex<r_8> *)b.Data(), &ldb,
+          (complex<r_8> *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
+    zsysv(&uplo, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv,
+	  (complex<r_8> *)b.Data(), &ldb,
+          (complex<r_8> *)work, &lwork, &info);
+  } else {
+    if(work) delete[] work;
+    delete[] ipiv;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LinSolveSym(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LinSolveSym(a,b) - Unsupported DataType (T)");
+  }
+  if(work) delete[] work;
+  delete[] ipiv;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LinSolveSym_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  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 , using QR or LQ factorization .
+  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::LeastSquareSolve(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 = -1; //minmn+maxmnrhs*5;
+  T * work = NULL;
+  T wkget[2];
+
+  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 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
+    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 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
+    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> *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
+    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> *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
+    zgels(&trans, &m, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, 
+	   (complex<r_8> *)b.Data(), &ldb, (complex<r_8> *)work, &lwork, &info);
+  } else {
+    if(work) delete [] work; work=NULL;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LeastSquareSolve(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LeastSquareSolve(a,b) - Unsupported DataType (T)");
+  }
+  if(work) delete [] work;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LeastSquareSolve_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//! Square matrix inversion using Lapack linear system solver
+/*! Compute the inverse of a square matrix using linear system solver routine
+  Input arrays should have FortranMemory mapping (column packed).
+  \param a : input matrix, overwritten on output
+  \param ainv : output matrix, contains inverse(a) on exit. 
+  ainv is allocated if it has size 0 
+  If not allocated, ainv is automatically 
+  \return : return code from LapackServer::LinSolve()
+  \sa LapackServer::LinSolve()
+ */
+template <class T>
+int LapackServer<T>::ComputeInverse(TMatrix<T>& a, TMatrix<T> & ainv)
+{  
+  if ( a.NbDimensions() != 2 )
+    throw(SzMismatchError("LapackServer::Inverse() NDim(a) != 2"));
+  if ( a.GetMemoryMapping() != BaseArray::FortranMemoryMapping )
+    throw(SzMismatchError("LapackServer::Inverse() a NOT in FortranMemoryMapping"));
+  if ( a.NRows() != a.NCols() )
+    throw(SzMismatchError("LapackServer::Inverse() a NOT square matrix (a.NRows!=a.NCols)"));
+  if (ainv.IsAllocated()) {
+    bool smo, ssz;
+    ssz = a.CompareSizes(ainv, smo);
+    if ( (ssz == false) || (smo == false) ) 
+      throw(SzMismatchError("LapackServer::Inverse() ainv<>a Size/MemOrg mismatch "));   
+  }
+  else  ainv.SetSize(a.NRows(), a.NCols(), BaseArray::FortranMemoryMapping, false);
+  ainv = IdentityMatrix(); 
+  return LinSolve(a, ainv);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//! Interface to Lapack least squares solver driver s/d/c/zgelsd().
+/*! Solves the linear least squares problem defined by an m-by-n matrix 
+  \b a and an m element vector \b b , using SVD factorization Divide and Conquer.
+  Inout arrays should have FortranMemory mapping (column packed).
+  \param rcond : definition of zero value (S(i) <= RCOND*S(0) are treated as zero).
+                 If RCOND < 0, machine precision is used instead.
+  \param a : input matrix, overwritten on output
+  \param b : input vector b overwritten by solution on output (beware of size changing)
+  \param x : output matrix of solutions.
+  \param rank : output the rank of the matrix.
+  \return : return code from lapack driver _gelsd()
+  \warning : b is not resized.
+ */
+template <class T>
+int LapackServer<T>::LeastSquareSolveSVD_DC(TMatrix<T>& a,TMatrix<T>& b,TVector<r_8>& s,int_4& rank,r_8 rcond)
+{
+#ifdef LAPACK_V2_EXTSOP 
+  throw NotAvailableOperation("LapackServer::LeastSquareSolveSVD_DC(a,b) NOT implemented in LapackV2") ;
+#else
+  if ( ( a.NbDimensions() != 2 ) )
+    throw(SzMismatchError("LapackServer::LeastSquareSolveSVD_DC(a,b) a != 2"));
+  
+  if (!a.IsPacked() || !b.IsPacked())
+     throw(SzMismatchError("LapackServer::LeastSquareSolveSVD_DC(a,b) a Or b Not Packed"));
+
+  int_4 m = a.NRows();
+  int_4 n = a.NCols();
+
+  if(b.NRows() != m)
+     throw(SzMismatchError("LapackServer::LeastSquareSolveSVD_DC(a,b) bad matching dim between a and b"));
+
+  int_4 nrhs = b.NCols();
+  int_4 minmn = (m < n) ? m : n;
+  int_4 maxmn = (m > n) ? m : n;
+
+  int_4 lda = m;
+  int_4 ldb = maxmn;
+  int_4 info;
+
+  { // Use {} for automatic des-allocation of "bsave"
+  TMatrix<T> bsave(m,nrhs); bsave.SetMemoryMapping(BaseArray::FortranMemoryMapping);
+  bsave = b;
+  b.ReSize(maxmn,nrhs); b = (T) 0;
+  for(int i=0;i<m;i++) for(int j=0;j<nrhs;j++) b(i,j) = bsave(i,j);
+  } // Use {} for automatic des-allocation of "bsave"
+  s.ReSize(minmn);
+  
+  int_4 smlsiz = 25;  // Normallement ilaenv_en_C(9,...) renvoie toujours 25
+  if(typeid(T) == typeid(r_4) )               smlsiz = ilaenv_en_C(9,"SGELSD"," ",0,0,0,0);
+  else if(typeid(T) == typeid(r_8) )          smlsiz = ilaenv_en_C(9,"DGELSD"," ",0,0,0,0);
+  else if(typeid(T) == typeid(complex<r_4>) ) smlsiz = ilaenv_en_C(9,"CGELSD"," ",0,0,0,0);
+  else if(typeid(T) == typeid(complex<r_8>) ) smlsiz = ilaenv_en_C(9,"ZGELSD"," ",0,0,0,0);
+  if(smlsiz<0) smlsiz = 0;
+  r_8 dum = log((r_8)minmn/(r_8)(smlsiz+1.)) / log(2.);
+  int_4 nlvl = int_4(dum) + 1; if(nlvl<0) nlvl = 0;
+
+  T * work = NULL;
+  int_4 * iwork = NULL;
+  int_4 lwork=-1, lrwork;
+  T wkget[2];
+
+  if(typeid(T) == typeid(r_4) ) {
+    r_4* sloc = new r_4[minmn];
+    r_4 srcond = rcond;
+    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
+    sgelsd(&m,&n,&nrhs,(r_4*)a.Data(),&lda, 
+	   (r_4*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
+           (r_4*)wkget,&lwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    sgelsd(&m,&n,&nrhs,(r_4*)a.Data(),&lda, 
+	   (r_4*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
+           (r_4*)work,&lwork,(int_4*)iwork,&info);
+    for(int_4 i=0;i<minmn;i++) s(i) = sloc[i];
+    delete [] sloc;
+  } else if(typeid(T) == typeid(r_8) )  {
+    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
+    dgelsd(&m,&n,&nrhs,(r_8*)a.Data(),&lda, 
+	   (r_8*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
+           (r_8*)wkget,&lwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    dgelsd(&m,&n,&nrhs,(r_8*)a.Data(),&lda, 
+	   (r_8*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
+           (r_8*)work,&lwork,(int_4*)iwork,&info);
+  } else if(typeid(T) == typeid(complex<r_4>) )  {
+    // Cf meme remarque que ci-dessous (complex<r_8)
+    lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+    int_4 lrwork_d = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
+    if(lrwork_d > lrwork) lrwork = lrwork_d;
+    r_4* rwork = new r_4[lrwork +GARDMEM];
+    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
+    r_4* sloc = new r_4[minmn];
+    r_4 srcond = rcond;
+    cgelsd(&m,&n,&nrhs,(complex<r_4>*)a.Data(),&lda, 
+	   (complex<r_4>*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
+           (complex<r_4>*)wkget,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    cgelsd(&m,&n,&nrhs,(complex<r_4>*)a.Data(),&lda, 
+	   (complex<r_4>*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
+           (complex<r_4>*)work,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
+    for(int_4 i=0;i<minmn;i++) s(i) = sloc[i];
+    delete [] sloc; delete [] rwork;
+  } else if(typeid(T) == typeid(complex<r_8>) )  {
+    // CMV: Bizarrement, la formule donnee dans zgelsd() plante pour des N grands (500)
+    // On prend (par analogie) la formule pour "lwork" de dgelsd()
+    lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
+    int_4 lrwork_d = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
+    if(lrwork_d > lrwork) lrwork = lrwork_d;
+    r_8* rwork = new r_8[lrwork +GARDMEM];
+    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
+    zgelsd(&m,&n,&nrhs,(complex<r_8>*)a.Data(),&lda, 
+	   (complex<r_8>*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
+           (complex<r_8>*)wkget,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    zgelsd(&m,&n,&nrhs,(complex<r_8>*)a.Data(),&lda, 
+	   (complex<r_8>*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
+           (complex<r_8>*)work,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
+    delete [] rwork;
+  } else {
+    if(work) delete [] work; work=NULL;
+    if(iwork) delete [] iwork; iwork=NULL;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LeastSquareSolveSVD_DC(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LeastSquareSolveSVD_DC(a,b) - Unsupported DataType (T)");
+  }
+
+  if(work) delete [] work; if(iwork) delete [] iwork;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LeastSquareSolveSVD_DC_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+#endif
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//! 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 FortranMemoryMapping)
+  \param s : Vector of min(m,n) singular values (descending order)
+  \param u : m-by-m Matrix of left singular vectors 
+  \param vt : Transpose of right singular vectors (n-by-n matrix).
+  \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::SVDDriver(a, ...) a.NbDimensions() != 2"));
+
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+
+  if ( !a.IsPacked(rowa) )
+     throw(SzMismatchError("LapackServer::SVDDriver(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::SVDDriver() 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::SVDDriver() 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 info;
+
+  int_4 lwork = -1;   // maxmn*5  *wspace_size_factor;
+  T * work = NULL;    // = new T[lwork];
+  T wkget[2];
+
+  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 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    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 *)wkget, &lwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    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>) ) {
+    r_4 * rwork = new r_4[5*minmn +GARDMEM];
+    r_4 * sloc  = new r_4[minmn];
+    cgesvd(&jobu, &jobvt, &m, &n, (complex<r_4> *)a.Data(), &lda,
+	    (r_4 *)sloc, (complex<r_4> *) up->Data(), &ldu, 
+	    (complex<r_4> *)vtp->Data(), &ldvt, 
+	    (complex<r_4> *)wkget, &lwork, (r_4 *)rwork, &info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    cgesvd(&jobu, &jobvt, &m, &n, (complex<r_4> *)a.Data(), &lda,
+	    (r_4 *)sloc, (complex<r_4> *) up->Data(), &ldu, 
+	    (complex<r_4> *)vtp->Data(), &ldvt, 
+	    (complex<r_4> *)work, &lwork, (r_4 *)rwork, &info);
+    for(int_4 i=0;i<minmn;i++) s[i] = sloc[i];
+    delete [] rwork; delete [] sloc;
+  } else if (typeid(T) == typeid(complex<r_8>) )  {
+    r_8 * rwork = new r_8[5*minmn +GARDMEM];
+    r_8 * sloc  = new r_8[minmn];
+    zgesvd(&jobu, &jobvt, &m, &n, (complex<r_8> *)a.Data(), &lda,
+	    (r_8 *)sloc, (complex<r_8> *) up->Data(), &ldu, 
+	    (complex<r_8> *)vtp->Data(), &ldvt, 
+	    (complex<r_8> *)wkget, &lwork, (r_8 *)rwork, &info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    zgesvd(&jobu, &jobvt, &m, &n, (complex<r_8> *)a.Data(), &lda,
+	    (r_8 *)sloc, (complex<r_8> *) up->Data(), &ldu, 
+	    (complex<r_8> *)vtp->Data(), &ldvt, 
+	    (complex<r_8> *)work, &lwork, (r_8 *)rwork, &info);
+    for(int_4 i=0;i<minmn;i++) s[i] = sloc[i];
+    delete [] rwork; delete [] sloc;
+  } else {
+    if(work) delete [] work; work=NULL;
+    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::SVDDriver(a,b) - Unsupported DataType (T)");
+  }
+
+  if(work) delete [] work;
+  if (jobu == 'N') delete up;
+  if (jobvt == 'N') delete vtp;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"SVDDriver_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+}
+
+
+//! Interface to Lapack SVD driver s/d/c/zgesdd().
+/*! Same as SVD but with Divide and Conquer method */
+template <class T>
+int LapackServer<T>::SVD_DC(TMatrix<T>& a, TVector<r_8>& s, TMatrix<T>& u, TMatrix<T>& vt)
+{
+#ifdef LAPACK_V2_EXTSOP 
+  throw NotAvailableOperation("LapackServer::SVD_DC(a,b) NOT implemented in LapackV2") ;
+#else
+  if ( !a.IsPacked() )
+     throw(SzMismatchError("LapackServer::SVD_DC(a, ...) a Not Packed "));
+
+  int_4 m = a.NRows();
+  int_4 n = a.NCols();
+  int_4 maxmn = (m > n) ? m : n;
+  int_4 minmn = (m < n) ? m : n;
+  int_4 supermax = 4*minmn*minmn+4*minmn; if(maxmn>supermax) supermax=maxmn;
+
+  char jobz = 'A';
+
+  s.ReSize(minmn);
+  u.ReSize(m,m);
+  vt.ReSize(n,n);
+
+  int_4 lda = m;
+  int_4 ldu = m;
+  int_4 ldvt = n;
+  int_4 info;
+  int_4 lwork=-1;
+  T * work = NULL;
+  int_4 * iwork = NULL;
+  T wkget[2];
+
+  if(typeid(T) == typeid(r_4) ) {
+    r_4* sloc = new r_4[minmn];
+    iwork = new int_4[8*minmn +GARDMEM];
+    sgesdd(&jobz,&m,&n,(r_4*)a.Data(),&lda,
+	   (r_4*)sloc,(r_4*)u.Data(),&ldu,(r_4*)vt.Data(),&ldvt, 
+	   (r_4*)wkget,&lwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    sgesdd(&jobz,&m,&n,(r_4*)a.Data(),&lda,
+	   (r_4*)sloc,(r_4*)u.Data(),&ldu,(r_4*)vt.Data(),&ldvt, 
+	   (r_4*)work,&lwork,(int_4*)iwork,&info);
+    for(int_4 i=0;i<minmn;i++) s(i) = (r_8) sloc[i];
+    delete [] sloc;
+  } else if(typeid(T) == typeid(r_8) ) {
+    iwork = new int_4[8*minmn +GARDMEM];
+    dgesdd(&jobz,&m,&n,(r_8*)a.Data(),&lda,
+	   (r_8*)s.Data(),(r_8*)u.Data(),&ldu,(r_8*)vt.Data(),&ldvt, 
+	   (r_8*)wkget,&lwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    dgesdd(&jobz,&m,&n,(r_8*)a.Data(),&lda,
+	   (r_8*)s.Data(),(r_8*)u.Data(),&ldu,(r_8*)vt.Data(),&ldvt, 
+	   (r_8*)work,&lwork,(int_4*)iwork,&info);
+  } else if(typeid(T) == typeid(complex<r_4>) ) {
+    r_4* sloc = new r_4[minmn];
+    r_4* rwork = new r_4[5*minmn*minmn+5*minmn +GARDMEM];
+    iwork = new int_4[8*minmn +GARDMEM];
+    cgesdd(&jobz,&m,&n,(complex<r_4>*)a.Data(),&lda,
+	   (r_4*)sloc,(complex<r_4>*)u.Data(),&ldu,(complex<r_4>*)vt.Data(),&ldvt, 
+	   (complex<r_4>*)wkget,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
+    cgesdd(&jobz,&m,&n,(complex<r_4>*)a.Data(),&lda,
+	   (r_4*)sloc,(complex<r_4>*)u.Data(),&ldu,(complex<r_4>*)vt.Data(),&ldvt, 
+	   (complex<r_4>*)work,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
+    for(int_4 i=0;i<minmn;i++) s(i) = (r_8) sloc[i];
+    delete [] sloc; delete [] rwork;
+  } else if(typeid(T) == typeid(complex<r_8>) )  {
+    r_8* rwork = new r_8[5*minmn*minmn+5*minmn +GARDMEM];
+    iwork = new int_4[8*minmn +GARDMEM];
+    zgesdd(&jobz,&m,&n,(complex<r_8>*)a.Data(),&lda,
+	   (r_8*)s.Data(),(complex<r_8>*)u.Data(),&ldu,(complex<r_8>*)vt.Data(),&ldvt, 
+	   (complex<r_8>*)wkget,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
+    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
+    zgesdd(&jobz,&m,&n,(complex<r_8>*)a.Data(),&lda,
+	   (r_8*)s.Data(),(complex<r_8>*)u.Data(),&ldu,(complex<r_8>*)vt.Data(),&ldvt, 
+	   (complex<r_8>*)work,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
+    delete [] rwork;
+  } else {
+    if(work) delete [] work; work=NULL;
+    if(iwork) delete [] iwork; iwork=NULL;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::SVD_DC(...) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::SVD_DC - Unsupported DataType (T)");
+  }
+
+  if(work) delete [] work; if(iwork) delete [] iwork;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"SVD_DC_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+#endif
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+/*! Computes the eigen values and eigen vectors of a symetric (or hermitian) matrix \b a.
+  Input arrays should have FortranMemoryMapping (column packed).
+  \param a : input symetric (or hermitian) n-by-n matrix 
+  \param b : Vector of eigenvalues (descending order)
+  \param eigenvector : if true compute eigenvectors, if not only eigenvalues
+  \param a : on return array of eigenvectors (same order than eval, one vector = one column)
+  \return : return code from lapack driver
+ */
+
+template <class T>
+int LapackServer<T>::LapackEigenSym(TArray<T>& a, TVector<r_8>& b, bool eigenvector)
+{
+  if ( a.NbDimensions() != 2 )
+    throw(SzMismatchError("LapackServer::LapackEigenSym(a,b) a NbDimensions() != 2"));
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+  if ( a.Size(rowa) !=  a.Size(cola)) 
+    throw(SzMismatchError("LapackServer::LapackEigenSym(a,b) a Not a square Array"));
+  if (!a.IsPacked(rowa))
+    throw(SzMismatchError("LapackServer::LapackEigenSym(a,b) a Not Column Packed"));
+
+  char uplo='U';
+  char jobz='N'; if(eigenvector) jobz='V';
+
+  int_4 n = a.Size(rowa);
+  int_4 lda = a.Step(cola);
+  int_4 info = 0;
+  int_4 lwork = -1;
+  T * work = NULL;
+  T wkget[2];
+
+  b.ReSize(n); b = 0.;
+
+  if (typeid(T) == typeid(r_4) ) {
+    r_4* w = new r_4[n];
+    ssyev(&jobz,&uplo,&n,(r_4 *)a.Data(),&lda,(r_4 *)w,(r_4 *)wkget,&lwork,&info);
+    lwork = type2i4(&wkget[0],4); /* 3*n-1;*/ work = new T[lwork  +GARDMEM];
+    ssyev(&jobz,&uplo,&n,(r_4 *)a.Data(),&lda,(r_4 *)w,(r_4 *)work,&lwork,&info);
+    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
+    delete [] w;
+  } else if (typeid(T) == typeid(r_8) )  {
+    r_8* w = new r_8[n];
+    dsyev(&jobz,&uplo,&n,(r_8 *)a.Data(),&lda,(r_8 *)w,(r_8 *)wkget,&lwork,&info);
+    lwork = type2i4(&wkget[0],8); /* 3*n-1;*/ work = new T[lwork  +GARDMEM];
+    dsyev(&jobz,&uplo,&n,(r_8 *)a.Data(),&lda,(r_8 *)w,(r_8 *)work,&lwork,&info);
+    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
+    delete [] w;
+  } else if (typeid(T) == typeid(complex<r_4>) )  {
+    r_4* rwork = new r_4[3*n-2  +GARDMEM]; r_4* w = new r_4[n];
+    cheev(&jobz,&uplo,&n,(complex<r_4> *)a.Data(),&lda,(r_4 *)w
+          ,(complex<r_4> *)wkget,&lwork,(r_4 *)rwork,&info);
+    lwork = type2i4(&wkget[0],4); /* 2*n-1;*/ work = new T[lwork  +GARDMEM];
+    cheev(&jobz,&uplo,&n,(complex<r_4> *)a.Data(),&lda,(r_4 *)w
+          ,(complex<r_4> *)work,&lwork,(r_4 *)rwork,&info);
+    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
+    delete [] rwork; delete [] w;
+  } else if (typeid(T) == typeid(complex<r_8>) )  {
+    r_8* rwork = new r_8[3*n-2  +GARDMEM]; r_8* w = new r_8[n];
+    zheev(&jobz,&uplo,&n,(complex<r_8> *)a.Data(),&lda,(r_8 *)w
+          ,(complex<r_8> *)wkget,&lwork,(r_8 *)rwork,&info);
+    lwork = type2i4(&wkget[0],8); /* 2*n-1;*/ work = new T[lwork  +GARDMEM];
+    zheev(&jobz,&uplo,&n,(complex<r_8> *)a.Data(),&lda,(r_8 *)w
+          ,(complex<r_8> *)work,&lwork,(r_8 *)rwork,&info);
+    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
+    delete [] rwork; delete [] w;
+  } else {
+    if(work) delete [] work; work=NULL;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LapackEigenSym(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LapackEigenSym(a,b) - Unsupported DataType (T)");
+  }
+
+  if(work) delete [] work;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LapackEigenSym_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+/*! Computes the eigen values and eigen vectors of a general squared matrix \b a.
+  Input arrays should have FortranMemoryMapping (column packed).
+  \param a : input general n-by-n matrix 
+  \param eval : Vector of eigenvalues (complex double precision)
+  \param evec : Matrix of eigenvector (same order than eval, one vector = one column)
+  \param eigenvector : if true compute (right) eigenvectors, if not only eigenvalues
+  \param a : on return array of eigenvectors
+  \return : return code from lapack driver
+  \verbatim
+  eval : contains the computed eigenvalues.
+         --- For real matrices "a" :
+         Complex conjugate pairs of eigenvalues appear consecutively
+         with the eigenvalue having the positive imaginary part first.
+  evec : the right eigenvectors v(j) are stored one after another
+         in the columns of evec, in the same order as their eigenvalues.
+         --- For real matrices "a" :
+         If the j-th eigenvalue is real, then v(j) = evec(:,j),
+           the j-th column of evec.
+         If the j-th and (j+1)-st eigenvalues form a complex
+           conjugate pair, then v(j) = evec(:,j) + i*evec(:,j+1) and
+           v(j+1) = evec(:,j) - i*evec(:,j+1).
+  \endverbatim
+*/
+
+template <class T>
+int LapackServer<T>::LapackEigen(TArray<T>& a, TVector< complex<r_8> >& eval, TMatrix<T>& evec, bool eigenvector)
+{
+  if ( a.NbDimensions() != 2 )
+    throw(SzMismatchError("LapackServer::LapackEigen(a,b) a NbDimensions() != 2"));
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+  if ( a.Size(rowa) !=  a.Size(cola)) 
+    throw(SzMismatchError("LapackServer::LapackEigen(a,b) a Not a square Array"));
+  if (!a.IsPacked(rowa))
+    throw(SzMismatchError("LapackServer::LapackEigen(a,b) a Not Column Packed"));
+
+  char jobvl = 'N';
+  char jobvr = 'N'; if(eigenvector) jobvr='V';
+
+  int_4 n = a.Size(rowa);
+  int_4 lda = a.Step(cola);
+  int_4 info = 0;
+
+  eval.ReSize(n); eval = complex<r_8>(0.,0.);
+  if(eigenvector) {evec.ReSize(n,n); evec = (T) 0.;}
+  int_4 ldvr = n, ldvl = 1;
+
+  int_4 lwork = -1;
+  T * work = NULL;
+  T wkget[2];
+
+  if (typeid(T) == typeid(r_4) ) {
+    r_4* wr = new r_4[n]; r_4* wi = new r_4[n]; r_4* vl = NULL;
+    sgeev(&jobvl,&jobvr,&n,(r_4 *)a.Data(),&lda,(r_4 *)wr,(r_4 *)wi,
+	   (r_4 *)vl,&ldvl,(r_4 *)evec.Data(),&ldvr,
+           (r_4 *)wkget,&lwork,&info);
+    lwork = type2i4(&wkget[0],4); /* 4*n;*/ work = new T[lwork  +GARDMEM];
+    sgeev(&jobvl,&jobvr,&n,(r_4 *)a.Data(),&lda,(r_4 *)wr,(r_4 *)wi,
+	   (r_4 *)vl,&ldvl,(r_4 *)evec.Data(),&ldvr,
+           (r_4 *)work,&lwork,&info);
+    if(info==0) for(int i=0;i<n;i++) eval(i) = complex<r_8>(wr[i],wi[i]);
+    delete [] wr; delete [] wi;
+  } else if (typeid(T) == typeid(r_8) )  {
+    r_8* wr = new r_8[n]; r_8* wi = new r_8[n]; r_8* vl = NULL;
+    dgeev(&jobvl,&jobvr,&n,(r_8 *)a.Data(),&lda,(r_8 *)wr,(r_8 *)wi,
+	   (r_8 *)vl,&ldvl,(r_8 *)evec.Data(),&ldvr,
+           (r_8 *)wkget,&lwork,&info);
+    lwork = type2i4(&wkget[0],8); /* 4*n;*/ work = new T[lwork  +GARDMEM];
+    dgeev(&jobvl,&jobvr,&n,(r_8 *)a.Data(),&lda,(r_8 *)wr,(r_8 *)wi,
+	   (r_8 *)vl,&ldvl,(r_8 *)evec.Data(),&ldvr,
+           (r_8 *)work,&lwork,&info);
+    if(info==0) for(int i=0;i<n;i++) eval(i) = complex<r_8>(wr[i],wi[i]);
+    delete [] wr; delete [] wi;
+  } else if (typeid(T) == typeid(complex<r_4>) )  {
+    r_4* rwork = new r_4[2*n  +GARDMEM]; r_4* vl = NULL; TVector< complex<r_4> > w(n);
+    cgeev(&jobvl,&jobvr,&n,(complex<r_4> *)a.Data(),&lda,(complex<r_4> *)w.Data(),
+	   (complex<r_4> *)vl,&ldvl,(complex<r_4> *)evec.Data(),&ldvr,
+           (complex<r_4> *)wkget,&lwork,(r_4 *)rwork,&info);
+    lwork = type2i4(&wkget[0],4); /* 2*n;*/ work = new T[lwork  +GARDMEM];
+    cgeev(&jobvl,&jobvr,&n,(complex<r_4> *)a.Data(),&lda,(complex<r_4> *)w.Data(),
+	   (complex<r_4> *)vl,&ldvl,(complex<r_4> *)evec.Data(),&ldvr,
+           (complex<r_4> *)work,&lwork,(r_4 *)rwork,&info);
+    if(info==0) for(int i=0;i<n;i++) eval(i) = w(i);
+    delete [] rwork;
+  } else if (typeid(T) == typeid(complex<r_8>) )  {
+    r_8* rwork = new r_8[2*n  +GARDMEM]; r_8* vl = NULL;
+    zgeev(&jobvl,&jobvr,&n,(complex<r_8> *)a.Data(),&lda,(complex<r_8> *)eval.Data(),
+	   (complex<r_8> *)vl,&ldvl,(complex<r_8> *)evec.Data(),&ldvr,
+           (complex<r_8> *)wkget,&lwork,(r_8 *)rwork,&info);
+    lwork = type2i4(&wkget[0],8); /* 2*n;*/ work = new T[lwork  +GARDMEM];
+    zgeev(&jobvl,&jobvr,&n,(complex<r_8> *)a.Data(),&lda,(complex<r_8> *)eval.Data(),
+	   (complex<r_8> *)vl,&ldvl,(complex<r_8> *)evec.Data(),&ldvr,
+           (complex<r_8> *)work,&lwork,(r_8 *)rwork,&info);
+    delete [] rwork;
+  } else {
+    if(work) delete [] work; work=NULL;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LapackEigen(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LapackEigen(a,b) - Unsupported DataType (T)");
+  }
+
+  if(work) delete [] work;
+  if(info!=0 && Throw_On_Error) {
+    char serr[128]; sprintf(serr,"LapackEigen_Error info=%d",info);
+    throw MathExc(serr);
+  }
+  return(info);
+}
+
+
+
+
+///////////////////////////////////////////////////////////////
+#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)
+namespace SOPHYA {
+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_Nov2007/SophyaExt/LinAlg/intflapack.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/intflapack.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/intflapack.h	(revision 3445)
@@ -0,0 +1,134 @@
+#ifndef  IntfLapack_H_SEEN
+#define  IntfLapack_H_SEEN
+
+#include "machdefs.h"
+#include "tarray.h"
+#include "tvector.h"
+
+namespace SOPHYA {
+
+template <class T>
+class LapackServer { 
+public:
+  LapackServer(bool throw_on_error=false);
+  virtual ~LapackServer();
+
+  virtual int LinSolve(TArray<T>& a, TArray<T> & b); 
+  virtual int LinSolveSym(TArray<T>& a, TArray<T> & b); 
+  virtual int LeastSquareSolve(TArray<T>& a, TArray<T> & b); 
+  virtual int LeastSquareSolveSVD_DC(TMatrix<T>& a,TMatrix<T>& b,TVector<r_8>& s,int_4& rank,r_8 rcond=-1.); 
+
+  // Calcul de la matrice inverse en utilisant la resolution de syst. lineaire
+  virtual int ComputeInverse(TMatrix<T>& a, TMatrix<T>& ainv);
+
+  virtual int SVD(TArray<T>& a, TArray<T> & s); 
+  virtual int SVD(TArray<T>& a, TArray<T> & s, TArray<T> & u, TArray<T> & vt);
+  virtual int SVD_DC(TMatrix<T>& a, TVector<r_8>& s, TMatrix<T>& u, TMatrix<T>& vt);
+ 
+  virtual int LapackEigenSym(TArray<T>& a, TVector<r_8>& b, bool eigenvector=true);
+  virtual int LapackEigen(TArray<T>& a, TVector< complex<r_8> >& eval, TMatrix<T>& evec, bool eigenvector);
+
+  //! 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_4 ilaenv_en_C(int_4 ispec,char *name,char *opts,int_4 n1,int_4 n2,int_4 n3,int_4 n4);
+  int_4 type2i4(void *val,int nbytes);
+
+  int wspace_size_factor;
+  bool Throw_On_Error;
+};
+
+/*! \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 LapackLinSolveSym(TArray<T>&, TArray<T> &)
+    \brief Solves the linear system A*X = B with A symetric using LapackServer. 
+*/
+template <class T>
+inline int LapackLinSolveSym(TArray<T>& a, TArray<T> & b)
+{ LapackServer<T> lps; return( lps.LinSolveSym(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 LapackInverse(TMatrix<T>&)
+    \brief Computes the inverse matrix using linear system solver LapackServer::LinSolve. 
+*/
+template <class T>
+inline TMatrix<T> LapackInverse(TMatrix<T>& a)
+{ LapackServer<T> lps; TMatrix<T> ainv; lps.ComputeInverse(a, ainv);  return ainv; }
+
+/*! \ingroup LinAlg
+    \fn LapackLeastSquareSolveSVD_DC
+    \brief Solves the linear least squares problem A*X = B by SVD
+*/
+template <class T>
+inline int LapackLeastSquareSolveSVD_DC(TMatrix<T>& a,TMatrix<T>& b,TVector<r_8>& s,int_4& rank,r_8 rcond=-1.)
+{ LapackServer<T> lps; return( lps.LeastSquareSolveSVD_DC(a,b,s,rank,rcond) );  }
+
+/*! \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) ); }
+
+
+/*! \ingroup LinAlg
+    \fn LapackSVD_DC(TMatrix<T>&, TVector<r_8>&, TMatrix<T>&, TMatrix<T>&)
+    \brief SVD decomposition DC using LapackServer. 
+*/
+template <class T>
+inline int LapackSVD_DC(TMatrix<T>& a, TVector<r_8>& s, TMatrix<T>& u, TMatrix<T>& vt)
+{ LapackServer<T> lps; return( lps.SVD_DC(a, s, u, vt) ); }
+
+
+/*! \ingroup LinAlg
+    \fn LapackEigenSym(TArray<T>&, TArray<T> &)
+    \brief Compute the eigenvalues and eigenvectors of A (symetric or hermitian). 
+*/
+template <class T>
+inline int LapackEigenSym(TArray<T>& a, TVector<r_8>& b, bool eigenvector=true)
+{ LapackServer<T> lps; return( lps.LapackEigenSym(a,b,eigenvector) );  }
+
+/*! \ingroup LinAlg
+    \fn LapackEigen(TArray<T>&, TArray<T> &)
+    \brief Compute the eigenvalues and (right) eigenvectors of A (general square matrix). 
+*/
+template <class T>
+inline int LapackEigen(TArray<T>& a, TVector< complex<r_8> >& eval, TMatrix<T>& evec, bool eigenvector=true)
+{ LapackServer<T> lps; return( lps.LapackEigen(a,eval,evec,eigenvector) );  }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/LinAlg/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/objlist.list	(revision 3445)
@@ -0,0 +1,1 @@
+intflapack.o
Index: /tags/V_Nov2007/SophyaExt/LinAlg/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libextsophya.so
Index: /tags/V_Nov2007/SophyaExt/LinAlg/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/LinAlg/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/LinAlg/smakefile	(revision 3445)
@@ -0,0 +1,40 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libLinAlg.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)intflapack.o
+	rm -f $(SOPHYALIBP)libLinAlg.a
+ 
+$(SOPHYALIBP)libLinAlg.a : $(SOPHYAOBJP)intflapack.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)intflapack.o: intflapack.cc \
+  $(SOPHYAINCP)sopnamsp.h intflapack.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)tmatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  intflapack.cc
+ 
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile	(revision 3445)
@@ -0,0 +1,25 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libXAstroPack.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)mollweide.o $(SOPHYAOBJP)tstmollweide.o $(SOPHYAOBJP)tstxastro.o $(SOPHYAOBJP)xastropack.o $(SOPHYAOBJP)magfield.o
+	rm -f $(SOPHYALIBP)libXAstroPack.a
+ 
+$(SOPHYALIBP)libXAstroPack.a : $(SOPHYAOBJP)magfield.o $(SOPHYAOBJP)mollweide.o $(SOPHYAOBJP)xastropack.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)mollweide.o: mollweide.cc $(SOPHYAINCP)sopnamsp.h \
+  mollweide.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mollweide.cc
+ 
+$(SOPHYAOBJP)xastropack.o: xastropack.cc \
+  $(SOPHYAINCP)sopnamsp.h xastropack.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)XAstro/astro.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xastropack.cc
+ 
+$(SOPHYAOBJP)magfield.o: magfield.c magfield.h
+	$(CCOMPILE) -o $@  magfield.c
+ 
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/Makefile.mgr	(revision 3445)
@@ -0,0 +1,17 @@
+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/astro.h
+$(OBJ)magfield.o: magfield.c magfield.h
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest	(revision 3445)
@@ -0,0 +1,20 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+all: tstxastro tstmollweide
+
+clean:
+	rm -f *.o tstxastro tstmollweide mollw.data mollw2.data
+
+#---------------------
+tstxastro: tstxastro.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ tstxastro.o $(SOPEXTLIBP) -L$(SOPHYALIBP) -lXAstroPack -lxastro -lc -lm
+
+tstxastro.o: tstxastro.cc
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@ tstxastro.cc
+
+#---------------------
+tstmollweide: tstmollweide.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ tstmollweide.o $(SOPEXTLIBP) -L$(SOPHYALIBP) -lXAstroPack -lxastro -lc -lm
+
+tstmollweide.o: tstmollweide.cc
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@ tstmollweide.cc
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/Maketest.mgr	(revision 3445)
@@ -0,0 +1,24 @@
+MODULECXXREPNAME :=  CmvTests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYABASEREP)/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_Nov2007/SophyaExt/XAstroPack/exclude
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/exclude	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/exclude	(revision 3445)
@@ -0,0 +1,2 @@
+tstxastro.cc
+tstmollweide.cc
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/extlib_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/extlib_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/extlib_list	(revision 3445)
@@ -0,0 +1,1 @@
+xastro
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/extslb_list
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/extslb_list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/extslb_list	(revision 3445)
@@ -0,0 +1,1 @@
+xastro
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/magfield.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/magfield.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/magfield.c	(revision 3445)
@@ -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_Nov2007/SophyaExt/XAstroPack/magfield.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/magfield.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/magfield.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/XAstroPack/mollweide.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/mollweide.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/mollweide.cc	(revision 3445)
@@ -0,0 +1,140 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "sopnamsp.h"
+#include "mollweide.h"
+
+/*! \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);
+
+ 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);
+}
+
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/mollweide.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/mollweide.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/mollweide.h	(revision 3445)
@@ -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_Nov2007/SophyaExt/XAstroPack/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/objlist.list	(revision 3445)
@@ -0,0 +1,3 @@
+magfield.o
+mollweide.o
+xastropack.o
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libextsophya.so
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/smakefile	(revision 3445)
@@ -0,0 +1,25 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libXAstroPack.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)mollweide.o $(SOPHYAOBJP)tstmollweide.o $(SOPHYAOBJP)tstxastro.o $(SOPHYAOBJP)xastropack.o $(SOPHYAOBJP)magfield.o
+	rm -f $(SOPHYALIBP)libXAstroPack.a
+ 
+$(SOPHYALIBP)libXAstroPack.a : $(SOPHYAOBJP)magfield.o $(SOPHYAOBJP)mollweide.o $(SOPHYAOBJP)xastropack.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+ 
+$(SOPHYAOBJP)mollweide.o: mollweide.cc $(SOPHYAINCP)sopnamsp.h \
+  mollweide.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mollweide.cc
+ 
+$(SOPHYAOBJP)xastropack.o: xastropack.cc \
+  $(SOPHYAINCP)sopnamsp.h xastropack.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)XAstro/astro.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xastropack.cc
+ 
+$(SOPHYAOBJP)magfield.o: magfield.c magfield.h
+	$(CCOMPILE) -o $@  magfield.c
+ 
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/tstmollweide.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/tstmollweide.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/tstmollweide.cc	(revision 3445)
@@ -0,0 +1,39 @@
+//#define TEST_MOLLWEIDE
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "sopnamsp.h"
+#include "mollweide.h"
+
+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;
+
+ 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\n",tvrai,tcalc,a,tcalc-tvrai);
+ }
+ printf("Maximum difference: %e for t=%.10e=Pi/2-%.10e\n",tll,txy,M_PI_2-txy);
+ if(file) fclose(file);
+
+ 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);
+ return 0;
+}
Index: /tags/V_Nov2007/SophyaExt/XAstroPack/tstxastro.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/tstxastro.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/tstxastro.cc	(revision 3445)
@@ -0,0 +1,118 @@
+// Test des possibilites de xastropack
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <string.h>
+#include <math.h>
+#include "sopnamsp.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_Nov2007/SophyaExt/XAstroPack/xastropack.cc
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/xastropack.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/xastropack.cc	(revision 3445)
@@ -0,0 +1,831 @@
+#include <math.h>
+#include <stdio.h>
+#include "sopnamsp.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,PLCode 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_Nov2007/SophyaExt/XAstroPack/xastropack.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XAstroPack/xastropack.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XAstroPack/xastropack.h	(revision 3445)
@@ -0,0 +1,311 @@
+#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"
+#undef mjd
+#undef lat
+#undef lng
+#undef tz
+#undef temp
+#undef pressure
+#undef elev
+#undef dip
+#undef epoch
+#undef tznm
+#undef mjed
+#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);
+inline unsigned long CoordConvertToStd(unsigned long typ,double &coord1,double &coord2)
+       {return CoordConvertToStd(typ,&coord1,&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);
+inline void ToCoLat(double &val,unsigned long typ)
+       {ToCoLat(&val,typ);}
+
+void InRangeLat(double* val,unsigned long typ);
+inline void InRangeLat(double &val,unsigned long typ)
+       {InRangeLat(&val,typ);}
+
+void InRangeCoLat(double* val,unsigned long typ);
+inline void InRangeCoLat(double &val,unsigned long typ)
+       {InRangeCoLat(&val,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)
+             {val-=range*floor(val/range);}
+
+inline void InRange(double *val,double range,double vmax)
+         {InRange(val,range); if(*val>vmax) *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);
+inline void DatefrMJD(double mjd,double &dy,int &mn,int &yr)
+       {DatefrMJD(mjd,&dy,&mn,&yr);}
+
+double YearfrMJD(double mjd);
+
+double MJDfrYear(double yr);
+
+void YDfrMJD(double mjd,double *dy,int *yr);
+inline void YDfrMJD(double mjd,double &dy,int &yr)
+       {YDfrMJD(mjd,&dy,&yr);}
+
+int IsLeapYear(int y);
+
+int DayOrder(double mjd,int *dow);
+inline int DayOrder(double mjd,int &dow)
+       {return DayOrder(mjd,&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);
+inline void HMSfrHdec(double hd,int &h,int &mn,double &s)
+       {HMSfrHdec(hd,&h,&mn,&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 Precess(double mjd1,double mjd2,double ra1,double dec1,double &ra2,double &dec2)
+       {Precess(mjd1,mjd2,ra1,dec1,&ra2,&dec2);}
+
+inline void PrecessInPlace(double mjd1,double mjd2,double* ra,double* dec) {
+  double ra1=*ra, dec1=*dec;
+  Precess(mjd1,mjd2,ra1,dec1,ra,dec);
+}
+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);
+inline void EqtoGal(double mjd,double ra,double dec,double &glng,double &glat)
+       {EqtoGal(mjd,ra,dec,&glng,&glat);}
+
+
+void GaltoEq(double mjd,double glng,double glat,double *ra,double *dec);
+inline void GaltoEq(double mjd,double glng,double glat,double &ra,double &dec)
+       {GaltoEq( mjd, glng, glat, &ra, &dec);}
+
+void EqHtoHor(double geolat,double ha,double dec,double *az,double *alt);
+inline void EqHtoHor(double geolat,double ha,double dec,double &az,double &alt)
+       {EqHtoHor( geolat, ha, dec, &az, &alt);}
+
+void HortoEqH(double geolat,double az,double alt,double *ha,double *dec);
+inline void HortoEqH(double geolat,double az,double alt,double &ha,double &dec)
+       {HortoEqH( geolat, az, alt, &ha, &dec);}
+
+void EqtoHor(double geolat,double lst,double ra,double dec,double *az,double *alt);
+inline void EqtoHor(double geolat,double lst,double ra,double dec,double &az,double &alt)
+       {EqtoHor( geolat, lst, ra, dec, &az, &alt);}
+
+void HortoEq(double geolat,double lst,double az,double alt,double *ra,double *dec);
+inline void HortoEq(double geolat,double lst,double az,double alt,double &ra,double &dec)
+       {HortoEq( geolat, lst, az, alt, &ra, &dec);}
+
+void EqtoEcl(double mjd,double ra,double dec,double *eclng,double *eclat);
+inline void EqtoEcl(double mjd,double ra,double dec,double &eclng,double &eclat)
+       {EqtoEcl( mjd, ra, dec, &eclng, &eclat);}
+
+void EcltoEq(double mjd,double eclng,double eclat,double *ra,double *dec);
+inline void EcltoEq(double mjd,double eclng,double eclat,double &ra,double &dec)
+       {EcltoEq( mjd, eclng, eclat, &ra, &dec);}
+
+// ------------------- Positions des astres -------------------
+void SunPos(double mjd,double *eclsn,double *ecbsn,double *rsn);
+inline void SunPos(double mjd,double &eclsn,double &ecbsn,double &rsn)
+       {SunPos( mjd, &eclsn, &ecbsn, &rsn);}
+
+void MoonPos(double mjd,double *lmn,double *bmn,double *rho);
+inline void MoonPos(double mjd,double &lmn,double &bmn,double &rho)
+       {MoonPos( mjd, &lmn, &bmn, &rho);}
+
+void PlanetPos(double mjd,PLCode numplan,double *sunecl,double *sunecb,double *sundist
+               ,double *geodist,double *geoecl,double *geoecb
+	       ,double *diamang,double *mag);
+inline void PlanetPos(double mjd,PLCode numplan,double &sunecl,double &sunecb,double &sundist
+               ,double &geodist,double &geoecl,double &geoecb
+	       ,double &diamang,double &mag)
+       {PlanetPos(mjd,numplan,&sunecl,&sunecb,&sundist,&geodist,&geoecl,&geoecb,&diamang,&mag);}
+
+/*! \ingroup XAstroPack
+\brief Same as PlanetPos above with less arguments
+*/
+inline void PlanetPos(double mjd,PLCode 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);
+}
+inline void PlanetPos(double mjd,PLCode 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);
+}
+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);
+}
+inline void SaturnPos(double mjd,double &ecl,double &ecb,double &geodist,double &diamang)
+{
+  PlanetPos(mjd,SATURN,ecl,ecb,geodist,diamang);
+}
+
+#endif
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile	(revision 3445)
@@ -0,0 +1,183 @@
+include ../BuildMgr/sophyamake.inc
+
+all: libxastro.a
+
+clean:
+	rm -f libxastro.a *.o testxephem
+
+OBJASTRO = aa_hadec.o aberration.o actan.o airmass.o anomaly.o ap_as.o atlas.o auxil.o bdl.o chap95.o chap95_data.o circum.o comet.o constel.o dbfmt.o deep.o deltat.o earthsat.o eq_ecl.o eq_gal.o formats.o helio.o jupmoon.o libration.o magdecl.o marsmoon.o misc.o mjd.o moon.o mooncolong.o moonnf.o nutation.o obliq.o parallactic.o parallax.o plans.o plmoon.o plshadow.o precess.o reduce.o refract.o rings.o riset.o riset_cir.o satmoon.o sdp4.o sgp4.o sphcart.o sun.o thetag.o twobody.o umoon.o utc_gst.o vsop87.o vsop87_data.o
+
+libxastro.a : $(OBJASTRO)
+	$(AR) $(ARFLAGS) $@ $?
+
+aa_hadec.o: aa_hadec.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ aa_hadec.c
+
+aberration.o: aberration.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ aberration.c
+
+actan.o: actan.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ actan.c
+
+airmass.o: airmass.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ airmass.c
+
+anomaly.o: anomaly.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ anomaly.c
+
+ap_as.o: ap_as.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ ap_as.c
+
+atlas.o: atlas.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ atlas.c
+
+auxil.o: auxil.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ auxil.c
+
+bdl.o: bdl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ bdl.c
+
+chap95.o: chap95.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ chap95.c
+
+chap95_data.o: chap95_data.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ chap95_data.c
+
+circum.o: circum.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ circum.c
+
+comet.o: comet.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ comet.c
+
+constel.o: constel.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ constel.c
+
+dbfmt.o: dbfmt.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ dbfmt.c
+
+deep.o: deep.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ deep.c
+
+deltat.o: deltat.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ deltat.c
+
+earthsat.o: earthsat.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ earthsat.c
+
+eq_ecl.o: eq_ecl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ eq_ecl.c
+
+eq_gal.o: eq_gal.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ eq_gal.c
+
+formats.o: formats.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ formats.c
+
+helio.o: helio.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ helio.c
+
+jupmoon.o: jupmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ jupmoon.c
+
+libration.o: libration.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ libration.c
+
+magdecl.o: magdecl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ magdecl.c
+
+marsmoon.o: marsmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ marsmoon.c
+
+misc.o: misc.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ misc.c
+
+mjd.o: mjd.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ mjd.c
+
+moon.o: moon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ moon.c
+
+mooncolong.o: mooncolong.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ mooncolong.c
+
+moonnf.o: moonnf.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ moonnf.c
+
+nutation.o: nutation.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ nutation.c
+
+obliq.o: obliq.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ obliq.c
+
+parallactic.o: parallactic.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ parallactic.c
+
+parallax.o: parallax.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ parallax.c
+
+plans.o: plans.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plans.c
+
+plmoon.o: plmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plmoon.c
+
+plshadow.o: plshadow.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plshadow.c
+
+precess.o: precess.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ precess.c
+
+reduce.o: reduce.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ reduce.c
+
+refract.o: refract.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ refract.c
+
+rings.o: rings.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ rings.c
+
+riset.o: riset.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ riset.c
+
+riset_cir.o: riset_cir.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ riset_cir.c
+
+satmoon.o: satmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ satmoon.c
+
+sdp4.o: sdp4.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sdp4.c
+
+sgp4.o: sgp4.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sgp4.c
+
+sphcart.o: sphcart.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sphcart.c
+
+sun.o: sun.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sun.c
+
+thetag.o: thetag.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ thetag.c
+
+twobody.o: twobody.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ twobody.c
+
+umoon.o: umoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ umoon.c
+
+utc_gst.o: utc_gst.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ utc_gst.c
+
+vsop87.o: vsop87.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ vsop87.c
+
+vsop87_data.o: vsop87_data.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ vsop87_data.c
+
+testxephem: testxephem.o
+	$(CLINK) -o $@ testxephem.o -L./ -lxastro -lc -lm
+
+testxephem.o: testxephem.c astro.h
+	$(CCOMPILE) -o $@ testxephem.c
+
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.mgr	(revision 3445)
@@ -0,0 +1,27 @@
+include $(SOPHYABASEREP)/Include/MakefileUser.h
+
+all: libxastro.a
+
+clean:
+	rm -f libxastro.a
+	rm -f *.o testxephem
+
+install:
+	if [ ! -d $(EXTINCPATH)/XAstro ] ; then mkdir $(EXTINCPATH)/XAstro ; fi
+	rm -f $(EXTINCPATH)/XAstro/astro.h
+	rm -f $(EXTINCPATH)/XAstro/bdl.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 $@ $<
+
+testxephem: testxephem.o
+	$(LINK.c) -o $@ $^ -L$(EXTLIBPATH) -lxastro -lc -lm
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.org
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.org	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/Makefile.org	(revision 3445)
@@ -0,0 +1,93 @@
+# Makefile for the basic astronomy routines.
+# The idea is to compile and archive them into libastro.a
+
+# compiler and flags
+
+# gcc
+CC = gcc
+CFLAGS= -O2 -ffast-math -Wall
+
+# solaris
+# CC = cc
+# CFLAGS= -O
+
+# AIX
+# CC = xlc
+# CFLAGS= -O2 -qlanglvl=ansi -qarch=com -qmaxmem=16384
+
+# HP-UX
+# CC = cc
+# CFLAGS= -Aa -fast
+
+HS = astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h \
+	sattypes.h vector.h vsop87.h
+
+OBJS =			\
+	aa_hadec.o	\
+	aberration.o	\
+	actan.o		\
+	airmass.o	\
+	anomaly.o	\
+	ap_as.o		\
+	atlas.o		\
+	auxil.o		\
+	bdl.o		\
+	chap95.o	\
+	chap95_data.o	\
+	circum.o	\
+	comet.o		\
+	constel.o	\
+	dbfmt.o		\
+	deep.o		\
+	deltat.o	\
+	earthsat.o	\
+	eq_ecl.o	\
+	eq_gal.o	\
+	formats.o	\
+	helio.o		\
+	jupmoon.o	\
+	libration.o	\
+	magdecl.o	\
+	marsmoon.o	\
+	misc.o		\
+	mjd.o		\
+	moon.o		\
+	mooncolong.o	\
+	moonnf.o	\
+	nutation.o	\
+	obliq.o		\
+	parallax.o	\
+	parallactic.o	\
+	plans.o		\
+	plmoon.o	\
+	plshadow.o	\
+	precess.o	\
+	reduce.o	\
+	refract.o	\
+	rings.o		\
+	riset.o		\
+	riset_cir.o	\
+	satmoon.o	\
+	sdp4.o		\
+	sgp4.o		\
+	sphcart.o	\
+	sun.o		\
+	thetag.o	\
+	utc_gst.o	\
+	umoon.o		\
+	twobody.o	\
+	vsop87.o	\
+	vsop87_data.o
+
+libastro.a: $(HS) $(OBJS)
+	ar rv $@ $(OBJS)
+	ranlib $@
+
+libastro.so: $(HS) $(OBJS)
+	$(CC) -shared -o $@ $(OBJS)
+
+clobber:
+	rm -f *.o libastro.a
+
+# For RCS Only -- Do Not Edit
+# @(#) $RCSfile: Makefile.org,v $ $Date: 2004-06-15 16:54:11 $ $Revision: 1.1 $ $Name: not supported by cvs2svn $
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/aa_hadec.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/aa_hadec.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/aa_hadec.c	(revision 3445)
@@ -0,0 +1,77 @@
+/* function to convert between alt/az and ha/dec.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void aaha_aux (double lt, double x, double y, double *p, double *q);
+
+/* given geographical latitude (n+, radians), lt, 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 (
+double lt,
+double alt, double az,
+double *ha, double *dec)
+{
+	aaha_aux (lt, az, alt, ha, dec);
+	if (*ha > PI)
+	    *ha -= 2*PI;
+}
+
+/* given geographical (n+, radians), lt, 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 (
+double lt,
+double ha, double dec,
+double *alt, double *az)
+{
+	aaha_aux (lt, ha, dec, az, alt);
+}
+
+#ifdef NEED_GEOC
+/* given a geographic (surface-normal) latitude, phi, return the geocentric
+ * latitude, psi.
+ */
+double
+geoc_lat (
+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 (
+double lt,
+double x, double y,
+double *p, double *q)
+{
+	static double last_lt = -3434, slt, clt;
+	double cap, B;
+
+	if (lt != last_lt) {
+	    slt = sin(lt);
+	    clt = cos(lt);
+	    last_lt = lt;
+	}
+
+	solve_sphere (-x, PI/2-y, slt, clt, &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: 2006-11-22 13:53:27 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/aberration.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/aberration.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/aberration.c	(revision 3445)
@@ -0,0 +1,161 @@
+/* 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 at the 
+ * epoch of date.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.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 (double mj, double *x, double *y, double lsn, int mode);
+
+/* apply aberration correction to ecliptical coordinates *lam and *bet
+ * (in radians) for a given time m and handily supplied longitude of sun,
+ * lsn (in radians)
+ */
+void
+ab_ecl (double mj, double lsn, double *lam, double *bet)
+{
+	ab_aux(mj, lam, bet, lsn, AB_ECL_EOD);
+}
+
+/* apply aberration correction to equatoreal coordinates *ra and *dec
+ * (in radians) for a given time m and handily supplied longitude of sun,
+ * lsn (in radians)
+ */
+void
+ab_eq (double mj, double lsn, double *ra, double *dec)
+{
+#if defined(USE_MEEUS_AB_EQ)
+
+	/* this claims to account for earth orbit excentricity and is also
+	 * smooth clear to dec=90 but it does not work well backwards with
+	 * ap_as()
+	 */
+	ab_aux(mj, ra, dec, lsn, AB_EQ_EOD);
+
+#else /* use Montenbruck */
+
+	/* this agrees with Meeus to within 0.2 arcsec until dec gets larger
+	 * than about 89.9, then grows to 1as at 89.97. but it works very
+	 * smoothly with ap_as
+	 */
+	double x, y, z;		/* equatorial rectangular coords */
+	double vx, vy, vz;	/* aberration velocity in rectangular coords */
+	double L;		/* helio long of earth */
+	double cL;
+	double r;
+
+
+	sphcart (*ra, *dec, 1.0, &x, &y, &z);
+
+	L = 2*PI*(0.27908 + 100.00214*(mj-J2000)/36525.0);
+	cL = cos(L);
+	vx = -0.994e-4*sin(L);
+	vy = 0.912e-4*cL;
+	vz = 0.395e-4*cL;
+	x += vx;
+	y += vy;
+	z += vz;
+
+	cartsph (x, y, z, ra, dec, &r);
+
+#endif
+}
+
+/* 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 (double mj, double *x, double *y, double lsn, int mode)
+{
+	static double lastmj = -10000;
+	static double eexc;	/* earth orbit excentricity */
+	static double leperi;	/* ... and longitude of perihelion */
+	static char dirty = 1;	/* flag for cached trig terms */
+
+	if (mj != lastmj) {
+	    double T;		/* centuries since J2000 */
+
+	    T = (mj - J2000)/36525.;
+	    eexc = 0.016708617 - (42.037e-6 + 0.1236e-6 * T) * T;
+	    leperi = degrad(102.93735 + (0.71953 + 0.00046 * T) * T);
+	    lastmj = mj;
+	    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(mj, &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;
+		*dec += ddec;
+		radecrange (ra, dec);
+	    }
+	    break;
+
+	default:
+	    printf ("ab_aux: bad mode: %d\n", mode);
+	    abort();
+	    break;
+
+	} /* switch (mode) */
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: aberration.c,v $ $Date: 2006-11-22 13:53:27 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/actan.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/actan.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/actan.c	(revision 3445)
@@ -0,0 +1,67 @@
+#include <math.h>
+
+/* @(#) $Id: actan.c,v 1.6 2006-11-22 13:53:27 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: 2006-11-22 13:53:27 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/airmass.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/airmass.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/airmass.c	(revision 3445)
@@ -0,0 +1,26 @@
+#include <math.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 (
+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: 2006-11-22 13:53:27 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/anomaly.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/anomaly.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/anomaly.c	(revision 3445)
@@ -0,0 +1,63 @@
+/* improved by rclark@lpl.arizona.edu (Richard Clark) */
+
+#include <stdio.h>
+#include <math.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 (double ma, double s, double *nu, double *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: 2006-11-22 13:53:27 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/ap_as.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/ap_as.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/ap_as.c	(revision 3445)
@@ -0,0 +1,68 @@
+#include <string.h>
+#include <math.h>
+
+#include "astro.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 (Now *np, double Mjd, double *rap, double *decp)
+{
+	double r0 = *rap, d0 = *decp;
+	Obj o;
+	Now n;
+
+	/* as -> ap */
+	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;
+
+	/* then back to start for second order correction */
+	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 - r0;
+	*decp -= o.s_dec - d0;
+
+	radecrange (rap, decp);
+	precess (mjd, Mjd, rap, decp);
+	radecrange (rap, decp);
+}
+
+/* convert the given astrometric RA/Dec which are precessed to Mjd into
+ * apparent @ EOD IN PLACE.
+ */
+void
+as_ap (Now *np, double Mjd, double *rap, double *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: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/astro.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/astro.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/astro.h	(revision 3445)
@@ -0,0 +1,813 @@
+#ifndef _ASTRO_H
+#define _ASTRO_H
+
+#include <stdio.h>
+
+#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().
+ */
+typedef enum {
+    MERCURY,
+    VENUS,
+    MARS,
+    JUPITER,
+    SATURN,
+    URANUS,
+    NEPTUNE,
+    PLUTO,
+    SUN,
+    MOON,
+    NOBJ	/* total number of basic objects */
+} PLCode;
+
+/* moon constants for pl_moon */
+typedef enum {
+    X_PLANET = 0,			/* use to mean planet itself */
+    PHOBOS = NOBJ, DEIMOS,
+    IO, EUROPA, GANYMEDE, CALLISTO,
+    MIMAS, ENCELADUS, TETHYS, DIONE, RHEA, TITAN, HYPERION, IAPETUS,
+    ARIEL, UMBRIEL, TITANIA, OBERON, MIRANDA,
+    NBUILTIN
+} MCode;
+
+/* starting point for MJD calculations
+ */
+#define MJD0  2415020.0
+#define J2000 (2451545.0 - MJD0)      /* yes, 2000 January 1 at 12h */
+
+/* the Now and Obj typedefs.
+ * also, a few miscellaneous constants and declarations.
+ */
+
+#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) lt, >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 ep 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)
+#define	get_fmag(op)	((op)->f_mag / MAGSCALE)
+
+/* longest object name, including trailing '\0' */
+#define	MAXNM	21
+
+typedef unsigned char ObjType_t;
+typedef unsigned char ObjAge_t;
+typedef unsigned char byte;
+
+/* Obj is a massive union.
+ * many fields are in common so we use macros to make things a little easier.
+ */
+
+/* fields common to *all* structs in the Obj union */
+#define	OBJ_COMMON_FLDS							\
+    ObjType_t co_type;	/* current object type; see flags, below */	\
+    byte co_flags;	/* FUSER*... used by others */			\
+    ObjAge_t co_age;	/* update aging code; see db.c */		\
+    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 */			\
+    float co_az;	/* azimuth, >0 e of n, rads */			\
+    float 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 */
+
+/* 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, % */
+
+/* fields common to all fixed objects in the Obj union */
+#define	OBJ_FIXED_FLDS 							\
+    char  fo_spect[2];	/* spectral codes, if appropriate */		\
+    float fo_epoch;	/* eq of ra/dec and time when pm=0; mjd */ 	\
+    float fo_ra;	/* ra, rads, in epoch frame */ 			\
+    float fo_dec;	/* dec, rads, in epoch frame */ 		\
+    float fo_pmra;	/* ra proper motion, rads/day/cos(dec) */ 	\
+    float fo_pmdec;	/* dec proper motion, rads/day */ 		\
+    char  fo_class	/* object class */
+
+/* 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 struct {
+    OBJ_COMMON_FLDS;
+    OBJ_FIXED_FLDS;
+
+    /* following are for galaxies */
+    byte  fo_ratio;	/* minor/major diameter ratio. use s/get_ratio() */
+    byte  fo_pa;	/* position angle, E of N, rads. use s/get_pa() */
+} ObjF;
+
+/* true-orbit parameters of binary-star object type */
+typedef struct {
+    float bo_T;		/* epoch of periastron, years */
+    float bo_e;		/* eccentricity */
+    float bo_o;		/* argument of periastron, degress */
+    float bo_O;		/* longitude of node, degrees */
+    float bo_i;		/* inclination to plane of sky, degrees */
+    float bo_a;		/* semi major axis, arc secs */
+    float bo_P;		/* period, years */
+
+    /* companion position, computed by obj_cir() iff b_2compute */
+    float bo_pa;	/* position angle @ ep, rads E of N */
+    float bo_sep;	/* separation @ ep, arc secs */
+    float bo_ra;	/* geo/topo app/mean ra, rads */
+    float bo_dec;	/* geo/topo app/mean dec, rads */
+} BinOrbit;
+typedef struct {
+    float bp_ep;	/* epoch of pa/sep, year */
+    float bp_pa;	/* position angle @ ep, rads E of N */
+    float bp_sep;	/* separation @ ep, arc secs */
+
+    /* companion position, computed by obj_cir() iff b_2compute */
+    float bp_ra;	/* geo/topo app/mean ra, rads */
+    float bp_dec;	/* geo/topo app/mean dec, rads */
+} BinPos;
+#define MAXBINPOS 2	/* max discrete epochs to store when no elements */
+typedef struct {
+    OBJ_COMMON_FLDS;
+    OBJ_FIXED_FLDS;
+
+    byte b_2compute;	/* whether to compute secondary positions */
+    byte b_nbp;		/* number of b_bp[] or 0 to use b_bo */
+    short b_2mag;	/* secondary's magnitude * MAGSCALE */
+    char b_2spect[2];	/* secondary's spectrum */
+
+    /* either a real orbit or a set of discrete pa/sep */
+    union {
+	BinOrbit b_bo;			/* orbital elements */
+	BinPos b_bp[MAXBINPOS];		/* table of discrete positions */
+    } u;
+} ObjB;
+
+#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;
+    PLCode plo_code;		/* which planet */
+    MCode plo_moon;		/* which moon, or X_PLANET if planet */
+    char plo_evis, plo_svis;	/* if moon: whether visible from earth, sun */
+    double plo_x, plo_y, plo_z;	/* if moon: eq dist from center, planet radii */
+    double plo_aux1, plo_aux2;	/* various values, depending on type */
+} 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 */
+    float  eo_startok;	/* nominal first mjd this set is ok, else 0 */
+    float  eo_endok;	/* nominal last mjd this set is ok, else 0 */
+    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_startok;	/* nominal first mjd this set is ok, else 0 */
+    float  ho_endok;	/* nominal last mjd this set is ok, else 0 */
+    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_startok;	/* nominal first mjd this set is ok, else 0 */
+    float  po_endok;	/* nominal last mjd this set is ok, else 0 */
+    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_startok;	/* nominal first mjd this set is ok, else 0 */
+    float  eso_endok;	/* nominal last mjd this set is ok, else 0 */
+    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, plus proper motion */
+    ObjB    b;		/* bona fide binary stars (doubles are stored in f) */
+    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
+/* mark an object as circum calculation failed */
+#define NOCIRCUM	FUSER7
+
+/* 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_pmRA		f.fo_pmra
+#define	f_dec		f.fo_dec
+#define	f_pmdec		f.fo_pmdec
+#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_startok	e.eo_startok
+#define	e_endok		e.eo_endok
+#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_startok	h.ho_startok
+#define	h_endok		h.ho_endok
+#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_startok	p.po_startok
+#define	p_endok		p.po_endok
+#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_startok	es.eso_startok
+#define	es_endok	es.eso_endok
+#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
+
+#define	pl_code		pl.plo_code
+#define	pl_moon		pl.plo_moon
+#define	pl_evis		pl.plo_evis
+#define	pl_svis		pl.plo_svis
+#define	pl_x		pl.plo_x
+#define	pl_y		pl.plo_y
+#define	pl_z		pl.plo_z
+#define	pl_aux1		pl.plo_aux1
+#define	pl_aux2		pl.plo_aux2
+
+#define b_2compute	b.b_2compute
+#define b_2spect	b.b_2spect
+#define b_2mag		b.b_2mag
+#define b_bo		b.u.b_bo
+#define b_bp		b.u.b_bp
+#define b_nbp		b.b_nbp
+
+/* 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 add switch in obj_cir().
+ * N.B. UNDEFOBJ must be zero so new objects are undefinied by being zeroed.
+ * N.B. maintain the bitmasks too.
+ */
+enum ObjType {
+    UNDEFOBJ=0,
+    FIXED, BINARYSTAR, ELLIPTICAL, HYPERBOLIC, PARABOLIC, EARTHSAT, PLANET,
+    NOBJTYPES
+};
+
+/* types as handy bitmasks too */
+#define	OBJTYPE2MASK(t)	(1<<(t))
+#define	FIXEDM		OBJTYPE2MASK(FIXED)
+#define	BINARYSTARM	OBJTYPE2MASK(BINARYSTAR)
+#define	ELLIPTICALM	OBJTYPE2MASK(ELLIPTICAL)
+#define	HYPERBOLICM	OBJTYPE2MASK(HYPERBOLIC)
+#define	PARABOLICM	OBJTYPE2MASK(PARABOLIC)
+#define	EARTHSATM	OBJTYPE2MASK(EARTHSAT)
+#define	PLANETM		OBJTYPE2MASK(PLANET)
+#define	ALLM		(~0)
+
+/* 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)	(OBJTYPE2MASK((op)->o_type) & (m))
+
+/* any planet or its moons */
+#define	is_planet(op,p)	(is_type(op,PLANETM) && op->pl_code == (p))
+
+/* any solar system object */
+#define	is_ssobj(op)	is_type(op,PLANETM|HYPERBOLICM|PARABOLICM|ELLIPTICALM)
+
+
+
+/* natural satellite support */
+
+typedef struct {
+    char *full;		/* full name */
+    char *tag;		/* Roman numeral tag */
+    float x, y, z;	/* sky loc in planet radii: +x:east +y:south +z:front */
+    float ra, dec;	/* sky location in ra/dec */
+    float mag;		/* magnitude */
+    int evis;		/* whether geometrically visible from earth */
+    int svis;		/* whether in sun light */
+    int pshad;		/* whether moon is casting shadow on planet */
+    int trans;		/* whether moon is transiting */
+    float sx, sy;	/* shadow sky loc in planet radii: +x:east +y:south */
+} MoonData;
+
+/* separate set for each planet -- use in pl_moon */
+
+
+enum _marsmoons {
+    M_MARS = 0,					/* == X_PLANET */
+    M_PHOBOS, M_DEIMOS,
+    M_NMOONS					/* including planet at 0 */
+};
+
+enum _jupmoons {
+    J_JUPITER = 0,				/* == X_PLANET */
+    J_IO, J_EUROPA, J_GANYMEDE, J_CALLISTO,
+    J_NMOONS					/* including planet */
+};
+
+enum _satmoons {
+    S_SATURN = 0,				/* == X_PLANET */
+    S_MIMAS, S_ENCELADUS, S_TETHYS, S_DIONE,
+    S_RHEA, S_TITAN, S_HYPERION, S_IAPETUS,
+    S_NMOONS					/* including planet */
+};
+
+enum _uramoons {
+    U_URANUS = 0,				/* == X_PLANET */
+    U_ARIEL, U_UMBRIEL, U_TITANIA, U_OBERON, U_MIRANDA,
+    U_NMOONS					/* including planet */
+};
+
+#define	X_MAXNMOONS	S_NMOONS		/* N.B. chosen by hand */
+
+
+
+/* global function declarations */
+
+
+/* aa_hadec.c */
+extern void aa_hadec (double lt, double alt, double az, double *ha,
+    double *dec);
+extern void hadec_aa (double lt, double ha, double dec, double *alt,
+    double *az); 
+
+/* aberration.c */
+extern void ab_ecl (double m, double lsn, double *lam, double *bet);
+extern void ab_eq (double m, double lsn, double *ra, double *dec);
+
+/* airmass.c */
+extern void airmass (double aa, double *Xp);
+
+/* anomaly.c */
+extern void anomaly (double ma, double s, double *nu, double *ea);
+
+/* ap_as.c */
+extern void ap_as ( Now *np, double Mjd, double *rap, double *decp);
+extern void as_ap ( Now *np, double Mjd, double *rap, double *decp);
+
+/* atlas.c */
+extern char *um_atlas (double ra, double dec);
+extern char *u2k_atlas (double ra, double dec);
+extern char *msa_atlas (double ra, double dec);
+
+/* aux.c */
+extern double mm_mjed (Now *np);
+
+/* chap95.c */
+extern int chap95 (double m, int obj, double prec, double *ret);
+
+/* chap95_data.c */
+
+/* circum.c */
+extern int obj_cir (Now *np, Obj *op);
+
+/* comet.c */
+extern void comet (double m, double ep, double inc, double ap, double qp,
+    double om, double *lpd, double *psi, double *rp, double *rho, double *lam,
+    double *bet);
+
+/* constel.c */
+#define	NCNS	89
+extern int cns_pick (double r, double d, double e);
+extern int cns_id (char *abbrev);
+extern char *cns_name (int id);
+extern int cns_edges (double e, double **ra0p, double **dec0p, double **ra1p,
+    double **dec1p);
+extern int cns_list (double ra, double dec, double e, double rad, int ids[]);
+extern int cns_figure (int id, double e, double ra[],double dec[],int dcodes[]);
+extern int cns_loadfigs (FILE *fp, char msg[]);
+
+/* dbfmt.c */
+extern int db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm,
+    char whynot[]);
+extern void db_write_line (Obj *op, char *lp);
+extern int dbline_candidate (char line[]);
+extern int get_fields (char *s, int delim, char *fields[]);
+extern int db_tle (char *name, char *l1, char *l2, Obj *op);
+extern int dateRangeOK (Now *np, Obj *op);
+
+/* deltat.c */
+extern double deltat (double m);
+
+/* earthsat.c */
+extern int obj_earthsat (Now *np, Obj *op);
+
+/* eq_ecl.c */
+extern void eq_ecl (double m, double ra, double dec, double *lt,double *lg);
+extern void ecl_eq (double m, double lt, double lg, double *ra,double *dec);
+
+/* eq_gal.c */
+extern void eq_gal (double m, double ra, double dec, double *lt,double *lg);
+extern void gal_eq (double m, double lt, double lg, double *ra,double *dec);
+
+/* formats.c */
+extern int fs_sexa (char *out, double a, int w, int fracbase);
+extern int fs_date (char out[], int format, double jd);
+extern int f_scansexa (const char *str, double *dp);
+extern void f_sscandate (char *bp, int pref, int *m, double *d, int *y);
+
+/* helio.c */
+extern void heliocorr (double jd, double ra, double dec, double *hcp);
+
+/* jupmoon.c */
+extern void jupiter_data (double Mjd, char dir[], Obj *sop, Obj *jop,
+    double *jupsize, double *cmlI, double *cmlII, double *polera,
+    double *poledec, MoonData md[J_NMOONS]); 
+
+/* libration.c */
+extern void llibration (double JD, double *llatp, double *llonp);
+
+/* magdecl.c */
+extern int magdecl (double l, double L, double e, double y, char *dir,
+    double *dp, char *err);
+
+/* marsmoon.c */
+extern void marsm_data (double Mjd, char dir[], Obj *sop, Obj *mop,
+    double *marssize, double *polera, double *poledec, MoonData md[M_NMOONS]); 
+
+/* misc.c */
+extern void zero_mem (void *loc, unsigned len);
+extern int tickmarks (double min, double max, int numdiv, double ticks[]);
+extern int lc (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 (double h, double g, double rp, double rho, double rsn,
+    double *mp);
+extern int magdiam (int fmag, int magstp, double scale, double mag,
+    double size);
+extern void gk_mag (double g, double k, double rp, double rho, double *mp);
+extern double atod (char *buf);
+extern void solve_sphere (double A, double b, double cc, double sc,
+    double *cap, double *Bp);
+extern double delra (double dra);
+extern void now_lst (Now *np, double *lstp);
+extern void radec2ha (Now *np, double ra, double dec, double *hap);
+extern void gha (Now *np, Obj *op, double *ghap);
+extern char *obj_description (Obj *op);
+extern int is_deepsky (Obj *op);
+
+/* mjd.c */
+extern void cal_mjd (int mn, double dy, int yr, double *m);
+extern void mjd_cal (double m, int *mn, double *dy, int *yr);
+extern int mjd_dow (double m, int *dow);
+extern int isleapyear (int year);
+extern void mjd_dpm (double m, int *ndays);
+extern void mjd_year (double m, double *yr);
+extern void year_mjd (double y, double *m);
+extern void rnd_second (double *t);
+extern void mjd_dayno (double jd, int *yr, double *dy);
+extern double mjd_day (double jd);
+extern double mjd_hr (double jd);
+extern void range (double *v, double r);
+extern void radecrange (double *ra, double *dec);
+
+/* moon.c */
+extern void moon (double m, double *lam, double *bet, double *rho,
+    double *msp, double *mdp);
+
+/* mooncolong.c */
+extern void moon_colong (double jd, double lt, double lg, double *cp,
+    double *kp, double *ap, double *sp);
+
+/* moonnf.c */
+extern void moonnf (double mj, double *mjn, double *mjf);
+
+/* nutation.c */
+extern void nutation (double m, double *deps, double *dpsi);
+extern void nut_eq (double m, double *ra, double *dec);
+
+/* obliq.c */
+extern void obliquity (double m, double *eps);
+
+/* parallax.c */
+extern void ta_par (double tha, double tdec, double phi, double ht,
+    double *rho, double *aha, double *adec);
+
+/* parallactic.c */
+extern double parallacticLDA (double lt, double dec, double alt);
+extern double parallacticLHD (double lt, double ha, double dec);
+
+/* plans.c */
+extern void plans (double m, PLCode p, double *lpd0, double *psi0,
+    double *rp0, double *rho0, double *lam, double *bet, double *dia,
+    double *mag);
+
+/* plshadow.c */
+extern int plshadow (Obj *op, Obj *sop, double polera,
+    double poledec, double x, double y, double z, float *sxp, float *syp);
+
+/* plmoon_cir.c */
+extern int plmoon_cir (Now *np, Obj *moonop);
+extern int getBuiltInObjs (Obj **opp);
+extern void setMoonDir (char *dir);
+
+/* precess.c */
+extern void precess (double mjd1, double mjd2, double *ra, double *dec);
+
+/* reduce.c */
+extern void reduce_elements (double mjd0, double m, double inc0,
+    double ap0, double om0, double *inc, double *ap, double *om);
+
+/* refract.c */
+extern void unrefract (double pr, double tr, double aa, double *ta);
+extern void refract (double pr, double tr, double ta, double *aa);
+
+/* rings.c */
+extern void satrings (double sb, double sl, double sr, double el, double er,
+    double JD, double *etiltp, double *stiltp);
+
+/* riset.c */
+extern void riset (double ra, double dec, double lt, double dis,
+    double *lstr, double *lsts, double *azr, double *azs, int *status);
+
+/* riset_cir.c */
+extern void riset_cir (Now *np, Obj *op, double dis, RiseSet *rp);
+extern void twilight_cir (Now *np, double dis, double *dawn, double *dusk,
+    int *status);
+
+/* satmoon.c */
+extern void saturn_data (double Mjd, char dir[], Obj *eop, Obj *sop,
+    double *satsize, double *etilt, double *stlit, double *polera, 
+    double *poledec, MoonData md[S_NMOONS]); 
+
+/* sphcart.c */
+extern void sphcart (double l, double b, double r, double *x, double *y,
+    double *z);
+extern void cartsph (double x, double y, double z, double *l, double *b,
+    double *r);
+
+/* sun.c */
+extern void sunpos (double m, double *lsn, double *rsn, double *bsn);
+
+/* twobody.c */
+extern int vrc (double *v, double *r, double tp, double e, double q);
+
+/* umoon.c */
+extern void uranus_data (double Mjd, char dir[], Obj *sop, Obj *uop,
+    double *usize, double *polera, double *poledec, MoonData md[U_NMOONS]); 
+
+/* utc_gst.c */
+extern void utc_gst (double m, double utc, double *gst);
+extern void gst_utc (double m, double gst, double *utc);
+
+/* vsop87.c */
+extern int vsop87 (double m, int obj, double prec, double *ret);
+
+#endif /* _ASTRO_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: astro.h,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/atlas.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/atlas.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/atlas.c	(revision 3445)
@@ -0,0 +1,196 @@
+/* look up which star atlas an ra/dec is in.
+ * Urano and Mill contributed by Atsuo Ohki <ohki@gssm.otsuka.tsukuba.ac.jp>
+ * U2K by Robert Lane <roblane@alum.mit.edu>
+ *
+ * N.B. skylist.c assumes a certain max length for any returned string.
+ */
+ 
+#include <stdio.h>
+#include <string.h>
+
+#include "astro.h"
+
+/* for Millennium Star Atlas */
+static int msa_charts[] = {
+    /* 90*/  2, /* 84*/  4, /* 78*/  8, /* 72*/ 10, /* 66*/ 12,
+    /* 60*/ 14, /* 54*/ 16, /* 48*/ 20, /* 42*/ 20, /* 36*/ 22,
+    /* 30*/ 22, /* 24*/ 24, /* 18*/ 24, /* 12*/ 24, /*  6*/ 24,
+    /*  0*/ 24,
+    /* -6*/ 24, /*-12*/ 24, /*-18*/ 24, /*-24*/ 24, /*-30*/ 22,
+    /*-36*/ 22, /*-42*/ 20, /*-48*/ 20, /*-54*/ 16, /*-60*/ 14,
+    /*-66*/ 12, /*-72*/ 10, /*-78*/  8, /*-84*/  4, /*-90*/  2
+};
+
+/*
+ * find the chart number of Millennium Star Atlas and return pointer to static
+ * string describing location.
+ * 0 <= ra < 24;  -90 <= dec <= 90
+ */
+char *
+msa_atlas(double ra, double dec)
+{
+	static char buf[512];
+	int zone, band;
+	int i, p;
+
+	ra = radhr(ra);
+	dec = raddeg(dec);
+	buf[0] = 0;
+	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec)
+	    return (buf);
+	zone = (int)(ra/8.0);
+	band = -((int)(dec+((dec>=0)?3:-3))/6 - 15);
+	for (p=0, i=0; i <= band; i++)
+	    p += msa_charts[i];
+	i = (int)((ra - 8.0*zone) / (8.0/msa_charts[band]));
+	sprintf(buf, "V%d - P%3d", zone+1, p-i+zone*516);
+	return (buf);
+}
+
+/* for original Uranometria */
+static struct {
+    double l;
+    int n;
+} um_zones[] = {
+    /* 84 - 90 */ { 84.5,  2},
+    /* 72 - 85 */ { 72.5, 12},
+    /* 60 - 73 */ { 61.0, 20},
+    /* 49 - 62 */ { 50.0, 24},
+    /* 38 - 51 */ { 39.0, 30},
+    /* 27 - 40 */ { 28.0, 36},
+    /* 16 - 29 */ { 17.0, 45},
+    /*  5 - 18 */ {  5.5, 45},
+    /*  0 -  6 */ {  0.0, 45},
+		  {  0.0,  0}
+};
+
+/*
+ * find the chart number of Uranometria first edition and return pointer to
+ * static string describing location.
+ * 0 <= ra < 24;  -90 <= dec <= 90
+ */
+char *
+um_atlas(double ra, double dec)
+{
+	static char buf[512];
+	int band, south;
+	int p;
+	double w;
+
+	ra = radhr(ra);
+	dec = raddeg(dec);
+	buf[0] = 0;
+	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec)
+	    return (buf);
+	p = 0;
+	if (dec < 0.0) {
+	    dec = -dec;
+	    south = 1;
+	} else
+	    south = 0;
+	p = 1;
+	for (band=0; um_zones[band].n; band++) {
+	    if (um_zones[band].l <= dec)
+		break; 
+	    p += um_zones[band].n;
+	}
+	if (!um_zones[band].n)
+	    return (buf);
+	w = 24.0 / um_zones[band].n;
+	if (band) {
+	    ra += w/2.0;
+	    if (ra >= 24.0)
+		ra -= 24.0;
+	}
+	if (south && um_zones[band+1].n)
+	    p = 475 - p - um_zones[band].n;
+	if (south && band == 0) {
+	    /* south pole part is mis-ordered! */
+	    ra = 24.0 - ra;
+	}
+	sprintf(buf, "V%d - P%3d", south+1, p+(int)(ra/w));
+	return (buf);
+}
+
+/* for Uranometria 2000.0 */
+static struct {
+    double lowDec; 	/* lower dec cutoff */
+    int numZones;	/* number of panels (aka zones) */
+
+} u2k_zones[] = { /* array of book layout info */
+    /* 84 - 90 */ { 84.5,  1}, /* lower dec cutoff, # of panels in band */
+    /* 73 - 85 */ { 73.5,  6},
+    /* 62 - 74 */ { 62.0, 10},
+    /* 51 - 63 */ { 51.0, 12},
+    /* 40 - 52 */ { 40.0, 15},
+    /* 29 - 41 */ { 29.0, 18},
+    /* 17 - 30 */ { 17.0, 18},
+    /*  5 - 18 */ {  5.5, 20},
+    /*  0 -  6 */ {  0.0, 20},
+                  {  0.0,  0} /*numZones value in this line is a stopper.*/
+};
+
+/* find the chart number of Uranometria 2000.0 and return pointer to static
+ * string describing location.
+ * 0 <= ra < 24;  -90 <= dec <= 90
+ */
+char *
+u2k_atlas(double ra, double dec)
+{
+	static char buf[512];
+	static char err[] = "???";
+	int band; 		/* index to array */
+	int south;		/* flag for volume 2*/
+	int panel;		/* panel number */
+
+	ra = radhr(ra);
+	dec = raddeg(dec);
+	buf[0] = 0;
+	if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) {
+	    strcpy (buf, err);
+	    return (buf); /* range checking */
+	}
+
+	if (dec < 0.0) {
+	    dec = -dec;
+	    south = 1; /* South is mirror of North */
+	} else
+	    south = 0;
+
+	panel = 1;
+	band = 0;
+
+	/* scan u2k_zones for the correct band: */
+	while (u2k_zones[band].numZones != 0 && dec <= u2k_zones[band].lowDec ){
+	    panel += u2k_zones[band].numZones; /*accumulate total panels */
+	    band++ ;
+	}
+
+	if (!u2k_zones[band].numZones) { /* hit end of array with no match. */
+	    strcpy (buf, err);
+	    return (buf);
+	}
+
+	ra -= 12.0 / u2k_zones[band].numZones; /*offset by half-width of panel*/
+	if (ra >= 24.0)			/* reality check. shouldn't happen. */
+	    ra -= 24.0;
+
+	if (ra < 0.0)			/* offset could give negative ra */
+	    ra += 24.0;
+
+	if (south && u2k_zones[band+1].numZones)
+	    panel = 222 - panel - u2k_zones[band].numZones;
+
+	/* resultant panel number is accumulated panels in prior bands plus
+	 * ra's fraction of panels in dec's band. panel # goes up as ra goes
+	 * down.
+	 */
+	sprintf(buf, "V%d - P%3d", south+1,
+	panel+(int)(u2k_zones[band].numZones*(24.0 - ra)/24.0));
+
+	return (buf);
+}
+
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: atlas.c,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/auxil.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/auxil.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/auxil.c	(revision 3445)
@@ -0,0 +1,42 @@
+/* aux functions so programs besides XEphem can use this library.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "astro.h"
+#include "preferences.h"
+
+/* default preferences */
+static int prefs[NPREFS] = {
+    PREF_TOPO, PREF_METRIC, PREF_MDY, PREF_UTCTZ, PREF_HIPREC, PREF_NOMSGBELL,
+    PREF_PREFILL, PREF_TIPSON, PREF_CONFIRMON, PREF_SUN
+};
+
+/* called anytime we want to know a preference.
+ */
+int
+pref_get(Preferences pref)
+{
+	return (prefs[pref]);
+}
+
+/* call to force a certain preference, return the old setting.
+ */
+int
+pref_set (Preferences pref, int newp)
+{
+	int prior = pref_get(pref);
+	prefs[pref] = newp;
+	return (prior);
+}
+
+/* given an mjd, return it modified for terrestial dynamical time */
+double
+mm_mjed (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: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.c	(revision 3445)
@@ -0,0 +1,234 @@
+/* crack natural satellite files from BDL */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "astro.h"
+#include "bdl.h"
+
+typedef enum {I, F, NL} ScanType;
+#define	SCANFLD(f,w,vp)	if(readField(fp,f,w,(void *)vp,ynot)<0) return (-1)
+
+static int readField (FILE *fp, ScanType f, int w, void *ptr, char ynot[]);
+static int readRec (FILE *fp, double *t0, double cmx[], double cfx[],
+    double cmy[], double cfy[], double cmz[], double cfz[], char ynot[]);
+
+/* given a sequencial text file in BDL natural satellite ephemeris format and a
+ * JD, find the x/y/z positions of each satellite. store in the given arrays,
+ * assumed to have one entry per moon. values are planetocentric, +x east, +y
+ * north, +z away from earth, all in au. corrected for light time.
+ * return the number of satellites or -1 and reason in ymot[].
+ * files obtained from ftp://ftp.bdl.fr/pub/misc/satxyz.
+ */
+int
+read_bdl (FILE *fp, double jd, double *xp, double *yp, double *zp, char ynot[])
+{
+	int npla;
+	int nsat;
+	int idn[8];
+	double freq[8];
+	double delt[8];
+	double djj;
+	double cmx[6], cfx[4], cmy[6], cfy[4], cmz[6], cfz[4];
+	int ienrf;
+	int jan;
+	int reclen;
+	long os0;
+	double t0;
+	int i;
+
+	/* read header line */
+	SCANFLD (I, 2, &npla);
+	SCANFLD (I, 2, &nsat);
+	for (i = 0; i < nsat; i++)
+	    SCANFLD (I, 5, &idn[i]);
+	for (i = 0; i < nsat; i++)
+	    SCANFLD (F, 8, &freq[i]);
+	for (i = 0; i < nsat; i++)
+	    SCANFLD (F, 5, &delt[i]);
+	SCANFLD (I, 5, &ienrf);
+	SCANFLD (F, 15, &djj);
+	SCANFLD (I, 5, &jan);
+	SCANFLD (NL, 0, NULL);
+
+	/* record position of first record */
+	os0 = ftell (fp);
+
+	/* read first record to get length */
+	reclen = readRec (fp, &t0, cmx, cfx, cmy, cfy, cmz, cfz, ynot);
+	if (reclen < 0)
+	    return (-1);
+
+	/* compute location of each satellite */
+	for (i = 0; i < nsat; i++) {
+	    int id = (int)floor((jd-djj)/delt[i]) + idn[i] - 2;
+	    long os = os0 + id*reclen;
+	    double t1, anu, tau, tau2, at;
+	    double tbx, tby, tbz;
+
+	    if (fseek (fp, os, SEEK_SET) < 0) {
+		sprintf (ynot, "Seek error to %ld for rec %d", os, id);
+		return (-1);
+	    }
+
+	    if (readRec (fp, &t0, cmx, cfx, cmy, cfy, cmz, cfz, ynot) < 0)
+		return (-1);
+
+	    t1 = floor(t0) + 0.5;
+	    anu = freq[i];
+	    tau = jd - t1;
+	    tau2 = tau * tau;
+	    at = tau*anu;
+
+	    tbx = cmx[0]+cmx[1]*tau+cmx[2]*sin(at+cfx[0])
+			    +cmx[3]*tau*sin(at+cfx[1])
+			    +cmx[4]*tau2*sin(at+cfx[2])
+			    +cmx[5]*sin(2*at+cfx[3]);
+	    tby = cmy[0]+cmy[1]*tau+cmy[2]*sin(at+cfy[0])
+			    +cmy[3]*tau*sin(at+cfy[1])
+			    +cmy[4]*tau2*sin(at+cfy[2])
+			    +cmy[5]*sin(2*at+cfy[3]);
+	    tbz = cmz[0]+cmz[1]*tau+cmz[2]*sin(at+cfz[0])
+			    +cmz[3]*tau*sin(at+cfz[1])
+			    +cmz[4]*tau2*sin(at+cfz[2])
+			    +cmz[5]*sin(2*at+cfz[3]);
+
+	    xp[i] = tbx*1000./149597870.;
+	    yp[i] = tby*1000./149597870.;
+	    zp[i] = tbz*1000./149597870.;
+	}
+
+	return (nsat);
+}
+
+/* read one field.
+ * return 0 if ok else -1
+ * N.B. this is enforce width, without skipping leading blanks.
+ */
+static int
+readField (FILE *fp, ScanType f, int width, void *ptr, char ynot[])
+{
+	char buf[128];
+	char *bp;
+
+	if (buf && width != (int)fread (buf, 1, width, fp)) {
+	    if (ferror(fp)) strcpy (ynot, "IO error");
+	    else if (feof(fp)) strcpy (ynot, "unexpected EOF");
+	    else strcpy (ynot, "short file");
+	    return (-1);
+	}
+
+	buf[width] = '\0';
+	switch (f) {
+	case I:
+	    *(int *)ptr = atoi (buf);
+	    break;
+	case F:
+	    bp = strchr (buf, 'D');
+	    if (bp)
+		*bp = 'e';
+	    *(double *)ptr = atof (buf);
+	    break;
+	case NL:
+	    fgets (buf, sizeof(buf), fp);
+	    break;
+	default:
+	    sprintf (ynot, "Bug! format = %d", f);
+	    return (-1);
+	}
+	return (0);
+}
+
+/* read one satellite record.
+ * return number of chars read else -1.
+ */
+static int
+readRec (FILE *fp, double *t0, double cmx[], double cfx[], double cmy[],
+double cfy[], double cmz[], double cfz[], char ynot[])
+{
+
+	long pos0, pos1;
+	int isat, idx;
+	int ldat1, ldat2;
+	int i;
+
+	pos0 = ftell (fp);
+
+	SCANFLD (I, 1, &isat);
+	SCANFLD (I, 5, &idx);
+	SCANFLD (I, 8, &ldat1);
+	SCANFLD (I, 8, &ldat2);
+	SCANFLD (F, 9, t0);
+	for (i = 0; i < 6; i++)
+	    SCANFLD (F, 17, &cmx[i]);
+	for (i = 0; i < 4; i++)
+	    SCANFLD (F, 17, &cfx[i]);
+	for (i = 0; i < 6; i++)
+	    SCANFLD (F, 17, &cmy[i]);
+	for (i = 0; i < 4; i++)
+	    SCANFLD (F, 17, &cfy[i]);
+	for (i = 0; i < 6; i++)
+	    SCANFLD (F, 17, &cmz[i]);
+	for (i = 0; i < 4; i++)
+	    SCANFLD (F, 17, &cfz[i]);
+	SCANFLD (NL, 0, NULL);
+
+	pos1 = ftell (fp);
+
+	return (pos1 - pos0);
+}
+
+
+#ifdef TEST_IT
+/* stand-alone test program.
+ * for example, compare
+ *   a.out jupiter.9910 2451910.50000
+ * with
+ *   satxyz2
+ *     jup.dir.9910
+ *     2001 1 1 0 0 0
+ *     1 0 0 0
+ *     1
+ */
+int
+main (int ac, char *av[])
+{
+	double x[10], y[10], z[10];
+	char ynot[1024];
+	double jd;
+	char *fn;
+	FILE *fp;
+	int nm;
+	int i;
+
+	if (ac != 3) {
+	    fprintf (stderr, "Usage: %s <filename> <jd>\n", av[0]);
+	    abort();
+	}
+	fn = av[1];
+	jd = atof (av[2]);
+
+	fp = fopen (fn, "r");
+	if (!fp) {
+	    perror (fn);
+	    abort();
+	}
+
+	nm = read_bdl (fp, jd, x, y, z, ynot);
+	if (nm < 0) {
+	    fprintf (stderr, "%s\n", ynot);
+	    abort();
+	}
+
+	for (i = 0; i < nm; i++)
+	    printf (" X= %19.11E Y= %19.11E Z= %19.11E\n", x[i], y[i], z[i]);
+
+	return (0);
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: bdl.c,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/bdl.h	(revision 3445)
@@ -0,0 +1,6 @@
+extern int read_bdl (FILE *fp, double jd, double *xp, double *yp, double *zp,
+    char ynot[]);
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: bdl.h,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.c	(revision 3445)
@@ -0,0 +1,174 @@
+/* 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 "astro.h"
+#include "chap95.h"
+
+#define CHAP_MAXTPOW	2	/* NB: valid for all 5 outer planets */
+
+/* chap95()
+ *
+ * input:
+ *	m	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 (double m, 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 (m < CHAP_BEGIN || m > 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 = (m - 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: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95.h	(revision 3445)
@@ -0,0 +1,68 @@
+/* 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[];
+
+extern int chap95 (double m, int obj, double prec, double *ret);
+
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: chap95.h,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95_data.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95_data.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/chap95_data.c	(revision 3445)
@@ -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: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/circum.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/circum.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/circum.c	(revision 3445)
@@ -0,0 +1,863 @@
+/* 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>
+#include <stdlib.h>
+
+#include "astro.h"
+#include "preferences.h"
+
+
+static int obj_planet (Now *np, Obj *op);
+static int obj_binary (Now *np, Obj *op);
+static int obj_2binary (Now *np, Obj *op);
+static int obj_fixed (Now *np, Obj *op);
+static int obj_elliptical (Now *np, Obj *op);
+static int obj_hyperbolic (Now *np, Obj *op);
+static int obj_parabolic (Now *np, Obj *op);
+static int sun_cir (Now *np, Obj *op);
+static int moon_cir (Now *np, Obj *op);
+static double solveKepler (double M, double e);
+static void binaryStarOrbit (double t, double T, double e, double o, double O,
+    double i, double a, double P, double *thetap, double *rhop);
+static void cir_sky (Now *np, double lpd, double psi, double rp, double *rho,
+    double lam, double bet, double lsn, double rsn, Obj *op);
+static void cir_pos (Now *np, double bet, double lam, double *rho, Obj *op);
+static void elongation (double lam, double bet, double lsn, double *el);
+static void deflect (double mjd1, double lpd, double psi, double rsn,
+    double lsn, double rho, double *ra, double *dec);
+static double h_albsize (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 (Now *np, Obj *op)
+{
+	op->o_flags &= ~NOCIRCUM;
+	switch (op->o_type) {
+	case BINARYSTAR: return (obj_binary (np, op));
+	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 %s\n", op->o_type, op->o_name);
+	    abort();
+	    return (-1);	/* just for lint */
+	}
+}
+
+static int
+obj_planet (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 */
+	PLCode p;
+
+	/* validate code and check for a few special cases */
+	p = op->pl_code;
+	if (p == SUN)
+	    return (sun_cir (np, op));
+	if (p == MOON)
+	    return (moon_cir (np, op));
+	if (op->pl_moon != X_PLANET)
+	    return (plmoon_cir (np, op));
+	if (p < 0 || p > MOON) {
+	    printf ("unknown planet code: %d\n", p);
+	    abort();
+	}
+
+	/* planet itself */
+
+	/* 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_binary (Now *np, Obj *op)
+{
+	/* always compute circumstances of primary */
+	if (obj_fixed (np, op) < 0)
+	    return (0);
+
+	/* compute secondary only if requested, and always reset request flag */
+	if (!op->b_2compute)
+	    return (0);
+	op->b_2compute = 0;
+	return (obj_2binary (np, op));
+}
+
+/* compute position of secondary component of a BINARYSTAR */
+static int
+obj_2binary (Now *np, Obj *op)
+{
+	if (op->b_nbp > 0) {
+	    /* we just have discrete pa/sep, project each from primary */
+	    int i;
+	    for (i = 0; i < op->b_nbp; i++) {
+		BinPos *bp = &op->b_bp[i];
+		bp->bp_dec = op->s_dec + bp->bp_sep*cos(bp->bp_pa);
+		bp->bp_ra = op->s_ra + bp->bp_sep*sin(bp->bp_pa)/cos(op->s_dec);
+	    }
+	} else {
+	    BinOrbit *bp = &op->b_bo;
+	    double t, theta, rho;
+
+	    mjd_year (mjd, &t);
+	    binaryStarOrbit (t, bp->bo_T, bp->bo_e, bp->bo_o, bp->bo_O,
+				bp->bo_i, bp->bo_a, bp->bo_P, &theta, &rho);
+	    bp->bo_pa = (float)theta;
+	    bp->bo_sep = (float)rho;
+	    rho = degrad(rho/3600.);	/* arc secs to rads */
+	    bp->bo_dec = op->s_dec + rho*cos(theta);
+	    bp->bo_ra =  op->s_ra  + rho*sin(theta)/cos(op->s_dec);
+	}
+
+	return (0);
+}
+
+/* from W. M. Smart */
+static void
+binaryStarOrbit (
+double t,		/* desired ephemeris epoch, year */
+double T,		/* epoch of periastron, year */
+double e,		/* eccentricity */
+double o,		/* argument of periastron, degrees */
+double O,		/* ascending node, degrees */
+double i,		/* inclination, degrees */
+double a,		/* semi major axis, arcsecs */
+double P,		/* period, years */
+double *thetap,		/* position angle, rads E of N */
+double *rhop)		/* separation, arcsecs */
+{
+	double M, E, cosE, nu, cosnu, r, rho, theta;
+
+	/* find mean anomaly, insure 0..2*PI */
+	M = 2*PI/P*(t-T);
+	range (&M, 2*PI);
+
+	/* solve for eccentric anomaly */
+	E = solveKepler (M, e);
+	cosE = cos(E);
+
+	/* find true anomaly and separation */
+	cosnu = (cosE - e)/(1.0 - e*cosE);
+	r = a*(1.0 - e*e)/(1.0 + e*cosnu);
+	nu = acos(cosnu);
+	if (E > PI)
+	    nu = -nu;
+
+	/* project onto sky */
+	theta = atan(tan(nu+degrad(o))*cos(degrad(i))) + degrad(O);
+	rho = r*cos(nu+degrad(o))/cos(theta-degrad(O));
+	if (rho < 0) {
+	    theta += PI;
+	    rho = -rho;
+	}
+	range (&theta, 2*PI);
+
+	*thetap = theta;
+	*rhop = rho;
+}
+
+/* solve kepler equation using Newton-Raphson search.
+ * Charles and Tatum have shown it always converges starting with PI.
+ */
+static double
+solveKepler (double M, double e)
+{
+	double E, Eprime = PI;
+
+	do {
+	    double cosE = cos(Eprime);
+	    E = Eprime;
+	    Eprime = (M - e*(E*cosE - sin(E)))/(1.0 - e*cosE);
+	} while (fabs(E-Eprime) > 1e-7);
+
+	return (Eprime);
+}
+
+static int
+obj_fixed (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 equinox of date */
+	double rpm, dpm; 	/* astrometric ra and dec with PM to now */
+	double lst;
+
+	/* on the assumption that the user will stick with their chosen display
+	 * epoch for a while, we move the defining values to match and avoid
+	 * precession for every call until it is changed again.
+	 * N.B. only compare and store jd's to lowest precission (f_epoch).
+	 * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err
+	 */
+	if (epoch != EOD && (float)epoch != (float)op->f_epoch) {
+	    double pr = op->f_RA, pd = op->f_dec, fe = (float)epoch;
+	    /* first bring back to 2k */
+	    precess (op->f_epoch, J2000, &pr, &pd);
+	    pr += op->f_pmRA*(J2000-op->f_epoch);
+	    pd += op->f_pmdec*(J2000-op->f_epoch);
+	    /* then to epoch */
+	    pr += op->f_pmRA*(fe-J2000);
+	    pd += op->f_pmdec*(fe-J2000);
+	    precess (J2000, fe, &pr, &pd);
+	    op->f_RA = (float)pr;
+	    op->f_dec = (float)pd;
+	    op->f_epoch = (float)fe;
+	}
+
+	/* apply proper motion .. assume pm epoch reference equals equinox */
+	rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch);
+	dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch);
+
+	/* set ra/dec to astrometric @ equinox of date */
+	ra = rpm;
+	dec = dpm;
+	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 equinox (usually different from mjd)
+	     */
+	    op->s_ra = rpm;
+	    op->s_dec = dpm;
+	}
+
+	/* 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 (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);
+	    if (vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e)) < 0)
+		op->o_flags |= NOCIRCUM;
+	    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 (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 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);
+
+	/* 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;
+	    if (vrc (&nu, &rp, tp, op->h_e, op->h_qp) < 0)
+		op->o_flags |= NOCIRCUM;
+	    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 (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 (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 (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. */
+	i = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))) 
+					+ 5*log10(edistau/.0025) /* dist */;
+	set_smag (op, i);
+
+	/* 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 (
+Now *np,
+double lpd,		/* heliocentric ecliptic longitude */
+double psi,		/* heliocentric ecliptic lat */
+double rp,		/* dist from sun */
+double *rho,		/* dist from earth: in as geo, back as geo or topo */
+double lam,		/* true geocentric ecliptic long */
+double bet,		/* true geocentric ecliptic lat */
+double lsn,		/* true geoc lng of sun */
+double rsn,		/* 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 equinox:
+ *   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 (
+Now *np,
+double bet,	/* geo lat (mean ecliptic of date) */
+double lam,	/* geo 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 equinox */
+{
+	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 (double lam, double bet, double 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 (
+double mjd1,		/* equinox */
+double lpd, double psi,	/* heliocentric ecliptical long / lat */
+double rsn, double lsn,	/* distance and longitude of sun */
+double rho,		/* geocentric distance */
+double *ra, double *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,
+	 * not obscured by the sun's disc (radius 0.25 deg) and farther away
+	 * than the sun.
+	 *
+	 * 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) || rho<rsn) 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 (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: 2006-11-22 13:53:28 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/comet.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/comet.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/comet.c	(revision 3445)
@@ -0,0 +1,83 @@
+#include <math.h>
+
+#include "astro.h"
+
+/* given a modified Julian date, mj, and a set of heliocentric parabolic
+ * orbital elements referred to the epoch of date (mj):
+ *   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 (double mj, double ep, double inc, double ap, double qp, double om,
+double *lpd, double *psi, double *rp, double *rho, double *lam, double *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 = ((mj-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 (mj, &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: 2006-11-22 13:53:28 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/compare_with_xephem.csh
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/compare_with_xephem.csh	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/compare_with_xephem.csh	(revision 3445)
@@ -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 '> $SOPHYASOURCE/XephemAstroLib/compare_with_xephem.csh'
+  exit -1
+endif
+
+set dir = $SOPHYASOURCE/XephemAstroLib/
+set log = `pwd`/compare.log
+
+rm -f $log; touch $log
+
+echo ======================= NOUVEAU REPERTOIRE `pwd` >>& $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_Nov2007/SophyaExt/XephemAstroLib/constel.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/constel.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/constel.c	(revision 3445)
@@ -0,0 +1,1803 @@
+/* code to handle constellation boundaries and figures */
+
+/*
+Constellation boundaries:
+
+ Primary reference:
+
+  METHOD TO DETERMINE THE CONSTELLATION IN WHICH A POSITION IS LOCATED
+
+        Recently, Mr. Barry N. Rappaport of New  Mexico State University
+  transcribed  the constellation  boundaries as  fixed  by the IAU  into
+  machine-readable form.  These have  been  transcribed  by Dr. Nancy G.
+  Roman to make it possible  to determine by  computer the constellation
+  in which a position is located.
+
+ NSSDC catalog description:
+ 6042   AN     Catalog of Constellation Boundary Data (Delporte, E. 1930, 
+               Cambridge Univ. Press)
+               Comment(s): includes constellation identification software 
+               (ADC 1987; see Roman, N.G. 1987, Publ. Astron. Soc. Pacific 
+               99, 695); 23 description, 118 software, 358 data records. 
+               3 files: 23x80, 118x80, 358x29 
+
+ Further adapted for xephem by:
+
+    Craig Counterman: conversion from original F77 to C
+    Elwood Downey:    incorporation into xephem
+    Ernie Wright:     additional speed and time improvments
+
+Constellation figures:
+
+    Chris Marriott:   original figures
+    Elwood Downey:    incorporated into xephem
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "astro.h"
+
+/*
+======================================================================
+Ernie Wright  2 Mar 94
+
+Find the constellation for a given position.
+
+First C version by Craig Counterman and Elwood Downey.  Based on a
+FORTRAN program by Nancy G. Roman (Roman, N.G. 1987, Publ. Astron.
+Soc. Pacific 99, 695).  IAU constellation boundaries transcribed into
+machine-readable form by Barry N. Rappaport, New Mexico State Univ.
+======================================================================
+*/
+
+#define NBOUNDS 357
+
+/* constellation ids */
+#define And  0
+#define Ant  1
+#define Aps  2
+#define Aql  3
+#define Aqr  4
+#define Ara  5
+#define Ari  6
+#define Aur  7
+#define Boo  8
+#define CMa  9
+#define CMi 10
+#define CVn 11
+#define Cae 12
+#define Cam 13
+#define Cap 14
+#define Car 15
+#define Cas 16
+#define Cen 17
+#define Cep 18
+#define Cet 19
+#define Cha 20
+#define Cir 21
+#define Cnc 22
+#define Col 23
+#define Com 24
+#define CrA 25
+#define CrB 26
+#define Crt 27
+#define Cru 28
+#define Crv 29
+#define Cyg 30
+#define Del 31
+#define Dor 32
+#define Dra 33
+#define Equ 34
+#define Eri 35
+#define For 36
+#define Gem 37
+#define Gru 38
+#define Her 39
+#define Hor 40
+#define Hya 41
+#define Hyi 42
+#define Ind 43
+#define LMi 44
+#define Lac 45
+#define Leo 46
+#define Lep 47
+#define Lib 48
+#define Lup 49
+#define Lyn 50
+#define Lyr 51
+#define Men 52
+#define Mic 53
+#define Mon 54
+#define Mus 55
+#define Nor 56
+#define Oct 57
+#define Oph 58
+#define Ori 59
+#define Pav 60
+#define Peg 61
+#define Per 62
+#define Phe 63
+#define Pic 64
+#define PsA 65
+#define Psc 66
+#define Pup 67
+#define Pyx 68
+#define Ret 69
+#define Scl 70
+#define Sco 71
+#define Sct 72
+#define Se1 73
+#define Sex 74
+#define Sge 75
+#define Sgr 76
+#define Tau 77
+#define Tel 78
+#define TrA 79
+#define Tri 80
+#define Tuc 81
+#define UMa 82
+#define UMi 83
+#define Vel 84
+#define Vir 85
+#define Vol 86
+#define Vul 87
+#define Se2 88
+
+static char *cns_namemap[ NCNS ] = {
+   /*  0 */   "And: Andromeda",
+   /*  1 */   "Ant: Antlia",
+   /*  2 */   "Aps: Apus",
+   /*  3 */   "Aql: Aquila",
+   /*  4 */   "Aqr: Aquarius",
+   /*  5 */   "Ara: Ara",
+   /*  6 */   "Ari: Aries",
+   /*  7 */   "Aur: Auriga",
+   /*  8 */   "Boo: Bootes",
+   /*  9 */   "CMa: Canis Major",
+   /* 10 */   "CMi: Canis Minor",
+   /* 11 */   "CVn: Canes Venatici",
+   /* 12 */   "Cae: Caelum",
+   /* 13 */   "Cam: Camelopardalis",
+   /* 14 */   "Cap: Capricornus",
+   /* 15 */   "Car: Carina",
+   /* 16 */   "Cas: Cassiopeia",
+   /* 17 */   "Cen: Centaurus",
+   /* 18 */   "Cep: Cepheus",
+   /* 19 */   "Cet: Cetus",
+   /* 20 */   "Cha: Chamaeleon",
+   /* 21 */   "Cir: Circinus",
+   /* 22 */   "Cnc: Cancer",
+   /* 23 */   "Col: Columba",
+   /* 24 */   "Com: Coma Berenices",
+   /* 25 */   "CrA: Corona Australis",
+   /* 26 */   "CrB: Corona Borealis",
+   /* 27 */   "Crt: Crater",
+   /* 28 */   "Cru: Crux",
+   /* 29 */   "Crv: Corvus",
+   /* 30 */   "Cyg: Cygnus",
+   /* 31 */   "Del: Delphinus",
+   /* 32 */   "Dor: Dorado",
+   /* 33 */   "Dra: Draco",
+   /* 34 */   "Equ: Equuleus",
+   /* 35 */   "Eri: Eridanus",
+   /* 36 */   "For: Fornax",
+   /* 37 */   "Gem: Gemini",
+   /* 38 */   "Gru: Grus",
+   /* 39 */   "Her: Hercules",
+   /* 40 */   "Hor: Horologium",
+   /* 41 */   "Hya: Hydra",
+   /* 42 */   "Hyi: Hydrus",
+   /* 43 */   "Ind: Indus",
+   /* 44 */   "LMi: Leo Minor",
+   /* 45 */   "Lac: Lacerta",
+   /* 46 */   "Leo: Leo",
+   /* 47 */   "Lep: Lepus",
+   /* 48 */   "Lib: Libra",
+   /* 49 */   "Lup: Lupus",
+   /* 50 */   "Lyn: Lynx",
+   /* 51 */   "Lyr: Lyra",
+   /* 52 */   "Men: Mensa",
+   /* 53 */   "Mic: Microscopium",
+   /* 54 */   "Mon: Monoceros",
+   /* 55 */   "Mus: Musca",
+   /* 56 */   "Nor: Norma",
+   /* 57 */   "Oct: Octans",
+   /* 58 */   "Oph: Ophiuchus",
+   /* 59 */   "Ori: Orion",
+   /* 60 */   "Pav: Pavo",
+   /* 61 */   "Peg: Pegasus",
+   /* 62 */   "Per: Perseus",
+   /* 63 */   "Phe: Phoenix",
+   /* 64 */   "Pic: Pictor",
+   /* 65 */   "PsA: Piscis Austrinus",
+   /* 66 */   "Psc: Pisces",
+   /* 67 */   "Pup: Puppis",
+   /* 68 */   "Pyx: Pyxis",
+   /* 69 */   "Ret: Reticulum",
+   /* 70 */   "Scl: Sculptor",
+   /* 71 */   "Sco: Scorpius",
+   /* 72 */   "Sct: Scutum",
+   /* 73 */   "Se1: Serpens Caput",
+   /* 74 */   "Sex: Sextans",
+   /* 75 */   "Sge: Sagitta",
+   /* 76 */   "Sgr: Sagittarius",
+   /* 77 */   "Tau: Taurus",
+   /* 78 */   "Tel: Telescopium",
+   /* 79 */   "TrA: Triangulum Australe",
+   /* 80 */   "Tri: Triangulum",
+   /* 81 */   "Tuc: Tucana",
+   /* 82 */   "UMa: Ursa Major",
+   /* 83 */   "UMi: Ursa Minor",
+   /* 84 */   "Vel: Vela",
+   /* 85 */   "Vir: Virgo",
+   /* 86 */   "Vol: Volans",
+   /* 87 */   "Vul: Vulpecula",
+   /* 88 */   "Se2: Serpens Cauda",
+};
+
+static struct {
+   unsigned short lower_ra;      /* hours * 1800 */
+   unsigned short upper_ra;      /* hours * 1800 */
+   short          lower_dec;     /* degrees * 60 */
+   short          index;
+} cbound[ NBOUNDS ] = {
+   {     0, 43200,  5280, UMi },
+   { 14400, 26100,  5190, UMi },
+   { 37800, 41400,  5170, UMi },
+   { 32400, 37800,  5160, UMi },
+   {     0, 14400,  5100, Cep },
+   { 16500, 19200,  4920, Cam },
+   {     0,  9000,  4800, Cep },
+   { 19200, 26100,  4800, Cam },
+   { 31500, 32400,  4800, UMi },
+   { 36300, 37800,  4800, Dra },
+   {     0,  6315,  4620, Cep },
+   { 20700, 24450,  4620, Cam },
+   { 29760, 31500,  4500, UMi },
+   { 36300, 37200,  4500, Cep },
+   { 14340, 16500,  4410, Cam },
+   { 16500, 20400,  4410, Dra },
+   { 23400, 29760,  4200, UMi },
+   {  5580,  6150,  4080, Cas },
+   { 36750, 37200,  4020, Dra },
+   { 20400, 21600,  3990, Dra },
+   {     0,   600,  3960, Cep },
+   { 25200, 28200,  3960, UMi },
+   { 42450, 43200,  3960, Cep },
+   { 21600, 24300,  3840, Dra },
+   { 24300, 25950,  3780, Dra },
+   { 41700, 42450,  3780, Cep },
+   { 10980, 12600,  3720, Cam },
+   { 36000, 36750,  3690, Dra },
+   { 36966, 37080,  3655, Cep },
+   { 12600, 14340,  3600, Cam },
+   { 14340, 15150,  3600, UMa },
+   { 35580, 36000,  3570, Dra },
+   { 36000, 36966,  3570, Cep },
+   { 41160, 41700,  3545, Cep },
+   {     0,  4380,  3510, Cas },
+   { 34950, 35580,  3480, Dra },
+   {  3060,  3435,  3450, Cas },
+   {  4380,  5580,  3420, Cas },
+   {  5580,  5700,  3420, Cam },
+   { 40170, 41160,  3375, Cep },
+   {  9000, 10980,  3360, Cam },
+   { 25260, 25950,  3330, UMa },
+   { 25950, 34950,  3330, Dra },
+   {  5700,  6000,  3300, Cam },
+   { 39840, 40170,  3300, Cep },
+   { 37080, 39540,  3290, Cep },
+   {     0,  3060,  3240, Cas },
+   { 10980, 11700,  3240, Lyn },
+   { 21750, 24300,  3180, UMa },
+   { 27450, 28350,  3180, Dra },
+   { 39540, 39840,  3165, Cep },
+   {  6000,  9000,  3150, Cam },
+   { 41160, 42000,  3150, Cas },
+   { 28350, 30600,  3090, Dra },
+   {  3675,  4530,  3030, Per },
+   { 30600, 32820,  3030, Dra },
+   {     0,  2460,  3000, Cas },
+   {  2460,  3000,  3000, Per },
+   { 11700, 12240,  3000, Lyn },
+   { 42000, 43200,  3000, Cas },
+   { 24300, 25260,  2910, UMa },
+   {     0,  2010,  2880, Cas },
+   { 42450, 43200,  2880, Cas },
+   { 32715, 32820,  2850, Her },
+   { 32820, 34350,  2850, Dra },
+   { 34350, 34500,  2850, Cyg },
+   {  3000,  3675,  2820, Per },
+   { 15150, 16500,  2820, UMa },
+   {   300,  1560,  2760, Cas },
+   { 21600, 21750,  2700, UMa },
+   { 12240, 13260,  2670, Lyn },
+   { 39435, 39540,  2640, Cyg },
+   { 39375, 39435,  2625, Cyg },
+   { 34500, 34920,  2610, Cyg },
+   { 16500, 18300,  2520, UMa },
+   { 18300, 19410,  2400, UMa },
+   { 27780, 28350,  2400, Boo },
+   { 28350, 29400,  2400, Her },
+   { 16650, 17250,  2385, Lyn },
+   {     0,  4530,  2205, And },
+   {  4530,  4620,  2205, Per },
+   { 34845, 34920,  2190, Lyr },
+   {  8100,  8445,  2160, Per },
+   { 39120, 39375,  2160, Cyg },
+   { 39375, 39600,  2160, Lac },
+   { 11760, 13260,  2130, Aur },
+   { 13260, 13950,  2130, Lyn },
+   {     0,  3600,  2100, And },
+   { 39600, 41070,  2100, Lac },
+   { 41070, 41160,  2070, Lac },
+   { 41160, 42300,  2070, And },
+   {  4620,  4890,  2040, Per },
+   { 19410, 19800,  2040, UMa },
+   { 21600, 22200,  2040, CVn },
+   { 13950, 16650,  2010, Lyn },
+   { 16650, 17790,  2010, LMi },
+   {  1290,  2535,  1980, And },
+   { 27330, 27780,  1980, Boo },
+   { 42300, 42750,  1925, And },
+   { 22200, 23850,  1920, CVn },
+   { 42750, 43200,  1880, And },
+   { 25125, 25260,  1845, CVn },
+   {  4350,  4890,  1840, Tri },
+   {  4890,  8100,  1840, Per },
+   {  8100,  8550,  1800, Aur },
+   { 32715, 34845,  1800, Lyr },
+   { 19800, 21600,  1740, UMa },
+   { 35400, 37650,  1740, Cyg },
+   {  8550, 10590,  1710, Aur },
+   { 17790, 18900,  1710, LMi },
+   { 23850, 25125,  1710, CVn },
+   {     0,   120,  1680, And },
+   {  2535,  3000,  1680, Tri },
+   { 10590, 11760,  1680, Aur },
+   { 14190, 14400,  1680, Gem },
+   { 37650, 39120,  1680, Cyg },
+   { 34665, 35400,  1650, Cyg },
+   {  3450,  4350,  1635, Tri },
+   { 29100, 29400,  1620, CrB },
+   { 27150, 27330,  1560, Boo },
+   { 27330, 29100,  1560, CrB },
+   { 33060, 33960,  1560, Lyr },
+   { 19350, 19800,  1530, LMi },
+   { 33960, 34665,  1530, Lyr },
+   {  3000,  3450,  1500, Tri },
+   {  1290,  1530,  1425, Psc },
+   { 18900, 19350,  1410, LMi },
+   { 38250, 38550,  1410, Vul },
+   { 10260, 10590,  1370, Tau },
+   {   120,   255,  1320, And },
+   { 28650, 28860,  1320, Se1 },
+   { 10590, 11190,  1290, Gem },
+   { 35700, 36450,  1275, Vul },
+   { 33960, 34650,  1265, Vul },
+   {   255,  1530,  1260, And },
+   { 36450, 37020,  1230, Vul },
+   { 14055, 14190,  1200, Gem },
+   { 37020, 38250,  1170, Vul },
+   { 34650, 35700,  1150, Vul },
+   {  5910,  6060,  1140, Ari },
+   { 33960, 34200,  1110, Sge },
+   { 10260, 10380,  1080, Ori },
+   { 11190, 11355,  1050, Gem },
+   { 34200, 35700,   970, Sge },
+   {  8940,  9600,   960, Tau },
+   { 28650, 28950,   960, Her },
+   { 35700, 36450,   945, Sge },
+   {  8310,  8940,   930, Tau },
+   {  9600, 10080,   930, Tau },
+   { 23100, 24300,   900, Com },
+   { 31050, 32850,   860, Her },
+   { 21360, 23100,   840, Com },
+   { 13500, 14055,   810, Gem },
+   { 30150, 31050,   770, Her },
+   {     0,   255,   750, Peg },
+   { 10080, 10380,   750, Tau },
+   { 12600, 13500,   750, Gem },
+   { 38010, 38400,   750, Peg },
+   { 11355, 12480,   720, Gem },
+   { 32850, 33960,   720, Her },
+   { 37575, 37890,   710, Del },
+   { 37890, 38010,   710, Peg },
+   { 20730, 21360,   660, Leo },
+   { 11235, 11355,   600, Ori },
+   { 12480, 12600,   600, Gem },
+   { 14055, 14265,   600, Cnc },
+   { 42900, 43200,   600, Peg },
+   {  3000,  5910,   595, Ari },
+   { 36255, 36540,   510, Del },
+   { 24300, 27150,   480, Boo },
+   { 40950, 42900,   450, Peg },
+   { 14265, 16650,   420, Cnc },
+   { 16650, 19350,   420, Leo },
+   { 32850, 33592,   375, Oph },
+   { 33592, 33960,   375, Aql },
+   { 37500, 37575,   360, Del },
+   { 12600, 12630,   330, CMi },
+   { 32850, 33165,   270, Se2 },
+   { 28950, 30150,   240, Her },
+   { 32850, 33165,   180, Oph },
+   { 38640, 39000,   165, Peg },
+   {     0,  3600,   120, Psc },
+   { 33450, 33960,   120, Se2 },
+   { 36540, 37500,   120, Del },
+   { 37500, 38400,   120, Equ },
+   { 38400, 38640,   120, Peg },
+   { 39600, 40950,   120, Peg },
+   { 39000, 39600,   105, Peg },
+   { 12630, 12960,    90, CMi },
+   {  6450,  8310,     0, Tau },
+   {  8310,  8400,     0, Ori },
+   { 12960, 14550,     0, CMi },
+   { 26400, 27150,     0, Vir },
+   { 32100, 32850,     0, Oph },
+   {  4770,  5910,  -105, Cet },
+   {  5910,  6450,  -105, Tau },
+   { 27150, 29280,  -195, Se1 },
+   {  8400,  9150,  -240, Ori },
+   { 10500, 11235,  -240, Ori },
+   { 32100, 32340,  -240, Se2 },
+   { 32850, 33450,  -240, Se2 },
+   { 33450, 33960,  -240, Aql },
+   { 40950, 42900,  -240, Psc },
+   { 19350, 20730,  -360, Leo },
+   { 20730, 21300,  -360, Vir },
+   {     0,   600,  -420, Psc },
+   { 42900, 43200,  -420, Psc },
+   { 25650, 26400,  -480, Vir },
+   { 28650, 29280,  -480, Oph },
+   { 36000, 36960,  -540, Aql },
+   { 38400, 39360,  -540, Aqr },
+   { 30900, 32340,  -600, Oph },
+   { 10500, 14550,  -660, Mon },
+   {  8850,  9150,  -660, Eri },
+   {  9150, 10500,  -660, Ori },
+   { 14550, 15060,  -660, Hya },
+   { 17250, 19350,  -660, Sex },
+   { 21300, 23100,  -660, Vir },
+   { 31650, 31800,  -700, Oph },
+   { 33960, 36000,  -722, Aql },
+   {  8700,  8850,  -870, Eri },
+   { 36960, 38400,  -900, Aqr },
+   { 30900, 32850,  -960, Se2 },
+   { 32850, 33960,  -960, Sct },
+   { 15060, 15450, -1020, Hya },
+   { 29280, 29475, -1095, Oph },
+   { 15450, 16350, -1140, Hya },
+   { 19350, 19500, -1140, Crt },
+   { 29280, 29475, -1155, Sco },
+   { 28200, 28650, -1200, Lib },
+   { 22650, 23100, -1320, Crv },
+   { 23100, 25650, -1320, Vir },
+   { 16350, 17550, -1440, Hya },
+   {  3000,  4770, -1463, Cet },
+   {  4770,  6750, -1463, Eri },
+   { 19500, 21300, -1470, Crt },
+   { 21300, 22650, -1470, Crv },
+   { 25650, 26850, -1470, Lib },
+   { 29280, 30150, -1475, Oph },
+   {     0,  3000, -1530, Cet },
+   { 38400, 39360, -1530, Cap },
+   { 39360, 42900, -1530, Aqr },
+   { 42900, 43200, -1530, Cet },
+   { 17550, 18450, -1590, Hya },
+   {  8460,  8700, -1635, Eri },
+   {  8700, 11010, -1635, Lep },
+   { 36000, 38400, -1680, Cap },
+   { 18450, 19050, -1750, Hya },
+   { 22650, 26850, -1770, Hya },
+   { 26850, 28200, -1770, Lib },
+   { 28200, 28800, -1770, Sco },
+   {  8250,  8460, -1800, Eri },
+   { 30150, 31680, -1800, Oph },
+   { 31680, 32100, -1800, Sgr },
+   { 19050, 19500, -1870, Hya },
+   { 11010, 13260, -1980, CMa },
+   { 22050, 22650, -1980, Hya },
+   { 19500, 22050, -2100, Hya },
+   {  6300,  6750, -2160, For },
+   { 15060, 16860, -2205, Pyx },
+   {  7680,  8250, -2220, Eri },
+   { 32100, 34500, -2220, Sgr },
+   { 38400, 41400, -2220, PsA },
+   { 41400, 42000, -2220, Scl },
+   {  5400,  6300, -2375, For },
+   { 16860, 19800, -2385, Ant },
+   {     0,  3000, -2400, Scl },
+   {  3000,  5400, -2400, For },
+   {  6960,  7680, -2400, Eri },
+   { 42000, 43200, -2400, Scl },
+   { 25500, 26850, -2520, Cen },
+   { 28200, 28800, -2520, Lup },
+   { 28800, 29557, -2520, Sco },
+   {  8700,  9000, -2580, Cae },
+   {  9000, 11850, -2580, Col },
+   { 14400, 15060, -2580, Pup },
+   {  6150,  6960, -2640, Eri },
+   { 29557, 32100, -2730, Sco },
+   { 32100, 34500, -2730, CrA },
+   { 34500, 36600, -2730, Sgr },
+   { 36600, 38400, -2730, Mic },
+   {  5400,  6150, -2760, Eri },
+   {  8100,  8700, -2790, Cae },
+   { 27600, 28200, -2880, Lup },
+   {     0,  4200, -2890, Phe },
+   {  4800,  5400, -2940, Eri },
+   {  7350,  7680, -2940, Hor },
+   {  7680,  8100, -2940, Cae },
+   { 38400, 39600, -3000, Gru },
+   { 10800, 14400, -3045, Pup },
+   { 14400, 14700, -3045, Vel },
+   {  4350,  4800, -3060, Eri },
+   {  6900,  7350, -3060, Hor },
+   {     0,  3300, -3090, Phe },
+   { 10800, 11100, -3150, Car },
+   { 14700, 15210, -3180, Vel },
+   {  6300,  6900, -3190, Hor },
+   {  6900,  7200, -3190, Dor },
+   {     0,  2850, -3210, Phe },
+   {  3900,  4350, -3240, Eri },
+   {  8100,  9000, -3240, Pic },
+   { 27090, 27600, -3240, Lup },
+   { 15210, 15900, -3270, Vel },
+   { 11100, 11700, -3300, Car },
+   { 21300, 23100, -3300, Cen },
+   { 25500, 27090, -3300, Lup },
+   { 27090, 27600, -3300, Nor },
+   {  7200,  7800, -3390, Dor },
+   { 15900, 19800, -3390, Vel },
+   { 19800, 20250, -3390, Cen },
+   { 31500, 32400, -3420, Ara },
+   { 32400, 36600, -3420, Tel },
+   { 39600, 42000, -3420, Gru },
+   {  5760,  6300, -3450, Hor },
+   {  9000,  9900, -3450, Pic },
+   { 11700, 12300, -3480, Car },
+   {     0,  2400, -3510, Phe },
+   {  2400,  3900, -3510, Eri },
+   { 42000, 43200, -3510, Phe },
+   {  7800,  8250, -3540, Dor },
+   { 27600, 29557, -3600, Nor },
+   { 36600, 38400, -3600, Ind },
+   {  9900, 10800, -3660, Pic },
+   { 27300, 27600, -3660, Cir },
+   { 29557, 29850, -3660, Ara },
+   { 26850, 27300, -3815, Cir },
+   { 29850, 30150, -3815, Ara },
+   { 10800, 12300, -3840, Pic },
+   { 12300, 16260, -3840, Car },
+   { 20250, 21300, -3840, Cen },
+   { 21300, 23100, -3840, Cru },
+   { 23100, 26160, -3840, Cen },
+   { 24300, 24600, -3900, Cir },
+   { 30150, 30300, -3900, Ara },
+   {  3900,  5760, -4050, Hor },
+   {  5760,  8250, -4050, Ret },
+   { 26550, 26850, -4050, Cir },
+   { 30300, 31500, -4050, Ara },
+   { 31500, 32400, -4050, Pav },
+   { 39600, 42000, -4050, Tuc },
+   {  8250, 11850, -4200, Dor },
+   { 24600, 26550, -4200, Cir },
+   { 26550, 30600, -4200, TrA },
+   {     0,  2400, -4500, Tuc },
+   {  6300,  8250, -4500, Hyi },
+   { 11850, 16260, -4500, Vol },
+   { 16260, 20250, -4500, Car },
+   { 20250, 24600, -4500, Mus },
+   { 32400, 38400, -4500, Pav },
+   { 38400, 42000, -4500, Ind },
+   { 42000, 43200, -4500, Tuc },
+   {  1350,  2400, -4560, Tuc },
+   {     0,  6300, -4950, Hyi },
+   { 13800, 24600, -4950, Cha },
+   { 24600, 32400, -4950, Aps },
+   {  6300, 13800, -5100, Men },
+   {     0, 43200, -5400, Oct }
+};
+
+static short start[] = {
+   355, 352, 343, 340, 332, 320,
+   303, 288, 277, 266, 257, 251,
+   239, 229, 221, 211, 203, 189,
+   177, 163, 149, 136, 124, 104,
+    87,  75,  69,  54,  43,  29,
+    23,  16,  12,   6,   4,   0,   0
+};
+
+
+/*
+======================================================================
+constellation_pick()
+
+Do a constellation pick from RA and Dec.
+
+INPUTS
+   r        right ascension, radians
+   d        declination, radians
+   e        epoch to which r and d precessed, as an mjd
+
+RESULTS
+   Returns an index for the constellation region that the coordinates
+   belong to, or -1 if no constellation pick can be found.
+
+The constellation is identified by linear search.  We look for a
+member of cbound[] whose lower_dec is less than the declination of the
+pick point and whose lower_ra and upper_ra bracket the pick point's
+right ascension.  The data for that cbound[] member describes a sub-
+region belonging to the picked constellation.
+
+In geometric terms, the search amounts to starting at the north pole
+and traveling south on a line of constant right ascension through the
+pick point.  At every declination where a cbound[] member lives, we
+wake up, and if (1) the pick point is now behind us, and (2) the
+cbound[] segment is crossing our path, we know we've hit the edge of
+a constellation subregion that the pick point belongs to.
+
+The cbound[] right ascension and declination values are scaled into
+integers; this conserves storage and makes comparisons faster.  The
+start[] array, which gives starting points in cbound[] for different
+declinations in 5-degree increments, further speeds the search by
+skipping early parts of the list for which we know the search can't
+succeed--geometrically, we start no more than 5 degrees north of the
+pick point, rather than at the north pole.
+
+The data in cbound[] are for epoch 1875.
+======================================================================
+*/
+
+int
+cns_pick(double r, double d, double e)
+{
+   double Mjd;
+   unsigned short ra;
+   short de, i;
+
+   cal_mjd( 1, 1.0, 1875, &Mjd );
+   precess( e, Mjd, &r, &d );
+   ra = ( unsigned short )( radhr( r ) * 1800 );
+   de = ( short )( raddeg( d ) * 60 );
+   if (d < 0.0) --de;
+
+   i = ( de + 5400 ) / 300;
+   if ( i < 0 || i > 36 ) return -1;
+   i = start[ i ];
+
+   for ( ; i < NBOUNDS; i++ )
+      if ( cbound[ i ].lower_dec <= de &&
+           cbound[ i ].upper_ra   > ra &&
+           cbound[ i ].lower_ra  <= ra ) break;
+
+   return ( i == NBOUNDS ) ? -1 : ( int ) cbound[ i ].index;
+}
+
+/* given a constellation id (as from cns_pick()), return pointer to static
+ * storage containg its name in the form "AAA: Name".
+ * return "???: ???" if id is invalid.
+ */
+char *
+cns_name (int id)
+{
+	if (id < 0 || id >= NCNS)
+	    return ("???: ???");
+	return (cns_namemap[id]);
+}
+
+/* return cns_namemap index matching first three chars in abbrev[], else -1.
+ */
+int
+cns_id (char *abbrev)
+{
+	int i;
+
+	for (i = 0; i < NCNS; i++)
+	    if (strncmp (abbrev, cns_namemap[i], 3) == 0)
+		return (i);
+	return (-1);
+}
+
+/* edges of constant ra */
+static struct {
+   unsigned short ra;	/* hours * 1800 */
+   short dec0, dec1;	/* degrees * 60 */
+} ra_edges[] = {
+    {     0, -4950, -4500 },
+    {     0,   600,   750 },
+    {     0,  1680,  1879 },
+    {   120,  1320,  1680 },
+    {   255,   750,  1260 },
+    {   255,  1260,  1320 },
+    {   300,  2760,  2880 },
+    {   599,  -420,     0 },
+    {   599,     0,   120 },
+    {   599,  3960,  4620 },
+    {  1290,  1425,  1980 },
+    {  1350, -4500, -4560 },
+    {  1530,  1260,  1425 },
+    {  1560,  2760,  2880 },
+    {  2010,  2880,  3000 },
+    {  2399, -4560, -3510 },
+    {  2399, -3510, -3210 },
+    {  2460,  3000,  3240 },
+    {  2534,  1680,  1980 },
+    {  2534,  1980,  2100 },
+    {  2849, -3210, -3090 },
+    {  3000, -2400, -1530 },
+    {  3000, -1530, -1462 },
+    {  3000,   595,  1500 },
+    {  3000,  1500,  1680 },
+    {  3000,  2820,  3000 },
+    {  3060,  3240,  3450 },
+    {  3299, -3090, -2890 },
+    {  3434,  3450,  3510 },
+    {  3450,  1500,  1635 },
+    {  3600,   120,   595 },
+    {  3600,  2100,  2205 },
+    {  3675,  2820,  3030 },
+    {  3900, -4050, -3510 },
+    {  3900, -3510, -3240 },
+    {  4199, -2890, -2400 },
+    {  4350, -3240, -3060 },
+    {  4350,  1635,  1840 },
+    {  4379,  3420,  3510 },
+    {  4530,  2205,  3030 },
+    {  4620,  2040,  2205 },
+    {  4770, -1462,  -105 },
+    {  4800, -3060, -2940 },
+    {  4890,  1840,  2040 },
+    {  5400, -2940, -2760 },
+    {  5400, -2400, -2374 },
+    {  5580,  3420,  4080 },
+    {  5700,  3300,  3420 },
+    {  5760, -3450, -4050 },
+    {  5909,  -105,     0 },
+    {  5909,     0,   595 },
+    {  5909,   595,  1140 },
+    {  5999,  3150,  3300 },
+    {  6060,  1140,  1840 },
+    {  6150, -2760, -2640 },
+    {  6150,  4080,  4620 },
+    {  6300, -5100, -4950 },
+    {  6300, -4950, -4500 },
+    {  6300, -3190, -3450 },
+    {  6300, -2374, -2160 },
+    {  6314,  4620,  4800 },
+    {  6449,  -105,     0 },
+    {  6750, -2160, -1462 },
+    {  6899, -3060, -3190 },
+    {  6960, -2640, -2400 },
+    {  7200, -3390, -3190 },
+    {  7349, -2940, -3060 },
+    {  7680, -2400, -2940 },
+    {  7680, -2220, -2400 },
+    {  7799, -3540, -3390 },
+    {  8100, -3240, -2940 },
+    {  8100, -2940, -2790 },
+    {  8100,  1800,  1840 },
+    {  8100,  1840,  2160 },
+    {  8249, -4500, -4200 },
+    {  8249, -4050, -4200 },
+    {  8249, -4050, -3540 },
+    {  8249, -1800, -2220 },
+    {  8310,     0,   930 },
+    {  8400,  -240,     0 },
+    {  8445,  2160,  3150 },
+    {  8460, -1635, -1800 },
+    {  8550,  1710,  1800 },
+    {  8699, -2790, -2580 },
+    {  8699,  -870, -1635 },
+    {  8850,  -660,  -870 },
+    {  8940,   930,   960 },
+    {  9000, -3450, -3240 },
+    {  9000, -2580, -1635 },
+    {  9000,  3150,  3360 },
+    {  9000,  4800,  5100 },
+    {  9149,  -660,  -240 },
+    {  9599,   930,   960 },
+    {  9900, -3660, -3450 },
+    { 10080,   750,   930 },
+    { 10260,  1080,  1369 },
+    { 10380,   750,  1080 },
+    { 10499,  -660,  -240 },
+    { 10589,  1290,  1369 },
+    { 10589,  1369,  1680 },
+    { 10589,  1680,  1710 },
+    { 10800, -3840, -3660 },
+    { 10800, -3150, -3045 },
+    { 10800, -3045, -2580 },
+    { 10980,  3240,  3360 },
+    { 10980,  3360,  3720 },
+    { 11010, -1980, -1635 },
+    { 11010, -1635,  -660 },
+    { 11100, -3300, -3150 },
+    { 11190,  1050,  1290 },
+    { 11235,  -240,     0 },
+    { 11235,     0,   600 },
+    { 11354,   600,   720 },
+    { 11354,   720,  1050 },
+    { 11700, -3480, -3300 },
+    { 11700,  3000,  3240 },
+    { 11759,  1680,  2130 },
+    { 11849, -4200, -4500 },
+    { 11849, -4200, -3840 },
+    { 11849, -1980, -2580 },
+    { 12240,  2670,  3000 },
+    { 12299, -3840, -3480 },
+    { 12479,   600,   720 },
+    { 12600,   330,   600 },
+    { 12600,   600,   750 },
+    { 12600,  3600,  3720 },
+    { 12630,    90,   330 },
+    { 12960,     0,    90 },
+    { 13260,  -660, -1980 },
+    { 13260,  2130,  2670 },
+    { 13500,   750,   810 },
+    { 13800, -5100, -4950 },
+    { 13800, -4500, -4950 },
+    { 13950,  2010,  2130 },
+    { 14054,   600,   810 },
+    { 14054,   810,  1200 },
+    { 14189,  1200,  1680 },
+    { 14265,   420,   600 },
+    { 14340,  3600,  4410 },
+    { 14400, -3045, -2580 },
+    { 14400,  1680,  2010 },
+    { 14400,  5100,  5190 },
+    { 14400,  5280,  5190 },
+    { 14549,  -660,     0 },
+    { 14549,     0,   420 },
+    { 14700, -3180, -3045 },
+    { 15060, -2580, -2205 },
+    { 15060, -2205, -1020 },
+    { 15060, -1020,  -660 },
+    { 15150,  2820,  3600 },
+    { 15209, -3270, -3180 },
+    { 15449, -1140, -1020 },
+    { 15899, -3390, -3270 },
+    { 16259, -4500, -3840 },
+    { 16349, -1440, -1140 },
+    { 16500,  2520,  2820 },
+    { 16500,  4410,  4920 },
+    { 16650,   420,  2010 },
+    { 16650,  2010,  2385 },
+    { 16860, -2385, -2205 },
+    { 16860, -1440, -2205 },
+    { 17249,  -660,     0 },
+    { 17249,     0,   420 },
+    { 17249,  2385,  2520 },
+    { 17550, -1590, -1440 },
+    { 17789,  1710,  2010 },
+    { 18300,  2400,  2520 },
+    { 18450, -1750, -1590 },
+    { 18900,  1410,  1710 },
+    { 19049, -1870, -1750 },
+    { 19200,  4800,  4920 },
+    { 19350,  -660, -1140 },
+    { 19350,  -360,  -660 },
+    { 19350,  -360,     0 },
+    { 19350,     0,   420 },
+    { 19350,  1410,  1530 },
+    { 19409,  2040,  2400 },
+    { 19499, -2100, -1870 },
+    { 19499, -1140, -1470 },
+    { 19800, -3390, -2385 },
+    { 19800, -2385, -2100 },
+    { 19800,  1530,  1740 },
+    { 19800,  1740,  2040 },
+    { 20250, -4500, -3840 },
+    { 20250, -3840, -3390 },
+    { 20399,  3990,  4410 },
+    { 20700,  4620,  4800 },
+    { 20730,  -360,     0 },
+    { 20730,     0,   660 },
+    { 21299, -3840, -3300 },
+    { 21299, -1470,  -660 },
+    { 21299,  -660,  -360 },
+    { 21360,   660,   840 },
+    { 21360,   840,  1740 },
+    { 21600,  1740,  2040 },
+    { 21600,  2040,  2700 },
+    { 21600,  3840,  3990 },
+    { 21749,  2700,  3180 },
+    { 22050, -1980, -2100 },
+    { 22199,  1920,  2040 },
+    { 22649, -1770, -1980 },
+    { 22649, -1470, -1320 },
+    { 23099, -3840, -3300 },
+    { 23099, -1320,  -660 },
+    { 23099,   840,   900 },
+    { 23400,  4620,  4200 },
+    { 23850,  1710,  1920 },
+    { 24300, -3900, -3840 },
+    { 24300,   480,   900 },
+    { 24300,   900,  1710 },
+    { 24300,  2910,  3180 },
+    { 24300,  3780,  3840 },
+    { 24449,  4800,  4620 },
+    { 24600, -4950, -4500 },
+    { 24600, -4500, -4200 },
+    { 24600, -4200, -3900 },
+    { 25124,  1710,  1845 },
+    { 25200,  4200,  3960 },
+    { 25259,  1845,  2910 },
+    { 25259,  2910,  3330 },
+    { 25500, -3300, -2520 },
+    { 25650, -1320, -1470 },
+    { 25650,  -480, -1320 },
+    { 25950,  3330,  3780 },
+    { 26100,  5190,  4800 },
+    { 26159, -3840, -3300 },
+    { 26400,     0,  -480 },
+    { 26550, -4200, -4050 },
+    { 26850, -4050, -3814 },
+    { 26850, -2520, -1770 },
+    { 26850, -1470, -1770 },
+    { 27090, -3300, -3240 },
+    { 27149,  -195,     0 },
+    { 27149,     0,   480 },
+    { 27149,   480,  1560 },
+    { 27300, -3814, -3660 },
+    { 27329,  1560,  1980 },
+    { 27450,  3180,  3330 },
+    { 27599, -3660, -3600 },
+    { 27599, -3600, -3300 },
+    { 27599, -3240, -2880 },
+    { 27779,  1980,  2400 },
+    { 28200, -2880, -2520 },
+    { 28200, -1770, -1200 },
+    { 28200,  3960,  4200 },
+    { 28350,  2400,  3090 },
+    { 28350,  3090,  3180 },
+    { 28650, -1200,  -480 },
+    { 28650,  -480,  -195 },
+    { 28650,   960,  1320 },
+    { 28800, -2520, -1770 },
+    { 28859,  1320,  1560 },
+    { 28949,   240,   960 },
+    { 29100,  1560,  1620 },
+    { 29280, -1474, -1155 },
+    { 29280, -1095,  -480 },
+    { 29280,  -195,     0 },
+    { 29280,     0,   240 },
+    { 29399,  1620,  2400 },
+    { 29475, -1155, -1095 },
+    { 29557, -3660, -3600 },
+    { 29557, -3600, -2730 },
+    { 29557, -2730, -2520 },
+    { 29759,  4200,  4500 },
+    { 29849, -3814, -3660 },
+    { 30150, -3900, -3814 },
+    { 30150, -1800, -1474 },
+    { 30150,   240,   769 },
+    { 30299, -4050, -3900 },
+    { 30600, -4050, -4200 },
+    { 30600,  3030,  3090 },
+    { 30900,  -960,  -600 },
+    { 31050,   769,   859 },
+    { 31500, -3420, -4050 },
+    { 31500,  4500,  4800 },
+    { 31649,  -700,  -600 },
+    { 31680,  -960, -1800 },
+    { 31800,  -700,  -600 },
+    { 32099, -2730, -2220 },
+    { 32099, -1800, -2220 },
+    { 32099,  -240,     0 },
+    { 32340,  -600,  -240 },
+    { 32400, -4950, -4500 },
+    { 32400, -4500, -4050 },
+    { 32400, -2730, -3420 },
+    { 32400,  4800,  5160 },
+    { 32715,  1800,  2850 },
+    { 32819,  2850,  3030 },
+    { 32850,  -240,  -960 },
+    { 32850,     0,   180 },
+    { 32850,   270,   375 },
+    { 32850,   720,   859 },
+    { 33060,  1560,  1800 },
+    { 33165,   180,   270 },
+    { 33449,  -240,     0 },
+    { 33449,     0,   120 },
+    { 33591,   375,   720 },
+    { 33960,  -960,  -721 },
+    { 33960,  -721,  -240 },
+    { 33960,   120,   375 },
+    { 33960,   720,  1110 },
+    { 33960,  1110,  1264 },
+    { 33960,  1264,  1530 },
+    { 33960,  1530,  1560 },
+    { 34200,   970,  1110 },
+    { 34349,  2850,  3330 },
+    { 34500, -2220, -2730 },
+    { 34500,  2610,  2850 },
+    { 34650,  1150,  1264 },
+    { 34664,  1530,  1650 },
+    { 34664,  1650,  1800 },
+    { 34844,  1800,  2190 },
+    { 34920,  2190,  2610 },
+    { 34950,  3330,  3480 },
+    { 35400,  1650,  1740 },
+    { 35580,  3480,  3570 },
+    { 35699,   945,   970 },
+    { 35699,  1150,  1275 },
+    { 36000, -1680,  -721 },
+    { 36000,  -540,  -721 },
+    { 36000,  3570,  3690 },
+    { 36255,   510,   945 },
+    { 36300,  4500,  4800 },
+    { 36450,   945,  1230 },
+    { 36450,  1230,  1275 },
+    { 36540,   120,   510 },
+    { 36599, -3600, -3420 },
+    { 36599, -3420, -2730 },
+    { 36599, -2730, -1680 },
+    { 36750,  3690,  4020 },
+    { 36959,  -900,  -540 },
+    { 36959,  -540,     0 },
+    { 36959,     0,   120 },
+    { 36966,  3570,  3655 },
+    { 37020,  1170,  1230 },
+    { 37080,  3289,  3655 },
+    { 37200,  4020,  4500 },
+    { 37499,   120,   360 },
+    { 37575,   360,   709 },
+    { 37650,  1680,  1740 },
+    { 37800,  4800,  5160 },
+    { 37800,  5160,  5169 },
+    { 37890,   709,  1170 },
+    { 38010,   709,   750 },
+    { 38250,  1170,  1410 },
+    { 38399, -4500, -3600 },
+    { 38399, -3000, -2730 },
+    { 38399, -2220, -2730 },
+    { 38399, -1680, -2220 },
+    { 38399, -1680, -1530 },
+    { 38399,  -540,  -900 },
+    { 38399,   120,   750 },
+    { 38550,  1410,  1680 },
+    { 38640,   120,   165 },
+    { 39000,   105,   165 },
+    { 39119,  1680,  2160 },
+    { 39360, -1530,  -540 },
+    { 39375,  2160,  2625 },
+    { 39434,  2625,  2640 },
+    { 39540,  2640,  3165 },
+    { 39540,  3165,  3289 },
+    { 39600, -4050, -3420 },
+    { 39600, -3420, -3000 },
+    { 39600,   105,   120 },
+    { 39600,  2100,  2160 },
+    { 39839,  3165,  3300 },
+    { 40170,  3300,  3375 },
+    { 40950,  -240,     0 },
+    { 40950,     0,   120 },
+    { 40950,   120,   450 },
+    { 41070,  2070,  2100 },
+    { 41160,  2070,  3150 },
+    { 41160,  3150,  3375 },
+    { 41160,  3375,  3544 },
+    { 41400, -2220, -1530 },
+    { 41400,  5169,  5280 },
+    { 41700,  3544,  3780 },
+    { 41999, -4500, -4050 },
+    { 41999, -3510, -3420 },
+    { 41999, -3420, -2400 },
+    { 41999, -2400, -2220 },
+    { 41999,  3000,  3150 },
+    { 42300,  1924,  2070 },
+    { 42449,  2880,  3000 },
+    { 42449,  3780,  3960 },
+    { 42750,  1879,  1924 },
+    { 42899, -1530,  -420 },
+    { 42899,  -420,  -240 },
+    { 42899,   450,   600 },
+};
+
+#define	NRA	((int)(sizeof(ra_edges)/sizeof(ra_edges[0])))
+
+/* edges of constant dec */
+static struct {
+   short dec;			/* degrees * 60 */
+   unsigned short ra0, ra1;	/* hours * 1800 */
+} dec_edges[] = {
+    { -5100,  6300, 13800 },
+    { -4950,     0,  6300 },
+    { -4950, 13800, 24600 },
+    { -4950, 24600, 32400 },
+    { -4560,  1350,  2399 },
+    { -4500,     0,  1350 },
+    { -4500,  6300,  8249 },
+    { -4500, 11849, 13800 },
+    { -4500, 13800, 16259 },
+    { -4500, 16259, 20250 },
+    { -4500, 20250, 24600 },
+    { -4500, 32400, 38399 },
+    { -4500, 38399, 41999 },
+    { -4500, 41999,     0 },
+    { -4200,  8249, 11849 },
+    { -4200, 24600, 26550 },
+    { -4200, 30600, 26550 },
+    { -4050,  3900,  5760 },
+    { -4050,  5760,  8249 },
+    { -4050, 26550, 26850 },
+    { -4050, 30299, 30600 },
+    { -4050, 31500, 30600 },
+    { -4050, 31500, 32400 },
+    { -4050, 39600, 41999 },
+    { -3900, 24300, 24600 },
+    { -3900, 30150, 30299 },
+    { -3840, 10800, 11849 },
+    { -3840, 11849, 12299 },
+    { -3840, 12299, 16259 },
+    { -3840, 20250, 21299 },
+    { -3840, 21299, 23099 },
+    { -3840, 23099, 24300 },
+    { -3840, 24300, 26159 },
+    { -3814, 26850, 27300 },
+    { -3814, 29849, 30150 },
+    { -3660,  9900, 10800 },
+    { -3660, 27300, 27599 },
+    { -3660, 29557, 29849 },
+    { -3600, 27599, 29557 },
+    { -3600, 36599, 38399 },
+    { -3540,  7799,  8249 },
+    { -3510,  2399,  3900 },
+    { -3510,  2399, 41999 },
+    { -3510,  3900,  2399 },
+    { -3510, 41999,  2399 },
+    { -3480, 11700, 12299 },
+    { -3450,  6300,  5760 },
+    { -3450,  9000,  9900 },
+    { -3420, 32400, 31500 },
+    { -3420, 32400, 36599 },
+    { -3420, 39600, 41999 },
+    { -3390,  7200,  7799 },
+    { -3390, 15899, 19800 },
+    { -3390, 19800, 20250 },
+    { -3300, 11100, 11700 },
+    { -3300, 21299, 23099 },
+    { -3300, 25500, 26159 },
+    { -3300, 26159, 27090 },
+    { -3300, 27090, 27599 },
+    { -3270, 15209, 15899 },
+    { -3240,  3900,  4350 },
+    { -3240,  8100,  9000 },
+    { -3240, 27090, 27599 },
+    { -3210,  2399,  2849 },
+    { -3190,  6899,  6300 },
+    { -3190,  6899,  7200 },
+    { -3180, 14700, 15209 },
+    { -3150, 10800, 11100 },
+    { -3090,  2849,  3299 },
+    { -3060,  4350,  4800 },
+    { -3060,  7349,  6899 },
+    { -3045, 10800, 14400 },
+    { -3045, 14400, 14700 },
+    { -3000, 38399, 39600 },
+    { -2940,  4800,  5400 },
+    { -2940,  7680,  7349 },
+    { -2940,  7680,  8100 },
+    { -2890,  3299,  4199 },
+    { -2880, 27599, 28200 },
+    { -2790,  8100,  8699 },
+    { -2760,  5400,  6150 },
+    { -2730, 29557, 32099 },
+    { -2730, 32099, 32400 },
+    { -2730, 34500, 32400 },
+    { -2730, 34500, 36599 },
+    { -2730, 38399, 36599 },
+    { -2640,  6150,  6960 },
+    { -2580,  8699,  9000 },
+    { -2580, 10800,  9000 },
+    { -2580, 11849, 10800 },
+    { -2580, 14400, 15060 },
+    { -2520, 25500, 26850 },
+    { -2520, 28200, 28800 },
+    { -2520, 29557, 28800 },
+    { -2400,  3000, 41999 },
+    { -2400,  4199,  3000 },
+    { -2400,  4199,  5400 },
+    { -2400,  6960,  7680 },
+    { -2385, 16860, 19800 },
+    { -2374,  5400,  6300 },
+    { -2220,  8249,  7680 },
+    { -2220, 32099, 34500 },
+    { -2220, 38399, 41400 },
+    { -2220, 41999, 41400 },
+    { -2205, 16860, 15060 },
+    { -2160,  6300,  6750 },
+    { -2100, 19800, 19499 },
+    { -2100, 22050, 19800 },
+    { -1980, 11010, 11849 },
+    { -1980, 13260, 11849 },
+    { -1980, 22649, 22050 },
+    { -1870, 19499, 19049 },
+    { -1800,  8460,  8249 },
+    { -1800, 30150, 31680 },
+    { -1800, 31680, 32099 },
+    { -1770, 26850, 22649 },
+    { -1770, 26850, 28200 },
+    { -1770, 28800, 28200 },
+    { -1750, 19049, 18450 },
+    { -1680, 36000, 36599 },
+    { -1680, 36599, 38399 },
+    { -1635,  8699,  8460 },
+    { -1635,  8699,  9000 },
+    { -1635,  9000, 11010 },
+    { -1590, 18450, 17550 },
+    { -1530,  3000, 42899 },
+    { -1530, 38399, 39360 },
+    { -1530, 41400, 39360 },
+    { -1530, 41400, 42899 },
+    { -1530, 42899,  3000 },
+    { -1530, 42899, 41400 },
+    { -1474, 29280, 30150 },
+    { -1470, 19499, 21299 },
+    { -1470, 21299, 22649 },
+    { -1470, 25650, 26850 },
+    { -1462,  3000,  4770 },
+    { -1462,  4770,  6750 },
+    { -1440, 16349, 16860 },
+    { -1440, 17550, 16860 },
+    { -1320, 22649, 23099 },
+    { -1320, 23099, 25650 },
+    { -1200, 28200, 28650 },
+    { -1155, 29280, 29475 },
+    { -1140, 15449, 16349 },
+    { -1140, 19350, 19499 },
+    { -1095, 29280, 29475 },
+    { -1020, 15060, 15449 },
+    {  -960, 30900, 31680 },
+    {  -960, 32850, 31680 },
+    {  -960, 32850, 33960 },
+    {  -900, 38399, 36959 },
+    {  -870,  8850,  8699 },
+    {  -721, 36000, 33960 },
+    {  -700, 31649, 31800 },
+    {  -660,  9149,  8850 },
+    {  -660, 10499,  9149 },
+    {  -660, 11010, 10499 },
+    {  -660, 11010, 13260 },
+    {  -660, 14549, 13260 },
+    {  -660, 15060, 14549 },
+    {  -660, 17249, 19350 },
+    {  -660, 23099, 21299 },
+    {  -600, 30900, 31649 },
+    {  -600, 31800, 32340 },
+    {  -540, 36959, 36000 },
+    {  -540, 39360, 38399 },
+    {  -480, 26400, 25650 },
+    {  -480, 28650, 29280 },
+    {  -420,   599, 42899 },
+    {  -360, 20730, 19350 },
+    {  -360, 21299, 20730 },
+    {  -240,  8400,  9149 },
+    {  -240, 10499, 11235 },
+    {  -240, 32099, 32340 },
+    {  -240, 33449, 32850 },
+    {  -240, 33960, 33449 },
+    {  -240, 40950, 42899 },
+    {  -195, 28650, 27149 },
+    {  -195, 28650, 29280 },
+    {  -105,  4770,  5909 },
+    {  -105,  5909,  6449 },
+    {     0,  6449,  8310 },
+    {     0,  8310,  8400 },
+    {     0, 12960, 14549 },
+    {     0, 27149, 26400 },
+    {     0, 32099, 32850 },
+    {    90, 12630, 12960 },
+    {   105, 39000, 39600 },
+    {   120,   599,  3600 },
+    {   120, 33449, 33960 },
+    {   120, 36540, 36959 },
+    {   120, 36959, 37499 },
+    {   120, 37499, 38399 },
+    {   120, 38399, 38640 },
+    {   120, 39600, 40950 },
+    {   165, 38640, 39000 },
+    {   180, 32850, 33165 },
+    {   240, 28949, 29280 },
+    {   240, 29280, 30150 },
+    {   270, 33165, 32850 },
+    {   330, 12600, 12630 },
+    {   360, 37499, 37575 },
+    {   375, 32850, 33591 },
+    {   375, 33591, 33960 },
+    {   420, 14265, 14549 },
+    {   420, 14549, 16650 },
+    {   420, 16650, 17249 },
+    {   420, 17249, 19350 },
+    {   450, 40950, 42899 },
+    {   480, 24300, 27149 },
+    {   510, 36255, 36540 },
+    {   595,  3000,  3600 },
+    {   595,  3600,  5909 },
+    {   600,     0, 42899 },
+    {   600, 11235, 11354 },
+    {   600, 12479, 12600 },
+    {   600, 14054, 14265 },
+    {   600, 42899,     0 },
+    {   660, 20730, 21360 },
+    {   709, 37575, 37890 },
+    {   709, 37890, 38010 },
+    {   720, 11354, 12479 },
+    {   720, 32850, 33591 },
+    {   720, 33591, 33960 },
+    {   750,     0,   255 },
+    {   750, 10080, 10380 },
+    {   750, 12600, 13500 },
+    {   750, 38010, 38399 },
+    {   769, 30150, 31050 },
+    {   810, 13500, 14054 },
+    {   840, 21360, 23099 },
+    {   859, 31050, 32850 },
+    {   900, 23099, 24300 },
+    {   930,  8310,  8940 },
+    {   930,  9599, 10080 },
+    {   945, 35699, 36255 },
+    {   945, 36255, 36450 },
+    {   960,  8940,  9599 },
+    {   960, 28650, 28949 },
+    {   970, 34200, 35699 },
+    {  1050, 11190, 11354 },
+    {  1080, 10260, 10380 },
+    {  1110, 33960, 34200 },
+    {  1140,  5909,  6060 },
+    {  1150, 34650, 35699 },
+    {  1170, 37020, 37890 },
+    {  1170, 37890, 38250 },
+    {  1200, 14054, 14189 },
+    {  1230, 36450, 37020 },
+    {  1260,   255,  1530 },
+    {  1264, 33960, 34650 },
+    {  1275, 35699, 36450 },
+    {  1290, 10589, 11190 },
+    {  1320,   120,   255 },
+    {  1320, 28650, 28859 },
+    {  1369, 10260, 10589 },
+    {  1410, 18900, 19350 },
+    {  1410, 38250, 38550 },
+    {  1425,  1290,  1530 },
+    {  1500,  3000,  3450 },
+    {  1530, 19350, 19800 },
+    {  1530, 33960, 34664 },
+    {  1560, 27149, 27329 },
+    {  1560, 27329, 28859 },
+    {  1560, 28859, 29100 },
+    {  1560, 33060, 33960 },
+    {  1620, 29100, 29399 },
+    {  1635,  3450,  4350 },
+    {  1650, 34664, 35400 },
+    {  1680,     0,   120 },
+    {  1680,  2534,  3000 },
+    {  1680, 10589, 11759 },
+    {  1680, 14189, 14400 },
+    {  1680, 37650, 38550 },
+    {  1680, 38550, 39119 },
+    {  1710,  8550, 10589 },
+    {  1710, 17789, 18900 },
+    {  1710, 23850, 24300 },
+    {  1710, 24300, 25124 },
+    {  1740, 19800, 21360 },
+    {  1740, 21360, 21600 },
+    {  1740, 35400, 37650 },
+    {  1800,  8100,  8550 },
+    {  1800, 32715, 33060 },
+    {  1800, 34664, 34844 },
+    {  1840,  4350,  4890 },
+    {  1840,  4890,  6060 },
+    {  1840,  6060,  8100 },
+    {  1845, 25124, 25259 },
+    {  1879,     0, 42750 },
+    {  1920, 22199, 23850 },
+    {  1924, 42300, 42750 },
+    {  1980,  1290,  2534 },
+    {  1980, 27329, 27779 },
+    {  2010, 13950, 14400 },
+    {  2010, 14400, 16650 },
+    {  2010, 16650, 17789 },
+    {  2040,  4620,  4890 },
+    {  2040, 19409, 19800 },
+    {  2040, 21600, 22199 },
+    {  2070, 41070, 41160 },
+    {  2070, 41160, 42300 },
+    {  2100,  2534,  3600 },
+    {  2100, 39600, 41070 },
+    {  2130, 11759, 13260 },
+    {  2130, 13260, 13950 },
+    {  2160,  8100,  8445 },
+    {  2160, 39119, 39375 },
+    {  2160, 39375, 39600 },
+    {  2190, 34844, 34920 },
+    {  2205,  3600,  4530 },
+    {  2205,  4530,  4620 },
+    {  2385, 16650, 17249 },
+    {  2400, 18300, 19409 },
+    {  2400, 27779, 28350 },
+    {  2400, 28350, 29399 },
+    {  2520, 16500, 17249 },
+    {  2520, 17249, 18300 },
+    {  2610, 34500, 34920 },
+    {  2625, 39375, 39434 },
+    {  2640, 39434, 39540 },
+    {  2670, 12240, 13260 },
+    {  2700, 21600, 21749 },
+    {  2760,   300,  1560 },
+    {  2820,  3000,  3675 },
+    {  2820, 15150, 16500 },
+    {  2850, 32715, 32819 },
+    {  2850, 32819, 34349 },
+    {  2850, 34349, 34500 },
+    {  2880,   300, 42449 },
+    {  2880,  1560,  2010 },
+    {  2880, 42449,   300 },
+    {  2910, 24300, 25259 },
+    {  3000,  2010,  2460 },
+    {  3000,  2460,  3000 },
+    {  3000, 11700, 12240 },
+    {  3000, 41999, 42449 },
+    {  3030,  3675,  4530 },
+    {  3030, 30600, 32819 },
+    {  3090, 28350, 30600 },
+    {  3150,  5999,  8445 },
+    {  3150,  8445,  9000 },
+    {  3150, 41160, 41999 },
+    {  3165, 39540, 39839 },
+    {  3180, 21749, 24300 },
+    {  3180, 27450, 28350 },
+    {  3240,  2460,  3060 },
+    {  3240, 10980, 11700 },
+    {  3289, 37080, 39540 },
+    {  3300,  5700,  5999 },
+    {  3300, 39839, 40170 },
+    {  3330, 25259, 25950 },
+    {  3330, 25950, 27450 },
+    {  3330, 34349, 34950 },
+    {  3360,  9000, 10980 },
+    {  3375, 40170, 41160 },
+    {  3420,  4379,  5580 },
+    {  3420,  5580,  5700 },
+    {  3450,  3060,  3434 },
+    {  3480, 34950, 35580 },
+    {  3510,  3434,  4379 },
+    {  3544, 41160, 41700 },
+    {  3570, 35580, 36000 },
+    {  3570, 36000, 36966 },
+    {  3600, 12600, 14340 },
+    {  3600, 14340, 15150 },
+    {  3655, 36966, 37080 },
+    {  3690, 36000, 36750 },
+    {  3720, 10980, 12600 },
+    {  3780, 24300, 25950 },
+    {  3780, 41700, 42449 },
+    {  3840, 21600, 24300 },
+    {  3960,   599, 42449 },
+    {  3960, 25200, 28200 },
+    {  3960, 42449,   599 },
+    {  3990, 20399, 21600 },
+    {  4020, 36750, 37200 },
+    {  4080,  5580,  6150 },
+    {  4200, 23400, 25200 },
+    {  4200, 28200, 29759 },
+    {  4410, 14340, 16500 },
+    {  4410, 16500, 20399 },
+    {  4500, 29759, 31500 },
+    {  4500, 36300, 37200 },
+    {  4620,   599,  6150 },
+    {  4620,  6150,  6314 },
+    {  4620, 20700, 23400 },
+    {  4620, 24449, 23400 },
+    {  4800,  6314,  9000 },
+    {  4800, 19200, 20700 },
+    {  4800, 26100, 24449 },
+    {  4800, 31500, 32400 },
+    {  4800, 36300, 37800 },
+    {  4920, 16500, 19200 },
+    {  5100,  9000, 14400 },
+    {  5160, 32400, 37800 },
+    {  5169, 37800, 41400 },
+    {  5190, 14400, 26100 },
+    {  5280,  6300, 14400 },
+    {  5280, 41400,  6300 },
+};
+
+#define	NDEC	((int)(sizeof(dec_edges)/sizeof(dec_edges[0])))
+
+/* given an epoch, give caller a list of all constellation edges.
+ * return count if ok, else -1.
+ * N.B. caller should *not* free what we return because we cache it here.
+ */
+int
+cns_edges (double e, double **ra0p, double **dec0p, double **ra1p,
+double **dec1p)
+{
+#define	NEDGES	(NRA+NDEC)
+	static double *ra0, *dec0, *ra1, *dec1;
+	static double laste = -12345.6;		/* any bogus value */
+	double mjd0;
+	int i, n;
+
+	/* if same epoch just return the same list */
+	if (e == laste) {
+	    *ra0p = ra0;
+	    *dec0p = dec0;
+	    *ra1p = ra1;
+	    *dec1p = dec1;
+	    return (NEDGES);
+	}
+
+	/* get space for arrays, first time only */
+	if (!ra0) {
+	    ra0 = (double *)malloc (NEDGES * sizeof(double));
+	    if (!ra0)
+		return (-1);
+	    dec0 = (double *)malloc (NEDGES * sizeof(double));
+	    if (!dec0) {
+		free ((void *)ra0);
+		return (-1);
+	    }
+	    ra1 = (double *)malloc (NEDGES * sizeof(double));
+	    if (!ra1) {
+		free ((void *)ra0);
+		free ((void *)dec0);
+		return (-1);
+	    }
+	    dec1 = (double *)malloc (NEDGES * sizeof(double));
+	    if (!dec1) {
+		free ((void *)ra0);
+		free ((void *)dec0);
+		free ((void *)ra1);
+		return (-1);
+	    }
+	}
+
+	/* prepare for precession from 1875 */
+	cal_mjd (1, 1.0, 1875, &mjd0);
+
+	/* build the constant-ra edge lists */
+	n = 0;
+	for (i = 0; i < NRA; i++) {
+	    ra0[n] = ra1[n] = hrrad((double)ra_edges[i].ra/1800.0);
+	    dec0[n] = degrad((double)ra_edges[i].dec0/60.0);
+	    dec1[n] = degrad((double)ra_edges[i].dec1/60.0);
+	    precess (mjd0, e, &ra0[n], &dec0[n]);
+	    precess (mjd0, e, &ra1[n], &dec1[n]);
+	    n++;
+	}
+
+	/* add the constant-dec edge lists */
+	for (i = 0; i < NDEC; i++) {
+	    ra0[n] = hrrad((double)dec_edges[i].ra0/1800.0);
+	    ra1[n] = hrrad((double)dec_edges[i].ra1/1800.0);
+	    dec0[n] = dec1[n] = degrad((double)dec_edges[i].dec/60.0);
+	    precess (mjd0, e, &ra0[n], &dec0[n]);
+	    precess (mjd0, e, &ra1[n], &dec1[n]);
+	    n++;
+	}
+
+	/* sanity check the count */
+	if (n != NEDGES) {
+	    printf ("cns_edges(): n=%d NEDGES=%ld\n", n, (long)NEDGES);
+	    abort();
+	}
+	
+	/* ok */
+	*ra0p = ra0;
+	*dec0p = dec0;
+	*ra1p = ra1;
+	*dec1p = dec1;
+	laste = e;
+	return (NEDGES);
+}
+
+/* given an ra, dec and epoch return the list of constellation ids which
+ * *may* fall within the given radius of said location.
+ * return the number of ids.
+ * ids[] need be no larger than 89.
+ */
+/* ARGSUSED */
+int
+cns_list (double ra, double dec, double e, double rad, int ids[])
+{
+	int i;
+
+	/* TODO: this! */
+	for (i = 0; i < NCNS; i++)
+	    ids[i] = i;
+	return (NCNS);
+}
+
+/* epoch 2000 RA/Dec of constellation figure end-points.
+ * drawcodes: 0=move to; 1=draw to; 2=draw to dashed; -1=end
+ */
+typedef struct {
+    int drawcode;	/* draw code */
+    float ra;		/* rads */
+    float dec;		/* rads */
+} ConFig;
+
+/* array of malloced lists of ConFigs, same order as cns_namemap[]
+ */
+static ConFig *figmap[NCNS];
+
+/* add one entry to the drawing code lists */
+static void
+addFigList (ConFig **new, int *nused, int c, int drawcode, double ra, double dec)
+{
+	ConFig *cp;
+
+	new[c]= (ConFig*) realloc (new[c], (nused[c]+1)*sizeof(ConFig));
+	cp = &new[c][nused[c]++];
+	cp->drawcode = drawcode;
+	cp->ra = (float)hrrad(ra);
+	cp->dec = (float)degrad(dec);
+}
+
+/* load the given constellation definition file.
+ * return 0 if ok else reason why not in msg[] and -1.
+ */
+int
+cns_loadfigs (FILE *fp, char *msg)
+{
+	char line[1024];		/* one line from the file */
+	char cname[1024];		/* constellation name */
+	ConFig **new;			/* array of ConFig[] for each cnstn */
+	int *nused;			/* number of ConFig[] for each cnstn */
+	int c = -1;			/* index, same as cns_namemap[] */
+	int s = 0;			/* status */
+
+	/* init the temp lists */
+	new = (ConFig **) calloc (NCNS, sizeof(ConFig*));
+	nused = (int *) calloc (NCNS, sizeof(int));
+
+	/* read the file */
+	while (fgets (line, sizeof(line), fp)) {
+	    char rastr[64], decstr[64];
+	    char *lp;
+	    int code;
+
+	    /* skip leading/trailing whitespace, blank lines and # lines */
+	    for (lp = line+strlen(line)-1; lp>=line && isspace(*lp); --lp)
+		*lp = '\0';
+	    for (lp = line; isspace(*lp); lp++)
+		continue;
+	    if (*lp == '#' || *lp == '\0')
+		continue;
+
+	    /* ok, line looks interesting, look more carefully */
+	    if (sscanf (lp, "%d %s %s", &code, rastr, decstr) == 3) {
+		/* looks like a drawing line */
+		double ra, dec;
+
+		/* must be working on a current constellation */
+		if (c < 0) {
+		    sprintf (msg,"Found coord line before first constellation");
+		    s = -1;
+		    break;
+		}
+
+		/* check draw code */
+		if (code < 0 || code > 2) {
+		    sprintf (msg, "Bad draw code in %s: %d", cname, code);
+		    s = -1;
+		    break;
+		}
+
+		/* crack ra dec */
+		if (f_scansexa (rastr, &ra) < 0 || ra < 0 || ra >= 24) {
+		    sprintf (msg, "Bad RA format in %s: %s", cname, rastr);
+		    s = -1;
+		    break;
+		}
+		if (f_scansexa (decstr, &dec) < 0 || dec < -90 || dec > 90) {
+		    sprintf (msg, "Bad Dec format in %s: %s", cname, decstr);
+		    s = -1;
+		    break;
+		}
+
+		/* add to list */
+		addFigList (new, nused, c, code, ra, dec);
+
+	    } else {
+		/* finish previous list, if any */
+		if (c >= 0)
+		    addFigList (new, nused, c, -1, 0.0, 0.0);
+
+		/* see if it's a recognized constellation name */
+		for (c = 0; c < NCNS; c++)
+		    if (strcmp (lp, cns_namemap[c]+5) == 0)
+			break;
+		if (c == NCNS) {
+		    sprintf (msg, "Unknown constellation: %s", lp);
+		    s = -1;
+		    break;
+		}
+		if (new[c]) {
+		    sprintf (msg, "Duplicate definition for %s", lp);
+		    s = -1;
+		    break;
+		}
+
+		/* init its list */
+		strcpy (cname, lp);
+		new[c] = (ConFig *) malloc (1);     /* realloc seed */
+	    }
+	}
+
+	/* even if ok check we found all definitions */
+	if (s == 0) {
+	    int l = 0;
+
+	    /* finish last list */
+	    addFigList (new, nused, c, -1, 0.0, 0.0);
+
+	    for (c = 0; c < NCNS; c++)
+		if (!new[c])
+		    l += sprintf (msg+l, "%s ", cns_namemap[c]+5);
+	    if (l > 0) {
+		strcat (msg, ": no definition found");
+		s = -1;
+	    }
+	}
+
+	/* handle ok or error */
+	if (s < 0) {
+	    /* trouble: free temp lists */
+	    for (c = 0; c < NCNS; c++)
+		if (new[c])
+		    free (new[c]);
+	} else {
+	    /* make temp lists persistent */
+	    for (c = 0; c < NCNS; c++) {
+		if (figmap[c])
+		    free (figmap[c]);
+		figmap[c] = new[c];
+	    }
+	}
+
+	/* done with lists themselves regardless */
+	free (new);
+	free (nused);
+
+	/* done */
+	return (s);
+}
+
+/* given a constellation id and epoch, return arrays of ra[] and dec[]
+ *   end-points precessed to the desired epoch that, if connected, will form the
+ *   given constellation figure.
+ * dcodes is 0 if the coord is a "move-to", 1 if a "draw-to" or 2 if a "draw-to
+ *   as dotted-line".
+ * return the total number of tripples or -1 if id is bogus.
+ * the arrays need be no larger than 35 entries.
+ */
+int
+cns_figure (int id, double e, double ra[], double dec[], int dcodes[])
+{
+	ConFig *cfp;
+
+	if (id < 0 || id >= NCNS)
+	    return (-1);
+
+	for (cfp = figmap[id]; cfp->drawcode >= 0; cfp++) {
+	    *ra = (double)cfp->ra;
+	    *dec = (double)cfp->dec;
+	    precess (J2000, e, ra, dec);
+	    ra++;
+	    dec++;
+	    *dcodes++ = cfp->drawcode;
+	}
+
+	return (cfp - figmap[id]);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: constel.c,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/create_smakefile.csh
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/create_smakefile.csh	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/create_smakefile.csh	(revision 3445)
@@ -0,0 +1,47 @@
+#!/bin/csh
+
+rm -f smakefile Makefile maketemp
+touch smakefile Makefile maketemp
+
+set inc = ( *.h )
+set src = ( `ls -1 *.c | grep -v testxephem` )
+set obj
+foreach f ( $src )
+  set obj = ( $obj ${f:r}.o )
+end
+
+echo '' >> maketemp
+echo 'all: libxastro.a' >> maketemp
+echo '' >> maketemp
+echo 'clean:' >> maketemp
+echo '	rm -f libxastro.a *.o testxephem' >> maketemp
+echo '' >> maketemp
+echo 'OBJASTRO = '${obj} >> maketemp
+echo '' >> maketemp
+echo 'libxastro.a : $(OBJASTRO)' >> maketemp
+echo '	$(AR) $(ARFLAGS) $@ $?' >> maketemp
+echo '' >> maketemp
+
+foreach f ( $obj )
+  set c = ${f:r}.c
+  echo "${f}: ${c} ${inc}" >> maketemp
+  echo '	$(CCOMPILE) -o $@' $c >> maketemp
+  echo '' >> maketemp
+end
+
+echo 'testxephem: testxephem.o' >> maketemp
+echo '	$(CLINK) -o $@ testxephem.o -L./ -lxastro -lc -lm' >> maketemp
+echo '' >> maketemp
+echo "testxephem.o: testxephem.c astro.h" >> maketemp
+echo '	$(CCOMPILE) -o $@ testxephem.c'  >> maketemp
+echo '' >> maketemp
+
+echo 'include $(SOPHYABASE)/include/sophyamake.inc' >> smakefile
+cat maketemp >> smakefile
+
+echo 'include ../BuildMgr/sophyamake.inc' >> Makefile
+cat maketemp >> Makefile
+
+rm -f maketemp
+
+exit 0
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/dbfmt.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/dbfmt.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/dbfmt.c	(revision 3445)
@@ -0,0 +1,998 @@
+/* code to convert between .edb format and an Obj */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "astro.h"
+#include "preferences.h"
+
+
+int get_fields (char *s, int delim, char *fields[]);
+
+#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 */
+
+static char *enm (char *flds[MAXFLDS]);
+static int crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
+static int crack_name (Obj *op, char *flds[MAXFLDS], int nf,
+    char nm[][MAXNM], int nnm);
+static void crack_year (char *bp, double *p);
+static void crack_okdates (char *fld, float *startok, float *endok);
+static int get_okdates (char *lp, float *sp, float *ep);
+static int tle_sum (char *l);
+static double tle_fld (char *l, int from, int thru);
+static double tle_expfld (char *l, int start);
+static void write_f (Obj *op, char lp[]);
+static void write_e (Obj *op, char lp[]);
+static void write_h (Obj *op, char lp[]);
+static void write_p (Obj *op, char lp[]);
+static void write_E (Obj *op, char lp[]);
+static void write_P (Obj *op, char lp[]);
+static void write_B (Obj *op, char lp[]);
+
+/* crack the given .edb database line into op.
+ * if ok
+ *   return number of names in nm[], or 1 if nm == NULL
+ * else
+ *   if whynot
+ *     if not even a candidate
+ *       set whynot[0] = '\0'
+ *     else
+ *       fill whynot with reason message.
+ *   return -1
+ * only the first name is stored in op, all names (up to nnm) are in nm[], or
+ *   ignored if nm == NULL.
+ */
+int
+db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[])
+{
+	char copy[MAXDBLINE];	/* work copy; leave s untouched */
+	char *flds[MAXFLDS];	/* point to each field for easy reference */
+	int nf;
+	int i;
+
+	/* init no response */
+	if (whynot)
+	    whynot[0] = '\0';
+
+	/* basic initial check */
+	if (dbline_candidate (s) < 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, "Bogus: %s", s);
+	    return (-1);
+	}
+
+	/* switch out on type of object - the second field */
+	switch (flds[1][0]) {
+
+	case 'f':
+	    if (crack_f (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'e':
+	    if (crack_e (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'h':
+	    if (crack_h (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'p':
+	    if (crack_p (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'B':
+	    if (crack_B (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'E':
+	    if (crack_E (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	case 'P':
+	    if (crack_P (op, flds, nf, whynot) < 0)
+		return (-1);
+	    break;
+
+	default:
+	    if (whynot)
+		sprintf (whynot, "%s: Unknown type %c for %s", enm(flds),
+							flds[1][0], flds[0]);
+	    return (-1);
+	}
+
+	return (crack_name (op, flds, nf, nm, nnm));
+}
+
+/* write the given Obj in .edb format to lp[].
+ * we do _not_ include a trailing '\n'.
+ */
+void
+db_write_line (Obj *op, char lp[])
+{
+	switch (op->o_type) {
+	case FIXED:
+	    write_f (op, lp);
+	    break;
+
+	case BINARYSTAR:
+	    write_B (op, lp);
+	    break;
+
+	case ELLIPTICAL:
+	    write_e (op, lp);
+	    break;
+
+	case HYPERBOLIC:
+	    write_h (op, lp);
+	    break;
+
+	case PARABOLIC:
+	    write_p (op, lp);
+	    break;
+
+	case EARTHSAT:
+	    write_E (op, lp);
+	    break;
+
+	case PLANET:
+	    write_P (op, lp);
+	    break;
+
+	default:
+	    printf ("Unknown type for %s: %d\n", op->o_name, op->o_type);
+	    abort();
+	}
+}
+
+/* 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 (char *name, char *l1, char *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);
+	op->es_decay = (float) tle_fld (l1, 34, 43);
+	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);
+}
+
+/* return 0 if op has no date range information or what it does have brackets
+ * now, else -1
+ */
+int
+dateRangeOK (Now *np, Obj *op)
+{
+	float *sp, *ep;
+
+	switch (op->o_type) {
+	case ELLIPTICAL:
+	    sp = &op->e_startok;
+	    ep = &op->e_endok;
+	    break;
+	case HYPERBOLIC:
+	    sp = &op->h_startok;
+	    ep = &op->h_endok;
+	    break;
+	case PARABOLIC:
+	    sp = &op->p_startok;
+	    ep = &op->p_endok;
+	    break;
+	case EARTHSAT:
+	    sp = &op->es_startok;
+	    ep = &op->es_endok;
+	    break;
+	default:
+	    return (0);
+	}
+
+	if (*sp <= mjd && (!*ep || mjd <= *ep))
+	    return (0);
+	return (-1);
+}
+
+/* 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 (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);
+}
+
+/* return 0 if buf qualifies as a database line worthy of a cracking
+ * attempt, else -1.
+ */
+int
+dbline_candidate (char *buf)
+{
+	char c = buf[0];
+
+	return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
+}
+
+/* return 0 if TLE checksum is ok, else -1 */
+static int
+tle_sum (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 (char *l, int from, int 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 (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);
+}
+
+static int
+crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	char *sflds[MAXFLDS];
+	double tmp;
+	int nsf;
+
+	if (nf < 5 || nf > 7) {
+	    if (whynot)
+		sprintf (whynot, "%s: type f needs 5-7 fields, not %d",
+								enm(flds),nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjF));
+	op->o_type = FIXED;
+
+	nsf = get_fields(flds[1], SUBFLD, sflds);
+	if (nsf > 1) {
+	    switch (sflds[1][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': case 'Y':
+		op->f_class = sflds[1][0];
+		if (op->f_class == 'B')
+		    op->f_class = 'D';	/* merge B and D since BINARYSTAR */
+		break;
+	    default:
+		if (whynot)
+		    sprintf (whynot, "%s: Bad f class: %c", enm(flds),
+		    						sflds[1][0]);
+		return (-1);
+	    }
+	} else
+	    op->f_class = 'T';		/* default to star-like */
+	if (nsf > 2) {
+	    /* fill f_spect all the way */
+	    char buf[sizeof(op->f_spect)+1];
+	    memset (buf, 0, sizeof(buf));
+	    sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
+	    memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
+	}
+
+	nsf = get_fields(flds[2], SUBFLD, sflds);
+	f_scansexa (sflds[0], &tmp);
+	op->f_RA = (float) hrrad(tmp);
+	if (nsf > 1)
+	    op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
+
+	nsf = get_fields(flds[3], SUBFLD, sflds);
+	f_scansexa (sflds[0], &tmp);
+	op->f_dec = (float) degrad(tmp);
+	if (nsf > 1)
+	    op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
+	if (fabs(op->f_dec) < PI/2)
+	    op->f_pmRA /= cos (op->f_dec);
+
+	set_fmag (op, atod(flds[4]));
+
+	if (nf > 5 && flds[5][0]) {
+	    tmp = op->f_epoch;
+	    crack_year (flds[5], &tmp);
+	    op->f_epoch = (float) tmp;
+	} else
+	    op->f_epoch = J2000;	/* default */
+
+	if (nf > 6) {
+	    op->f_size = (float) atod(flds[6]);
+
+	    /* optional minor axis and position angle subfields */
+	    nsf = get_fields(flds[6], 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);
+	    }
+	}
+
+	return (0);
+}
+
+static int
+crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	if (nf != 13 && nf != 14) {
+	    if (whynot)
+		sprintf (whynot, "%s: type e needs 13 or 14 fields, not %d",
+								enm(flds), nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjE));
+	op->o_type = ELLIPTICAL;
+
+	op->e_inc = (float) atod (flds[2]);
+	op->e_Om = (float) atod (flds[3]);
+	op->e_om = (float) atod (flds[4]);
+	op->e_a = (float) atod (flds[5]);
+	/* retired op->e_n = (float) atod (flds[6]); */
+	op->e_e = atod (flds[7]);
+	op->e_M = (float) atod (flds[8]);
+	crack_year (flds[9], &op->e_cepoch);
+	crack_okdates (flds[9], &op->e_startok, &op->e_endok);
+	crack_year (flds[10], &op->e_epoch);
+
+	/* magnitude model gk or HG(default). allow prefixes in either field */
+	op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG;
+	if (isdigit(flds[11][0]))
+	    op->e_mag.m1 = (float) atod(&flds[11][0]);
+	else
+	    op->e_mag.m1 = (float) atod(&flds[11][1]);
+	if (isdigit(flds[12][0]))
+	    op->e_mag.m2 = (float) atod(&flds[12][0]);
+	else
+	    op->e_mag.m2 = (float) atod(&flds[12][1]);
+
+	if (nf == 14)
+	    op->e_size = (float) atod (flds[13]);
+
+	return (0);
+}
+
+static int
+crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	if (nf != 11 && nf != 12) {
+	    if (whynot)
+		sprintf (whynot, "%s: type h needs 11 or 12 fields, not %d",
+								enm(flds), nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjH));
+	op->o_type = HYPERBOLIC;
+
+	crack_year (flds[2], &op->h_ep);
+	crack_okdates (flds[2], &op->h_startok, &op->h_endok);
+	op->h_inc = (float) atod (flds[3]);
+	op->h_Om = (float) atod (flds[4]);
+	op->h_om = (float) atod (flds[5]);
+	op->h_e = (float) atod (flds[6]);
+	op->h_qp = (float) atod (flds[7]);
+	crack_year (flds[8], &op->h_epoch);
+	op->h_g = (float) atod (flds[9]);
+	op->h_k = (float) atod (flds[10]);
+
+	if (nf == 12)
+	    op->h_size = (float) atod (flds[11]);
+
+	return (0);
+}
+
+static int
+crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	if (nf != 10 && nf != 11) {
+	    if (whynot)
+		sprintf (whynot, "%s: type p needs 10 or 11 fields, not %d",	
+								enm(flds), nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjP));
+	op->o_type = PARABOLIC;
+
+	crack_year (flds[2], &op->p_ep);
+	crack_okdates (flds[2], &op->p_startok, &op->p_endok);
+	op->p_inc = (float) atod (flds[3]);
+	op->p_om = (float) atod (flds[4]);
+	op->p_qp = (float) atod (flds[5]);
+	op->p_Om = (float) atod (flds[6]);
+	crack_year (flds[7], &op->p_epoch);
+	op->p_g = (float) atod (flds[8]);
+	op->p_k = (float) atod (flds[9]);
+
+	if (nf == 11)
+	    op->p_size = (float) atod (flds[10]);
+
+	return (0);
+}
+
+static int
+crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	if (nf != 11 && nf != 12) {
+	    if (whynot)
+		sprintf (whynot, "%s: type E needs 11 or 12 fields, not %d",
+							    enm(flds), nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjES));
+	op->o_type = EARTHSAT;
+	crack_year (flds[2], &op->es_epoch);
+	crack_okdates (flds[2], &op->es_startok, &op->es_endok);
+	op->es_inc = (float) atod (flds[3]);
+	op->es_raan = (float) atod (flds[4]);
+	op->es_e = (float) atod (flds[5]);
+	op->es_ap = (float) atod (flds[6]);
+	op->es_M = (float) atod (flds[7]);
+	op->es_n = atod (flds[8]);
+	op->es_decay = (float) atod (flds[9]);
+	op->es_orbit = atoi (flds[10]);
+	if (nf == 12)
+	    op->es_drag = (float) atod (flds[11]);
+
+	return (0);
+}
+
+static int
+crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	Obj *bi;
+	int nbi;
+	int i;
+
+	nbi = getBuiltInObjs (&bi);
+
+	for (i = 0; i < nbi; i++) {
+	    Obj *bop = bi + i;
+	    if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) {
+		memcpy ((void *)op, bop, sizeof(ObjPl));
+		return (0);
+	    }
+	}
+
+	if (whynot)
+	    sprintf (whynot, "%s: Unknown planet or moon", enm(flds));
+	return (-1);
+}
+
+static int
+crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
+{
+	char *sflds[MAXFLDS];
+	double tmp;
+	int nsf;
+
+	if (nf != 7) {
+	    if (whynot)
+		sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf);
+	    return (-1);
+	}
+
+	zero_mem ((void *)op, sizeof(ObjB));
+	op->o_type = BINARYSTAR;
+
+	nsf = get_fields(flds[1], SUBFLD, sflds);
+	if (nsf > 1) {
+	    switch (sflds[1][0]) {
+	    case 'a': case 'c': case 'e': case 'x': case 'y': case 'o':
+	    case 's': case 't': case 'u': case 'v': case 'b': case 'd':
+	    case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y':
+		op->f_class = sflds[1][0];
+		break;
+	    default:
+		if (whynot)
+		    sprintf (whynot, "%s: Bad B class: %c", enm(flds),
+		    						sflds[1][0]);
+		return (-1);
+	    }
+	}
+	if (nsf > 2) {
+	    /* fill f_spect all the way */
+	    char buf[sizeof(op->f_spect)+1];
+	    memset (buf, 0, sizeof(buf));
+	    sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
+	    memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
+	}
+	if (nsf > 3) {
+	    /* fill b_2spect all the way */
+	    char buf[sizeof(op->b_2spect)+1];
+	    memset (buf, 0, sizeof(buf));
+	    sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]);
+	    memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect));
+	}
+
+	nsf = get_fields(flds[2], SUBFLD, sflds);
+	f_scansexa (sflds[0], &tmp);
+	op->f_RA = (float) hrrad(tmp);
+	if (nsf > 1)
+	    op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
+
+	nsf = get_fields(flds[3], SUBFLD, sflds);
+	f_scansexa (sflds[0], &tmp);
+	op->f_dec = (float) degrad(tmp);
+	if (nsf > 1)
+	    op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
+	if (fabs(op->f_dec) < PI/2)
+	    op->f_pmRA /= cos (op->f_dec);
+
+	nsf = get_fields(flds[4], SUBFLD, sflds);
+	if (nsf > 0)
+	    set_fmag (op, atod(sflds[0]));
+	if (nsf > 1)
+	    op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5);
+
+	if (flds[5][0]) {
+	    tmp = op->f_epoch;
+	    crack_year (flds[5], &tmp);
+	    op->f_epoch = (float) tmp;
+	} else
+	    op->f_epoch = J2000;	/* default */
+
+	nsf = get_fields(flds[6], SUBFLD, sflds);
+	if (nsf == 7) {
+	    int l;
+	    char c;
+
+	    op->b_bo.bo_a = atod(sflds[0]);
+	    op->b_bo.bo_i = atod(sflds[1]);
+	    op->b_bo.bo_O = atod(sflds[2]);
+	    op->b_bo.bo_e = atod(sflds[3]);
+	    op->b_bo.bo_T = atod(sflds[4]);
+	    op->b_bo.bo_o = atod(sflds[5]);
+	    op->b_bo.bo_P = atod(sflds[6]);
+
+	    /* reject some weird entries actually seen in real lists */
+	    if (op->b_bo.bo_a <= 0) {
+		if (whynot)
+		    sprintf (whynot, "%s: Bogus B semi major axis: %g",
+						    enm(flds), op->b_bo.bo_a);
+		return (-1);
+	    }
+	    if (op->b_bo.bo_P <= 0) {
+		if (whynot)
+		    sprintf (whynot, "%s: Bogus B period: %g", enm(flds),
+		    						op->b_bo.bo_P);
+		return (-1);
+	    }
+
+	    /* scale period */
+	    l = strlen (sflds[6]);
+	    c = sflds[6][l-1];
+	    switch (c) {
+	    case 'y': case 'Y':
+		break;
+	    case 'h': case 'H':
+		op->b_bo.bo_P /= (24.0*365.25);
+		break;
+	    case 'd': case 'D':
+		op->b_bo.bo_P /= 365.25;
+		break;
+	    default:
+		if (c != ' ' && !isdigit(c)) {
+		    if (whynot)
+			sprintf (whynot,"%s: B period suffix not Y, D or H: %c",
+								enm(flds), c);
+		    return (-1);
+		}
+	    }
+
+	} else if (nsf==3 || nsf==6 || nsf==9) {
+	    double yr;
+	    int i;
+
+	    op->b_nbp = nsf/3;
+	    for (i = 0; i < nsf; i += 3) {
+		tmp = 0;
+		crack_year (sflds[i+0], &tmp);
+		mjd_year (tmp, &yr);
+		op->b_bp[i/3].bp_ep = (float)yr;
+		op->b_bp[i/3].bp_sep = atod(sflds[i+1]);
+		op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2]));
+	    }
+	} else {
+	    if (whynot)
+		sprintf (whynot,
+		       "%s: type B needs 3,6 or 7 subfields in field 7, not %d",
+								enm(flds), nsf);
+	    return (-1);
+	}
+
+	return (0);
+}
+
+/* put all names in nm but load only the first into o_name */
+static int
+crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm)
+{
+	char *sflds[MAXFLDS];
+	int nsf;
+	int i;
+	
+	nsf = get_fields (flds[0], SUBFLD, sflds);
+	for (i = 0; nm && i < nsf && i < nnm; i++) {
+	    strncpy (nm[i], sflds[i], MAXNM);
+	    nm[i][MAXNM-1] = '\0';
+	}
+	strncpy (op->o_name, sflds[0], MAXNM-1);
+	return (nsf);
+}
+
+/* simple name cracker just for error messages */
+static char *
+enm (char *flds[MAXFLDS])
+{
+	char *sflds[MAXFLDS];
+	int nsf = get_fields (flds[0], SUBFLD, sflds);
+	return (nsf > 0 ? sflds[0] : "Unknown");
+}
+
+/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date
+ * convert it to an mjd and store it at *p.
+ */
+static void
+crack_year (char *bp, double *p)
+{
+	int m, y;
+	double d;
+
+	mjd_cal (*p, &m, &d, &y);	/* init with current */
+	f_sscandate (bp, PREF_MDY, &m, &d, &y);
+	cal_mjd (m, d, y, p);
+}
+
+/* crack the startok and endok date fields found in several Obj types.
+ * set to 0 if blank or any problems.
+ */
+static void
+crack_okdates (char *fld, float *startok, float *endok)
+{
+	char *sflds[MAXFLDS];
+	double tmp;
+	int m, y;
+	double d;
+	int nsf;
+
+	*startok = *endok = 0;
+	nsf = get_fields(fld, SUBFLD, sflds);
+	if (nsf > 1) {
+	    d = m = y = 0;
+	    f_sscandate (sflds[1], PREF_MDY, &m, &d, &y);
+	    cal_mjd (m, d, y, &tmp);
+	    *startok = (float)tmp;
+	    if (nsf > 2) {
+		d = m = y = 0;
+		f_sscandate (sflds[2], PREF_MDY, &m, &d, &y);
+		cal_mjd (m, d, y, &tmp);
+		*endok = (float)tmp;
+	    }
+	}
+}
+
+/* add startok and endok to string at lp if non-zero.
+ * return number of characters added.
+ */
+static int
+get_okdates (char *lp, float *sp, float *ep)
+{
+	char *lp0 = lp;
+
+	if (*sp || *ep) {
+	    *lp++ = '|';
+	    if (*sp)
+		lp += fs_date (lp, PREF_MDY, *sp);
+	    if (*ep) {
+		*lp++ = '|';
+		lp += fs_date (lp, PREF_MDY, *ep);
+	    }
+	}
+
+	return (lp - lp0);
+}
+
+static void
+write_f (Obj *op, char lp[])
+{
+	double tmp;
+
+	lp += sprintf (lp, "%s,f", op->o_name);
+	if (op->f_class)
+	    lp += sprintf (lp, "|%c", op->f_class);
+	if (op->f_spect[0])
+	    lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
+	*lp++ = ',';
+	lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
+	if (op->f_pmRA)
+	    lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
+	*lp++ = ',';
+	lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
+	if (op->f_pmdec)
+	    lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
+	lp += sprintf (lp, ",%.2f", get_mag(op));
+	mjd_year (op->f_epoch, &tmp);
+	lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
+	lp += sprintf (lp, ",%.7g", op->f_size);
+	if (op->f_size && (op->f_ratio || op->f_pa))
+	    lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op),
+							    raddeg(get_pa(op)));
+}
+
+static void
+write_e (Obj *op, char lp[])
+{
+	lp += sprintf (lp, "%s,e", op->o_name);
+	lp += sprintf (lp, ",%.7g", op->e_inc);
+	lp += sprintf (lp, ",%.7g", op->e_Om);
+	lp += sprintf (lp, ",%.7g", op->e_om);
+	lp += sprintf (lp, ",%.7g", op->e_a);
+	lp += sprintf (lp, ",%.7g", 0.0);		/* retired op->e_n */
+	lp += sprintf (lp, ",%.7g", op->e_e);
+	lp += sprintf (lp, ",%.7g", op->e_M);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->e_cepoch);
+	lp += get_okdates (lp, &op->e_startok, &op->e_endok);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->e_epoch);
+	if (op->e_mag.whichm == MAG_gk)
+	    lp += sprintf (lp, ",g%.7g", op->e_mag.m1);
+	else if (op->e_mag.whichm == MAG_HG)
+	    lp += sprintf (lp, ",H%.7g", op->e_mag.m1);
+	else
+	    lp += sprintf (lp, ",%.7g", op->e_mag.m1);
+	lp += sprintf (lp, ",%.7g", op->e_mag.m2);
+	lp += sprintf (lp, ",%.7g", op->e_size);
+}
+
+static void
+write_h (Obj *op, char lp[])
+{
+	lp += sprintf (lp, "%s,h", op->o_name);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->h_ep);
+	lp += get_okdates (lp, &op->h_startok, &op->h_endok);
+	lp += sprintf (lp, ",%.7g", op->h_inc);
+	lp += sprintf (lp, ",%.7g", op->h_Om);
+	lp += sprintf (lp, ",%.7g", op->h_om);
+	lp += sprintf (lp, ",%.7g", op->h_e);
+	lp += sprintf (lp, ",%.7g", op->h_qp);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->h_epoch);
+	lp += sprintf (lp, ",%.7g", op->h_g);
+	lp += sprintf (lp, ",%.7g", op->h_k);
+	lp += sprintf (lp, ",%.7g", op->h_size);
+}
+
+static void
+write_p (Obj *op, char lp[])
+{
+	lp += sprintf (lp, "%s,p", op->o_name);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->p_ep);
+	lp += get_okdates (lp, &op->p_startok, &op->p_endok);
+	lp += sprintf (lp, ",%.7g", op->p_inc);
+	lp += sprintf (lp, ",%.7g", op->p_om);
+	lp += sprintf (lp, ",%.7g", op->p_qp);
+	lp += sprintf (lp, ",%.7g", op->p_Om);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->p_epoch);
+	lp += sprintf (lp, ",%.7g", op->p_g);
+	lp += sprintf (lp, ",%.7g", op->p_k);
+	lp += sprintf (lp, ",%.7g", op->p_size);
+}
+
+static void
+write_E (Obj *op, char lp[])
+{
+	lp += sprintf (lp, "%s,E", op->o_name);
+	*lp++ = ',';
+	lp += fs_date (lp, PREF_MDY, op->es_epoch);
+	lp += get_okdates (lp, &op->es_startok, &op->es_endok);
+	lp += sprintf (lp, ",%.7g", op->es_inc);
+	lp += sprintf (lp, ",%.7g", op->es_raan);
+	lp += sprintf (lp, ",%.7g", op->es_e);
+	lp += sprintf (lp, ",%.7g", op->es_ap);
+	lp += sprintf (lp, ",%.7g", op->es_M);
+	lp += sprintf (lp, ",%.7g", op->es_n);
+	lp += sprintf (lp, ",%.7g", op->es_decay);
+	lp += sprintf (lp, ",%d", op->es_orbit);
+	lp += sprintf (lp, ",%.7g", op->es_drag);
+}
+
+static void
+write_B (Obj *op, char lp[])
+{
+	double tmp;
+
+	lp += sprintf (lp, "%s,B", op->o_name);
+	if (op->f_class)
+	    lp += sprintf (lp, "|%c", op->f_class);
+	if (op->f_spect[0])
+	    lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
+	if (op->b_2spect[0])
+	    lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect);
+	*lp++ = ',';
+	lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
+	if (op->f_pmRA)
+	    lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
+	*lp++ = ',';
+	lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
+	if (op->f_pmdec)
+	    lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
+	lp += sprintf (lp, ",%.2f", get_mag(op));
+	lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE);
+	mjd_year (op->f_epoch, &tmp);
+	lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
+	if (op->b_nbp == 0) {
+	    lp += sprintf (lp, ",%.6g",  op->b_bo.bo_a);
+	    lp += sprintf (lp, "|%.6g",  op->b_bo.bo_i);
+	    lp += sprintf (lp, "|%.6g",  op->b_bo.bo_O);
+	    lp += sprintf (lp, "|%.6g",  op->b_bo.bo_e);
+	    lp += sprintf (lp, "|%.6g",  op->b_bo.bo_T);
+	    lp += sprintf (lp, "|%.6g",  op->b_bo.bo_o);
+	    lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P);
+	} else {
+	    int i;
+
+	    for (i = 0; i < op->b_nbp; i++) {
+		BinPos *bp = &op->b_bp[i];
+		lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep);
+		lp += sprintf (lp, "|%.6g", bp->bp_sep);
+		lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa));
+	    }
+	}
+}
+
+static void
+write_P (Obj *op, char lp[])
+{
+
+	lp += sprintf (lp, "%s,P", op->o_name);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2006-11-22 13:53:28 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/deep.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/deep.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/deep.c	(revision 3445)
@@ -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: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/deepconst.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/deepconst.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/deepconst.h	(revision 3445)
@@ -0,0 +1,34 @@
+#ifndef _CONST_H
+#define _CONST_H
+
+/* $Id: deepconst.h,v 1.6 2006-11-22 13:53:29 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: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/deltat.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/deltat.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/deltat.c	(revision 3445)
@@ -0,0 +1,305 @@
+/* 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 mj (modified julian date from MJD0 on). [stern]
+ *  Note that xephem uses a different epoch for this "mj" than the
+ *  normal value of JD=240000.5.
+ * See AA page B4.
+ *
+ * Output double deltat(mj) 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 mj 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 lastmj cache (made ans static)
+ *
+ *   - no changes to table interpolation scheme and past extrapolations */
+
+#include <math.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 */
+     /* 6440, 6510, 6600, 6750, 6900, 7060 */
+     6409, 6430, 6447, 6507, 6578, 6610	/* ECD */
+
+    /* 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(double mj)
+{
+	double Y;
+	double p, B;
+	int d[6];
+	int i, iy, k;
+	static double ans;
+	static double lastmj = -10000;
+
+	if (mj == lastmj) {
+	    return(ans);
+	}
+	lastmj = mj;
+
+	Y = 2000.0 + (mj - J2000)/365.25;
+
+	if( Y > TABEND) {
+	    /* linear interpolation from table end; stern */
+	    B = Y - TABEND;
+	    ans = dt[TABSIZ-1] + B * (dt[TABSIZ-1]  - dt[TABSIZ-11])/10;
+	    ans *= 0.01;
+	    return(ans);
+	}
+
+	if( Y < TABSTART) {
+	    if( Y >= 948.0 - 15.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: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/earthsat.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/earthsat.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/earthsat.c	(revision 3445)
@@ -0,0 +1,786 @@
+/* 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>
+#include <stdlib.h>
+
+#include "astro.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 int crazyOp (Now *np, Obj *op);
+static void esat_prop (Now *np, Obj *op, double *SatX, double *SatY, double
+    *SatZ, double *SatVX, double *SatVY, double *SatVZ);
+static void GetSatelliteParams (Obj *op);
+static void GetSiteParams (Now *np);
+static double Kepler (double MeanAnomaly, double Eccentricity);
+static void GetSubSatPoint (double SatX, double SatY, double SatZ,
+    double T, double *Latitude, double *Longitude, double *Height);
+static void GetSatPosition (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 (double SiteLat, double SiteLong,
+    double SiteElevation, double CrntTime, double *SiteX, double *SiteY,
+    double *SiteZ, double *SiteVX, double *SiteVY, MAT3x3 SiteMatrix);
+static void GetRange (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 (double SatX, double SatY, double SatZ,
+    double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *X,
+    double *Y, double *Z);
+static void GetBearings (double SatX, double SatY, double SatZ,
+    double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix,
+    double *Azimuth, double *Elevation);
+static int Eclipsed (double SatX, double SatY, double SatZ,
+    double SatRadius, double CrntTime);
+static void InitOrbitRoutines (double EpochDay, int AtEod);
+
+#ifdef USE_ORBIT_PROPAGATOR 
+static void GetPrecession (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 (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 (Now *np, Obj *op, double *SatX, double *SatY, double *SatZ,
+double *SatVX, double *SatVY, double *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;
+
+	if (crazyOp (np, op)) {
+	    *SatX = *SatY = *SatZ = *SatVX = *SatVY = *SatVZ = 0;
+	    return;
+	}
+
+	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;
+
+	if (crazyOp (np, op)) {
+	    *SatX = *SatY = *SatZ = *SatVX = *SatVY = *SatVZ = 0;
+	    return;
+	}
+
+	/* 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
+}
+
+/* return 1 if op is crazy @ np */
+static int
+crazyOp (Now *np, Obj *op)
+{
+	/* figure its daft if long enough to decay 1 rev/day */
+	return (fabs(op->es_epoch - mjd) > 1/fabs(op->es_decay));
+}
+
+/* grab the xephem stuff from op and copy into orbit's globals.
+ */
+static void
+GetSatelliteParams(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(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(double MeanAnomaly, double 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(double SatX, double SatY, double SatZ, double T,
+double *Latitude, double *Longitude, double *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(double SemiMajorAxis, double Eccentricity, double Inclination,
+double *RAANPrecession, double *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(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)
+
+{
+    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(double SiteLat, double SiteLong, double SiteElevation,
+double CrntTime, double *SiteX, double *SiteY, double *SiteZ, double *SiteVX,
+double *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(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)
+{
+    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(double SatX, double SatY, double SatZ, double SiteX,
+double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *X, double *Y,
+double *Z)
+{
+    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(double SatX, double SatY, double SatZ, double SiteX,
+double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *Azimuth,
+double *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(double SatX, double SatY, double SatZ, double SatRadius,
+double 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(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: 2006-11-22 13:53:29 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_ecl.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_ecl.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_ecl.c	(revision 3445)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void ecleq_aux (int sw, double mj, double x, double y,
+    double *p, double *q);
+
+#define	EQtoECL	1
+#define	ECLtoEQ	(-1)
+
+
+/* given the modified Julian date, mj, and an equitorial ra and dec, each in
+ * radians, find the corresponding geocentric ecliptic latitude, *lt, and
+ * longititude, *lg, also each in radians.
+ * correction for the effect on the angle of the obliquity due to nutation is
+ * not included.
+ */
+void
+eq_ecl (double mj, double ra, double dec, double *lt, double *lg)
+{
+	ecleq_aux (EQtoECL, mj, ra, dec, lg, lt);
+}
+
+/* given the modified Julian date, mj, and a geocentric ecliptic latitude,
+ * *lt, and longititude, *lg, 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 (double mj, double lt, double lg, double *ra, double *dec)
+{
+	ecleq_aux (ECLtoEQ, mj, lg, lt, ra, dec);
+}
+
+static void
+ecleq_aux (
+int sw,			/* +1 for eq to ecliptic, -1 for vv. */
+double mj,
+double x, double y,	/* sw==1: x==ra, y==dec.  sw==-1: x==lg, y==lt. */
+double *p, double *q)	/* sw==1: p==lg, q==lt. sw==-1: p==ra, q==dec. */
+{
+	static double lastmj = -10000;	/* last mj calculated */
+	static double seps, ceps;	/* sin and cos of mean obliquity */
+	double sx, cx, sy, cy, ty, sq;
+
+	if (mj != lastmj) {
+	    double eps;
+	    obliquity (mj, &eps);		/* mean obliquity for date */
+    	    seps = sin(eps);
+	    ceps = cos(eps);
+	    lastmj = mj;
+	}
+
+	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: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_gal.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_gal.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/eq_gal.c	(revision 3445)
@@ -0,0 +1,99 @@
+/* code to convert between equitorial and galactic coordinates */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void galeq_aux (int sw, double x, double y, double *p, double *q);
+static void galeq_init (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 mj2000;			/* mj 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, *lt, and longititude, *lg, also each in
+ * radians.
+ */
+void
+eq_gal (double mj, double ra, double dec, double *lt, double *lg)
+{
+	galeq_init();
+	precess (mj, mj2000, &ra, &dec);
+	galeq_aux (EQtoGAL, ra, dec, lg, lt);
+}
+
+/* given galactic latitude, lt, and longititude, lg, each in radians, find
+ * the corresponding equitorial ra and dec, also each in radians, at the 
+ * given epoch.
+ */
+void
+gal_eq (double mj, double lt, double lg, double *ra, double *dec)
+{
+	galeq_init();
+	galeq_aux (GALtoEQ, lg, lt, ra, dec);
+	precess (mj2000, mj, ra, dec);
+}
+
+static void
+galeq_aux (
+int sw,			/* +1 for eq to gal, -1 for vv. */
+double x, double y,	/* sw==1: x==ra, y==dec.  sw==-1: x==lg, y==lt. */
+double *p, double *q)	/* sw==1: p==lg, q==lt. 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);
+	    mj2000 = J2000;
+	    before = 1;
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: eq_gal.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/formats.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/formats.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/formats.c	(revision 3445)
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.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
+ * return number of characters written to out, not counting final '\0'.
+ */
+int
+fs_sexa (char *out, double a, int w, int fracbase)
+{
+	char *out0 = out;
+	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)
+	    out += sprintf (out, "%*s-0", w-2, "");
+	else
+	    out += sprintf (out, "%*d", w, isneg ? -d : d);
+
+	/* do the rest */
+	switch (fracbase) {
+	case 60:	/* dd:mm */
+	    m = f/(fracbase/60);
+	    out += sprintf (out, ":%02d", m);
+	    break;
+	case 600:	/* dd:mm.m */
+	    out += sprintf (out, ":%02d.%1d", f/10, f%10);
+	    break;
+	case 3600:	/* dd:mm:ss */
+	    m = f/(fracbase/60);
+	    s = f%(fracbase/60);
+	    out += sprintf (out, ":%02d:%02d", m, s);
+	    break;
+	case 36000:	/* dd:mm:ss.s*/
+	    m = f/(fracbase/60);
+	    s = f%(fracbase/60);
+	    out += 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);
+	    out += sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100);
+	    break;
+	default:
+	    printf ("fs_sexa: unknown fracbase: %d\n", fracbase);
+	    abort();
+	}
+
+	return (out - out0);
+}
+
+/* put the given modified Julian date, jd, in out[] according to the given
+ * preference format.
+ * return number of characters written to out, not counting final '\0'.
+ */
+int
+fs_date (char out[], int format, double jd)
+{
+	char *out0 = out;
+	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 (format) {
+	case PREF_YMD:
+	    out += sprintf (out, "%4d/%02d/%02.6g", y, m, d);
+	    break;
+	case PREF_DMY:
+	    out += sprintf (out, "%2.6g/%02d/%-4d", d, m, y);
+	    break;
+	case PREF_MDY:
+	    out += sprintf (out, "%2d/%02.6g/%-4d", m, d, y);
+	    break;
+	default:
+	    printf ("fs_date: bad date pref: %d\n", format);
+	    abort();
+	}
+
+	return (out - out0);
+}
+
+
+/* convert sexagesimal string str AxBxC to double.
+ *   x can be anything non-numeric. Any missing A, B or C will be assumed 0.
+ *   optional - and + can be anywhere.
+ * return 0 if ok, -1 if can't find a thing.
+ */
+int
+f_scansexa (
+const char *str0,	/* input string */
+double *dp)		/* cracked value, if return 0 */
+{
+	double a, b, c;
+	char str[256];
+	char *neg;
+	int isneg, r;
+
+	/* copy str0 so we can play with it */
+	strncpy (str, str0, sizeof(str)-1);
+	str[sizeof(str)-1] = '\0';
+
+	/* note first negative (but not fooled by neg exponent) */
+	isneg = 0;
+	neg = strchr(str, '-');
+	if (neg && (neg == str || (neg[-1] != 'E' && neg[-1] != 'e'))) {
+	    *neg = ' ';
+	    isneg = 1;
+	}
+
+	/* crack up to three components */
+	a = b = c = 0.0;
+	r = sscanf (str, "%lf%*[^0-9]%lf%*[^0-9]%lf", &a, &b, &c);
+	if (r < 1)
+	    return (-1);
+
+	/* back to one value, restoring neg */
+	*dp = (c/60.0 + b)/60.0 + a;
+	if (isneg)
+	    *dp *= -1;
+	return (0);
+}
+
+/* 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,
+ * the slashes may also be spaces or colons.
+ * a lone component with a decimal point is considered a year.
+ */
+void
+f_sscandate (
+char *bp,
+int pref,       /* one of PREF_X for PREF_DATE_FORMAT */
+int *m,
+double *d,
+int *y)
+{
+        double X,Y,Z; /* the three components */
+	int n;
+
+	X = Y = Z = 0.0;
+	n = sscanf (bp, "%lf%*[/: ]%lf%*[/: ]%lf", &X, &Y, &Z);
+	if (n == 1 && (strchr(bp, '.')
+			|| (pref == PREF_MDY && (X < 1 || X > 12))
+			|| (pref == PREF_DMY && (X < 1 || X > 31)))) {
+	    double Mjd;
+	    year_mjd (X, &Mjd);
+	    mjd_cal (Mjd, m, d, y);
+	} else {
+	    switch (pref) {
+	    case PREF_MDY:
+		if (n > 0 && X != 0)
+		    *m = (int)X;
+		if (n > 1 && Y != 0)
+		    *d = Y;
+		if (n > 2 && Z != 0)
+		    *y = (int)Z;
+		break;
+	    case PREF_YMD:
+		if (n > 0 && X != 0)
+		    *y = (int)X;
+		if (n > 1 && Y != 0)
+		    *m = (int)Y;
+		if (n > 2 && Z != 0)
+		    *d = Z;
+		break;
+	    case PREF_DMY:
+		if (n > 0 && X != 0)
+		    *d = X;
+		if (n > 1 && Y != 0)
+		    *m = (int)Y;
+		if (n > 2 && Z != 0)
+		    *y = (int)Z;
+		break;
+	    }
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: formats.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/helio.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/helio.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/helio.c	(revision 3445)
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <math.h>
+#include <math.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 (double jd, double ra, double 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: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/jupmoon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/jupmoon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/jupmoon.c	(revision 3445)
@@ -0,0 +1,391 @@
+/* jupiter moon info */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include "astro.h"
+#include "bdl.h"
+
+static int use_bdl (double jd, char *dir, MoonData md[J_NMOONS]);
+static void meeus_jupiter (double d, double *cmlI, double *cmlII,
+    MoonData md[J_NMOONS]);
+static void moonradec (double jupsize, MoonData md[J_NMOONS]);
+static void moonSVis (Obj *sop, Obj *jop, MoonData md[J_NMOONS]);
+static void moonEVis (MoonData md[J_NMOONS]);
+static void moonPShad (Obj *sop, Obj *jop, MoonData md[J_NMOONS]);
+static void moonTrans (MoonData md[J_NMOONS]);
+
+/* moon table and a few other goodies and when it was last computed */
+static double mdmjd = -123456;
+static MoonData jmd[J_NMOONS] = {
+    {"Jupiter", NULL},
+    {"Io", "I"},
+    {"Europa", "II"},
+    {"Ganymede", "III"},
+    {"Callisto", "IV"}
+};
+static double sizemjd;	/* size at last mjd */
+static double cmlImjd;	/* central meridian long sys I, at last mjd */
+static double cmlIImjd;	/*    "                      II      " */
+
+/* These values are from the Explanatory Supplement.
+ * Precession degrades them gradually over time.
+ */
+#define POLE_RA   degrad(268.05)	 /* RA of Jupiter's north pole */
+#define POLE_DEC  degrad(64.50)		/* Dec of Jupiter's north pole */
+
+
+/* get jupiter info in md[0], moon info in md[1..J_NMOONS-1].
+ * if !dir always use meeus model.
+ * if !jop caller just wants md[] for names
+ * N.B. we assume sop and jop are updated.
+ */
+void
+jupiter_data (
+double Mjd,		/* mjd */
+char dir[],             /* dir in which to look for helper files */
+Obj *sop,               /* Sun */
+Obj *jop,		/* jupiter */
+double *sizep,		/* jup angular diam, rads */
+double *cmlI, double *cmlII,		/* central meridian longitude, rads */
+double *polera, double *poledec,	/* pole location */
+MoonData md[J_NMOONS])	/* return info */
+{
+        double JD;
+
+	/* always copy back at least for name */
+	memcpy (md, jmd, sizeof(jmd));
+
+	/* pole */
+	if (polera) *polera = POLE_RA;
+	if (poledec) *poledec = POLE_DEC;
+
+	/* nothing else if repeat call or just want names */
+	if (Mjd == mdmjd || !jop) {
+	    if (jop) {
+		*sizep = sizemjd;
+		*cmlI = cmlImjd;
+		*cmlII = cmlIImjd;
+	    }
+	    return;
+	}
+	JD = Mjd + MJD0;
+
+	/* planet in [0] */
+	md[0].ra = jop->s_ra;
+	md[0].dec = jop->s_dec;
+	md[0].mag = get_mag(jop);
+	md[0].x = 0;
+	md[0].y = 0;
+	md[0].z = 0;
+	md[0].evis = 1;
+	md[0].svis = 1;
+
+	/* size is straight from jop */
+	*sizep = degrad(jop->s_size/3600.0);
+
+	/* mags from JPL ephemeris */
+	md[1].mag = 5.7;
+	md[2].mag = 5.8;
+	md[3].mag = 5.3;
+	md[4].mag = 6.7;
+
+	/* get moon data from BDL if possible, else Meeus' model.
+	 * always use Meeus for cml
+	 */
+	if (dir && use_bdl (JD, dir, md) == 0)
+	    meeus_jupiter (Mjd, cmlI, cmlII, NULL);
+	else
+	    meeus_jupiter (Mjd, cmlI, cmlII, md);
+
+	/* set visibilities */
+	moonSVis (sop, jop, md);
+	moonPShad (sop, jop, md);
+	moonEVis (md);
+	moonTrans (md);
+
+	/* fill in moon ra and dec */
+	moonradec (*sizep, md);
+
+	/* save */
+	mdmjd = Mjd;
+	sizemjd = *sizep;
+	cmlImjd = *cmlI;
+	cmlIImjd = *cmlII;
+	memcpy (jmd, md, sizeof(jmd));
+}
+
+/* hunt for BDL file in dir[] and use if possible
+ * return 0 if ok, else -1
+ */
+static int
+use_bdl (
+double JD,		/* julian date */
+char dir[],		/* directory */
+MoonData md[J_NMOONS])	/* fill md[1..NM-1].x/y/z for each moon */
+{
+#define	JUPRAU	.0004769108	/* jupiter radius, AU */
+	double x[J_NMOONS], y[J_NMOONS], z[J_NMOONS];
+	char buf[1024];
+	FILE *fp;
+	char *fn;
+	int i;
+
+	/* check ranges and appropriate data file */
+	if (JD < 2451179.50000)		/* Jan 1 1999 UTC */
+	    return (-1);
+	if (JD < 2455562.5)		/* Jan 1 2011 UTC */
+	    fn = "jupiter.9910";
+	else if (JD < 2459215.5)	/* Jan 1 2021 UTC */
+	    fn = "jupiter.1020";
+	else
+	    return (-1);
+
+	/* open */
+	(void) sprintf (buf, "%s/%s", dir, fn);
+	fp = fopen (buf, "r");
+	if (!fp) {
+	    fprintf (stderr, "%s: %s\n", fn, strerror(errno));
+	    return (-1);
+	}
+
+	/* use it */
+	if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) {
+	    fprintf (stderr, "%s: %s\n", fn, buf);
+	    fclose (fp);
+	    return (-1);
+	}
+	if (i != J_NMOONS-1) {
+	    fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, 
+								i, J_NMOONS-1);
+	    fclose (fp);
+	    return (-1);
+	}
+
+	/* copy into md[1..NM-1] with our scale and sign conventions */
+	for (i = 1; i < J_NMOONS; i++) {
+	    md[i].x =  x[i-1]/JUPRAU;	/* we want jup radii +E */
+	    md[i].y = -y[i-1]/JUPRAU;	/* we want jup radii +S */
+	    md[i].z = -z[i-1]/JUPRAU;	/* we want jup radii +front */
+	}
+
+	/* ok */
+	fclose (fp);
+	return (0);
+}
+
+/* compute location of GRS and Galilean moons.
+ * if md == NULL, just to cml.
+ * from "Astronomical Formulae for Calculators", 2nd ed, by Jean Meeus,
+ *   Willmann-Bell, Richmond, Va., U.S.A. (c) 1982, chapters 35 and 36.
+ */
+static void
+meeus_jupiter(
+double d,
+double *cmlI, double *cmlII,	/* central meridian longitude, rads */
+MoonData md[J_NMOONS])	/* fill in md[1..NM-1].x/y/z for each moon.
+			 * N.B. md[0].ra/dec must already be set
+			 */
+{
+#define	dsin(x)	sin(degrad(x))
+#define	dcos(x)	cos(degrad(x))
+	double A, B, Del, J, K, M, N, R, V;
+	double cor_u1, cor_u2, cor_u3, cor_u4;
+	double solc, tmp, G, H, psi, r, r1, r2, r3, r4;
+	double u1, u2, u3, u4;
+	double lam, Ds;
+	double z1, z2, z3,  z4;
+	double De, dsinDe;
+	double theta, phi;
+	double tvc, pvc;
+	double salpha, calpha;
+	int i;
+
+	V = 134.63 + 0.00111587 * d;
+
+	M = (358.47583 + 0.98560003*d);
+	N = (225.32833 + 0.0830853*d) + 0.33 * dsin (V);
+
+	J = 221.647 + 0.9025179*d - 0.33 * dsin(V);
+
+	A = 1.916*dsin(M) + 0.02*dsin(2*M);
+	B = 5.552*dsin(N) + 0.167*dsin(2*N);
+	K = (J+A-B);
+	R = 1.00014 - 0.01672 * dcos(M) - 0.00014 * dcos(2*M);
+	r = 5.20867 - 0.25192 * dcos(N) - 0.00610 * dcos(2*N);
+	Del = sqrt (R*R + r*r - 2*R*r*dcos(K));
+	psi = raddeg (asin (R/Del*dsin(K)));
+
+	*cmlI  = degrad(268.28 + 877.8169088*(d - Del/173) + psi - B);
+	range (cmlI, 2*PI);
+	*cmlII = degrad(290.28 + 870.1869088*(d - Del/173) + psi - B);
+	range (cmlII, 2*PI);
+
+	/* that's it if don't want moon info too */
+	if (!md)
+	    return;
+
+	solc = (d - Del/173.);	/* speed of light correction */
+	tmp = psi - B;
+
+	u1 = 84.5506 + 203.4058630 * solc + tmp;
+	u2 = 41.5015 + 101.2916323 * solc + tmp;
+	u3 = 109.9770 + 50.2345169 * solc + tmp;
+	u4 = 176.3586 + 21.4879802 * solc + tmp;
+
+	G = 187.3 + 50.310674 * solc;
+	H = 311.1 + 21.569229 * solc;
+      
+	cor_u1 =  0.472 * dsin (2*(u1-u2));
+	cor_u2 =  1.073 * dsin (2*(u2-u3));
+	cor_u3 =  0.174 * dsin (G);
+	cor_u4 =  0.845 * dsin (H);
+      
+	r1 = 5.9061 - 0.0244 * dcos (2*(u1-u2));
+	r2 = 9.3972 - 0.0889 * dcos (2*(u2-u3));
+	r3 = 14.9894 - 0.0227 * dcos (G);
+	r4 = 26.3649 - 0.1944 * dcos (H);
+
+	md[1].x = -r1 * dsin (u1+cor_u1);
+	md[2].x = -r2 * dsin (u2+cor_u2);
+	md[3].x = -r3 * dsin (u3+cor_u3);
+	md[4].x = -r4 * dsin (u4+cor_u4);
+
+	lam = 238.05 + 0.083091*d + 0.33*dsin(V) + B;
+	Ds = 3.07*dsin(lam + 44.5);
+	De = Ds - 2.15*dsin(psi)*dcos(lam+24.)
+		- 1.31*(r-Del)/Del*dsin(lam-99.4);
+	dsinDe = dsin(De);
+
+	z1 = r1 * dcos(u1+cor_u1);
+	z2 = r2 * dcos(u2+cor_u2);
+	z3 = r3 * dcos(u3+cor_u3);
+	z4 = r4 * dcos(u4+cor_u4);
+
+	md[1].y = z1*dsinDe;
+	md[2].y = z2*dsinDe;
+	md[3].y = z3*dsinDe;
+	md[4].y = z4*dsinDe;
+
+	/* compute sky transformation angle as triple vector product */
+	tvc = PI/2.0 - md[0].dec;
+	pvc = md[0].ra;
+	theta = PI/2.0 - POLE_DEC;
+	phi = POLE_RA;
+	salpha = -sin(tvc)*sin(theta)*(cos(pvc)*sin(phi) - sin(pvc)*cos(phi));
+	calpha = sqrt (1.0 - salpha*salpha);
+
+	for (i = 0; i < J_NMOONS; i++) {
+	    double tx =  md[i].x*calpha + md[i].y*salpha;
+	    double ty = -md[i].x*salpha + md[i].y*calpha;
+	    md[i].x = tx;
+	    md[i].y = ty;
+	}
+
+	md[1].z = z1;
+	md[2].z = z2;
+	md[3].z = z3;
+	md[4].z = z4;
+}
+
+
+/* given jupiter loc in md[0].ra/dec and size, and location of each moon in 
+ * md[1..NM-1].x/y in jup radii, find ra/dec of each moon in md[1..NM-1].ra/dec.
+ */
+static void
+moonradec (
+double jupsize,		/* jup diameter, rads */
+MoonData md[J_NMOONS])	/* fill in RA and Dec */
+{
+	double juprad = jupsize/2;
+	double jupra = md[0].ra;
+	double jupdec = md[0].dec;
+	int i;
+
+	for (i = 1; i < J_NMOONS; i++) {
+	    double dra  = juprad * md[i].x;
+	    double ddec = juprad * md[i].y;
+	    md[i].ra  = jupra + dra;
+	    md[i].dec = jupdec - ddec;
+	}
+}
+
+/* set svis according to whether moon is in sun light */
+static void
+moonSVis(
+Obj *sop,		/* SUN */
+Obj *jop,		/* jupiter */
+MoonData md[J_NMOONS])
+{
+	double esd = sop->s_edist;
+	double eod = jop->s_edist;
+	double sod = jop->s_sdist;
+	double soa = degrad(jop->s_elong);
+	double esa = asin(esd*sin(soa)/sod);
+	double   h = sod*jop->s_hlat;
+	double nod = h*(1./eod - 1./sod);
+	double sca = cos(esa), ssa = sin(esa);
+	int i;
+
+	for (i = 1; i < J_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    double xp =  sca*mdp->x + ssa*mdp->z;
+	    double yp =  mdp->y;
+	    double zp = -ssa*mdp->x + sca*mdp->z;
+	    double ca = cos(nod), sa = sin(nod);
+	    double xpp = xp;
+	    double ypp = ca*yp - sa*zp;
+	    double zpp = sa*yp + ca*zp;
+	    int outside = xpp*xpp + ypp*ypp > 1.0;
+	    int infront = zpp > 0.0;
+	    mdp->svis = outside || infront;
+	}
+}
+
+/* set evis according to whether moon is geometrically visible from earth */
+static void
+moonEVis (MoonData md[J_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < J_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
+	    int infront = mdp->z > 0.0;
+	    mdp->evis = outside || infront;
+	}
+}
+
+/* set pshad and sx,sy shadow info */
+static void
+moonPShad(
+Obj *sop,		/* SUN */
+Obj *jop,		/* jupiter */
+MoonData md[J_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < J_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->pshad = !plshadow (jop, sop, POLE_RA, POLE_DEC, mdp->x,
+					    mdp->y, mdp->z, &mdp->sx, &mdp->sy);
+	}
+}
+
+/* set whether moons are transiting */
+static void
+moonTrans (MoonData md[J_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < J_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: jupmoon.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/libration.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/libration.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/libration.c	(revision 3445)
@@ -0,0 +1,2218 @@
+/* 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 "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 (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 (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 (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 (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 (double JD, double *llatp, double *llonp)
+{
+	double lg, lt;	/* arc seconds */
+	
+	lg = gplan (JD, &liblon);
+	lt = gplan (JD, &liblat);
+
+	*llonp = degrad (lg/3600.0);
+	*llatp = degrad (lt/3600.0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: libration.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/magdecl.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/magdecl.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/magdecl.c	(revision 3445)
@@ -0,0 +1,381 @@
+/* DoD NIMA World Magnetic Model.
+ * from http://www.ngdc.noaa.gov
+ *
+#define	TEST_MAIN
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "astro.h"
+
+static char mfn[] = "wmm.cof";	/* file with model coefficients */
+
+static int geomag(FILE *wmmdat, int *maxdeg);
+static int geomg1(FILE *wmmdat, float alt, float glat, float glon,
+	float t, float *dec, float *mdp, float *ti, float *gv);
+
+/* compute magnetic declination for given location, elevation and time.
+ * sign is such that mag bearing = true az + mag deviation.
+ * return 0 if ok, -1 if no model file, -2 if time outside model range.
+ * fill err[] with excuse if return < 0.
+ */
+int
+magdecl (
+double l, double L,		/* geodesic lat, +N, long, +E, rads */
+double e,			/* elevation, m */
+double y,			/* time, decimal year */
+char *dir,			/* dir for model file */
+double *mdp,			/* magnetic deviation, rads E of N */
+char *err)			/* err message if return < 0 */
+{
+	float dlat = raddeg(l);
+	float dlon = raddeg(L);
+	float alt = e/1000.;
+	int maxdeg = 12;
+	float dec, dp, ti, gv;
+	char mfile[1024];
+	FILE *wmmdat;
+	int s;
+
+	/* open model file */
+	sprintf (mfile, "%s/%s", dir, mfn);
+	wmmdat = fopen (mfile, "r");
+	if (!wmmdat) {
+	    sprintf (err, "%s: %s", mfile, strerror(errno));
+	    return (-1);
+	}
+
+	/* compute deviation */
+	geomag(wmmdat, &maxdeg);
+	s = geomg1(wmmdat,alt,dlat,dlon,y,&dec,&dp,&ti,&gv);
+	fclose(wmmdat);
+	if (s < 0) {
+	    sprintf (err, "%s: Magnetic model only available for %g .. %g. See http://www.ngdc.noaa.gov", mfile, ti, ti+5);
+	    return (-2);
+	}
+	*mdp = degrad(dec);
+	return (0);
+}
+
+#if defined(TEST_MAIN)
+
+int
+main(int ac, char *av[])
+{
+      char err[1024];
+      float altm, dlat, dlon;
+      float t;
+      double dec;
+
+    S1:
+      printf("\n\n\n ENTER LATITUDE IN DECIMAL DEGREES (+25.0)\n");
+      scanf("%f", &dlat);
+
+      printf(" ENTER LONGITUDE IN DECIMAL DEGREES (-100.0)\n");
+      scanf("%f", &dlon);
+
+      printf(" ENTER ALTITUDE IN METERS\n");
+      scanf("%f", &altm);
+
+      printf(" ENTER TIME IN DECIMAL YEAR\n");
+      scanf("%f",&t);
+
+      if (magdecl (degrad(dlat), degrad(dlon), altm, t, "auxil", &dec,
+								  err) < 0) {
+	  printf ("%s\n", err);
+	  return(1);
+      }
+
+      printf("\n LATITUDE:    = %-7.2f DEG",dlat);
+      printf("\n LONGITUDE:   = %-7.2f DEG\n",dlon);
+      printf("\n ALTITUDE     = %.2f  METERS",altm);
+      printf("\n DATE         = %-5.1f\n",t);
+
+      printf("\n\t\t\t      OUTPUT\n\t\t\t      ------");
+      
+      printf("\n DEC         = %-7.2f DEG", raddeg(dec));
+
+      printf("\n\n\n DO YOU NEED MORE POINT DATA? (y or n)\n");
+      scanf("%s", err);
+      if ((err[0] =='y')||(err[0] == 'Y')) goto S1;
+
+      return(0);
+}
+#endif	/* defined(TEST_MAIN) */
+
+/*************************************************************************
+ * return 0 if ok, -1 if time is out of range with base epoc in *ti
+ */
+
+static int E0000(FILE *wmmdat, int IENTRY, int *maxdeg, float alt,
+float glat, float glon, float t, float *dec, float *mdp, float *ti,
+float *gv)
+{
+     static int maxord,i,icomp,n,m,j,D1,D2,D3,D4;
+     static float c[13][13],cd[13][13],tc[13][13],dp[13][13],snorm[169],
+	  sp[13],cp[13],fn[13],fm[13],pp[13],k[13][13],pi,dtr,a,b,re,
+	  a2,b2,c2,a4,b4,c4,epoc,gnm,hnm,dgnm,dhnm,flnmj,otime,oalt,
+	  olat,olon,dt,rlon,rlat,srlon,srlat,crlon,crlat,srlat2,
+	  crlat2,q,q1,q2,ct,st,r2,r,d,ca,sa,aor,ar,br,bt,bp,bpp,
+	  par,temp1,temp2,parp,bx,by,bz,bh;
+     static char model[20], c_str[81], c_new[5];
+     static float *p = snorm;
+
+     switch(IENTRY){case 0: goto GEOMAG; case 1: goto GEOMG1;}
+
+GEOMAG:
+
+/* INITIALIZE CONSTANTS */
+      maxord = *maxdeg;
+      sp[0] = 0.0;
+      cp[0] = *p = pp[0] = 1.0;
+      dp[0][0] = 0.0;
+      a = 6378.137;
+      b = 6356.7523142;
+      re = 6371.2;
+      a2 = a*a;
+      b2 = b*b;
+      c2 = a2-b2;
+      a4 = a2*a2;
+      b4 = b2*b2;
+      c4 = a4 - b4;
+
+/* READ WORLD MAGNETIC MODEL SPHERICAL HARMONIC COEFFICIENTS */
+      c[0][0] = 0.0;
+      cd[0][0] = 0.0;
+      fgets(c_str, 80, wmmdat);
+      sscanf(c_str,"%f%s",&epoc,model);
+S3:
+      fgets(c_str, 80, wmmdat);
+/* CHECK FOR LAST LINE IN FILE */
+      for (i=0; i<4 && (c_str[i] != '\0'); i++)
+      {
+	c_new[i] = c_str[i];
+	c_new[i+1] = '\0';
+      }
+      icomp = strcmp("9999", c_new);
+      if (icomp == 0) goto S4;
+/* END OF FILE NOT ENCOUNTERED, GET VALUES */
+      sscanf(c_str,"%d%d%f%f%f%f",&n,&m,&gnm,&hnm,&dgnm,&dhnm);
+      if (m <= n)
+      {
+	c[m][n] = gnm;
+	cd[m][n] = dgnm;
+	if (m != 0) 
+	{
+	  c[n][m-1] = hnm;
+	  cd[n][m-1] = dhnm;
+	}
+      }
+      goto S3;
+
+/* CONVERT SCHMIDT NORMALIZED GAUSS COEFFICIENTS TO UNNORMALIZED */
+S4:
+      *snorm = 1.0;
+      for (n=1; n<=maxord; n++) 
+      {
+	*(snorm+n) = *(snorm+n-1)*(float)(2*n-1)/(float)n;
+	j = 2;
+	for (m=0,D1=1,D2=(n-m+D1)/D1; D2>0; D2--,m+=D1) 
+	{
+	  k[m][n] = (float)(((n-1)*(n-1))-(m*m))/(float)((2*n-1)*(2*n-3));
+	  if (m > 0) 
+	  {
+	    flnmj = (float)((n-m+1)*j)/(float)(n+m);
+	    *(snorm+n+m*13) = *(snorm+n+(m-1)*13)*sqrt(flnmj);
+	    j = 1;
+	    c[n][m-1] = *(snorm+n+m*13)*c[n][m-1];
+	    cd[n][m-1] = *(snorm+n+m*13)*cd[n][m-1];
+	  }
+	  c[m][n] = *(snorm+n+m*13)*c[m][n];
+	  cd[m][n] = *(snorm+n+m*13)*cd[m][n];
+	}
+	fn[n] = (float)(n+1);
+	fm[n] = (float)n;
+      }
+      k[1][1] = 0.0;
+
+      otime = oalt = olat = olon = -1000.0;
+      return (0);
+
+/*************************************************************************/
+
+GEOMG1:
+
+      dt = t - epoc;
+      if (otime < 0.0 && (dt < 0.0 || dt > 5.0)) {
+	  *ti = epoc;			/* pass back base time for diag msg */
+	  return (-1);
+      }
+
+      pi = 3.14159265359;
+      dtr = pi/180.0;
+      rlon = glon*dtr;
+      rlat = glat*dtr;
+      srlon = sin(rlon);
+      srlat = sin(rlat);
+      crlon = cos(rlon);
+      crlat = cos(rlat);
+      srlat2 = srlat*srlat;
+      crlat2 = crlat*crlat;
+      sp[1] = srlon;
+      cp[1] = crlon;
+
+/* CONVERT FROM GEODETIC COORDS. TO SPHERICAL COORDS. */
+      if (alt != oalt || glat != olat) 
+      {
+	q = sqrt(a2-c2*srlat2);
+	q1 = alt*q;
+	q2 = ((q1+a2)/(q1+b2))*((q1+a2)/(q1+b2));
+	ct = srlat/sqrt(q2*crlat2+srlat2);
+	st = sqrt(1.0-(ct*ct));
+	r2 = (alt*alt)+2.0*q1+(a4-c4*srlat2)/(q*q);
+	r = sqrt(r2);
+	d = sqrt(a2*crlat2+b2*srlat2);
+	ca = (alt+d)/r;
+	sa = c2*crlat*srlat/(r*d);
+      }
+      if (glon != olon) 
+      {
+	for (m=2; m<=maxord; m++) 
+	{
+	  sp[m] = sp[1]*cp[m-1]+cp[1]*sp[m-1];
+	  cp[m] = cp[1]*cp[m-1]-sp[1]*sp[m-1];
+	}
+      }
+      aor = re/r;
+      ar = aor*aor;
+      br = bt = bp = bpp = 0.0;
+      for (n=1; n<=maxord; n++) 
+      {
+	ar = ar*aor;
+	for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) 
+	{
+/*
+   COMPUTE UNNORMALIZED ASSOCIATED LEGENDRE POLYNOMIALS
+   AND DERIVATIVES VIA RECURSION RELATIONS
+*/
+	  if (alt != oalt || glat != olat) 
+	  {
+	    if (n == m) 
+	    {
+	      *(p+n+m*13) = st**(p+n-1+(m-1)*13);
+	      dp[m][n] = st*dp[m-1][n-1]+ct**(p+n-1+(m-1)*13);
+	      goto S50;
+	    }
+	    if (n == 1 && m == 0) 
+	    {
+	      *(p+n+m*13) = ct**(p+n-1+m*13);
+	      dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13);
+	      goto S50;
+	    }
+	    if (n > 1 && n != m) 
+	    {
+	      if (m > n-2) *(p+n-2+m*13) = 0.0;
+	      if (m > n-2) dp[m][n-2] = 0.0;
+	      *(p+n+m*13) = ct**(p+n-1+m*13)-k[m][n]**(p+n-2+m*13);
+	      dp[m][n] = ct*dp[m][n-1] - st**(p+n-1+m*13)-k[m][n]*dp[m][n-2];
+	     }
+	  }
+S50:
+/*
+    TIME ADJUST THE GAUSS COEFFICIENTS
+*/
+	  if (t != otime) 
+	  {
+	    tc[m][n] = c[m][n]+dt*cd[m][n];
+	    if (m != 0) tc[n][m-1] = c[n][m-1]+dt*cd[n][m-1];
+	  }
+/*
+    ACCUMULATE TERMS OF THE SPHERICAL HARMONIC EXPANSIONS
+*/
+	  par = ar**(p+n+m*13);
+	  if (m == 0) 
+	  {
+	    temp1 = tc[m][n]*cp[m];
+	    temp2 = tc[m][n]*sp[m];
+	  }
+	  else 
+	  {
+	    temp1 = tc[m][n]*cp[m]+tc[n][m-1]*sp[m];
+	    temp2 = tc[m][n]*sp[m]-tc[n][m-1]*cp[m];
+	  }
+	  bt = bt-ar*temp1*dp[m][n];
+	  bp += (fm[m]*temp2*par);
+	  br += (fn[n]*temp1*par);
+/*
+    SPECIAL CASE:  NORTH/SOUTH GEOGRAPHIC POLES
+*/
+	  if (st == 0.0 && m == 1) 
+	  {
+	    if (n == 1) pp[n] = pp[n-1];
+	    else pp[n] = ct*pp[n-1]-k[m][n]*pp[n-2];
+	    parp = ar*pp[n];
+	    bpp += (fm[m]*temp2*parp);
+	  }
+	}
+      }
+      if (st == 0.0) bp = bpp;
+      else bp /= st;
+/*
+    ROTATE MAGNETIC VECTOR COMPONENTS FROM SPHERICAL TO
+    GEODETIC COORDINATES
+*/
+      bx = -bt*ca-br*sa;
+      by = bp;
+      bz = bt*sa-br*ca;
+/*
+    COMPUTE DECLINATION (DEC), INCLINATION (DIP) AND
+    TOTAL INTENSITY (TI)
+*/
+      bh = sqrt((bx*bx)+(by*by));
+      *ti = sqrt((bh*bh)+(bz*bz));
+      *dec = atan2(by,bx)/dtr;
+      *mdp = atan2(bz,bh)/dtr;
+/*
+    COMPUTE MAGNETIC GRID VARIATION IF THE CURRENT
+    GEODETIC POSITION IS IN THE ARCTIC OR ANTARCTIC
+    (I.E. GLAT > +55 DEGREES OR GLAT < -55 DEGREES)
+
+    OTHERWISE, SET MAGNETIC GRID VARIATION TO -999.0
+*/
+      *gv = -999.0;
+      if (fabs(glat) >= 55.) 
+      {
+	if (glat > 0.0 && glon >= 0.0) *gv = *dec-glon;
+	if (glat > 0.0 && glon < 0.0) *gv = *dec+fabs(glon);
+	if (glat < 0.0 && glon >= 0.0) *gv = *dec+glon;
+	if (glat < 0.0 && glon < 0.0) *gv = *dec-fabs(glon);
+	if (*gv > +180.0) *gv -= 360.0;
+	if (*gv < -180.0) *gv += 360.0;
+      }
+      otime = t;
+      oalt = alt;
+      olat = glat;
+      olon = glon;
+      return (0);
+}
+
+/*************************************************************************/
+
+static int
+geomag(FILE *wmmdat, int *maxdeg)
+{
+     return (E0000(wmmdat,0,maxdeg,0.0,0.0,0.0,0.0,NULL,NULL,NULL,NULL));
+}
+
+/*************************************************************************/
+
+static int
+geomg1(FILE *wmmdat, float alt, float glat, float glon, float t,
+float *dec, float *mdp, float *ti, float *gv)
+{
+     return (E0000(wmmdat,1,NULL,alt,glat,glon,t,dec,mdp,ti,gv));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: magdecl.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.5 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/marsmoon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/marsmoon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/marsmoon.c	(revision 3445)
@@ -0,0 +1,265 @@
+/* mars moon info */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include "astro.h"
+#include "bdl.h"
+
+static int use_bdl (double JD, char *dir, MoonData md[M_NMOONS]);
+static void moonradec (double msize, MoonData md[M_NMOONS]);
+static void moonSVis (Obj *sop, Obj *mop, MoonData md[M_NMOONS]);
+static void moonEVis (MoonData md[M_NMOONS]);
+static void moonPShad (Obj *sop, Obj *mop, MoonData md[M_NMOONS]);
+static void moonTrans (MoonData md[M_NMOONS]);
+
+/* moon table and a few other goodies and when it was last computed */
+static double mdmjd = -123456;
+static MoonData mmd[M_NMOONS] = {
+    {"Mars", NULL},
+    {"Phobos", "I"},
+    {"Deimos", "II"},
+};
+static double sizemjd;
+
+/* These values are from the Explanatory Supplement.
+ * Precession degrades them gradually over time.
+ */
+#define POLE_RA         degrad(317.61)
+#define POLE_DEC        degrad(52.85)
+
+
+/* get mars info in md[0], moon info in md[1..M_NMOONS-1].
+ * if !dir always use bruton model.
+ * if !mop caller just wants md[] for names
+ * N.B. we assume sop and mop are updated.
+ */
+void
+marsm_data (
+double Mjd,			/* mjd */
+char dir[],			/* dir in which to look for helper files */
+Obj *sop,			/* Sun */
+Obj *mop,			/* mars */
+double *sizep,			/* mars's angular diam, rads */
+double *polera, double *poledec,/* pole location */
+MoonData md[M_NMOONS])		/* return info */
+{
+	double JD, dmag;
+
+	/* always copy back at least for name */
+	memcpy (md, mmd, sizeof(mmd));
+
+	/* pole */
+	if (polera) *polera = POLE_RA;
+	if (poledec) *poledec = POLE_DEC;
+
+	/* nothing else if repeat call or just want names */
+	if (Mjd == mdmjd || !mop) {
+	    if (mop) {
+		*sizep = sizemjd;
+	    }
+	    return;
+	}
+	JD = Mjd + MJD0;
+
+	/* planet in [0] */
+	md[0].ra = mop->s_ra;
+	md[0].dec = mop->s_dec;
+	md[0].mag = get_mag(mop);
+	md[0].x = 0;
+	md[0].y = 0;
+	md[0].z = 0;
+	md[0].evis = 1;
+	md[0].svis = 1;
+
+	/* size is straight from mop */
+	*sizep = degrad(mop->s_size/3600.0);
+
+	/* from Pasachoff/Menzel: brightest @ .6 AU */
+	dmag = 5.0*log10(mop->s_edist + 0.4);
+	md[1].mag = 11.8 + dmag;
+	md[2].mag = 12.9 + dmag;
+
+	/* get moon x,y,z from BDL if possible */
+	if (!dir || use_bdl (JD, dir, md) < 0) {
+	    int i;
+	    for (i = 1; i < M_NMOONS; i++)
+		md[i].x = md[i].y = md[i].z = 0.0;
+	    fprintf (stderr, "No mars model available\n");
+	}
+
+	/* set visibilities */
+	moonSVis (sop, mop, md);
+	moonPShad (sop, mop, md);
+	moonEVis (md);
+	moonTrans (md);
+
+	/* fill in moon ra and dec */
+	moonradec (*sizep, md);
+
+	/* save */
+	mdmjd = Mjd;
+	sizemjd = *sizep;
+	memcpy (mmd, md, sizeof(mmd));
+}
+
+/* hunt for BDL file in dir[] and use if possible.
+ * return 0 if ok, else -1
+ */
+static int
+use_bdl (
+double JD,		/* julian date */
+char dir[],		/* directory */
+MoonData md[M_NMOONS])	/* fill md[1..NM-1].x/y/z for each moon */
+{
+#define MRAU    .00002269       /* Mars radius, AU */
+	double x[M_NMOONS], y[M_NMOONS], z[M_NMOONS];
+	char buf[1024];
+	FILE *fp;
+	char *fn;
+	int i;
+
+	/* check ranges and appropriate data file */
+	if (JD < 2451179.50000)		/* Jan 1 1999 UTC */
+	    return (-1);
+	if (JD < 2455562.5)		/* Jan 1 2011 UTC */
+	    fn = "mars.9910";
+	else if (JD < 2459215.5)	/* Jan 1 2021 UTC */
+	    fn = "mars.1020";
+	else
+	    return (-1);
+
+	/* open */
+	(void) sprintf (buf, "%s/%s", dir, fn);
+	fp = fopen (buf, "r");
+	if (!fp) {
+	    fprintf (stderr, "%s: %s\n", fn, strerror(errno));
+	    return (-1);
+	}
+
+	/* use it */
+	if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) {
+	    fprintf (stderr, "%s: %s\n", fn, buf);
+	    fclose (fp);
+	    return (-1);
+	}
+	if (i != M_NMOONS-1) {
+	    fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn,
+								i, M_NMOONS-1);
+	    fclose (fp);
+	    return (-1);
+	}
+
+	/* copy into md[1..NM-1] with our scale and sign conventions */
+	for (i = 1; i < M_NMOONS; i++) {
+	    md[i].x =  x[i-1]/MRAU;	/* we want mars radii +E */
+	    md[i].y = -y[i-1]/MRAU;	/* we want mars radii +S */
+	    md[i].z = -z[i-1]/MRAU;	/* we want mars radii +front */
+	}
+
+	/* ok */
+	fclose (fp);
+	return (0);
+}
+
+/* given mars loc in md[0].ra/dec and size, and location of each moon in 
+ * md[1..NM-1].x/y in mars radii,find ra/dec of each moon in md[1..NM-1].ra/dec.
+ */
+static void
+moonradec (
+double msize,		/* mars diameter, rads */
+MoonData md[M_NMOONS])	/* fill in RA and Dec */
+{
+	double mrad = msize/2;
+	double mra = md[0].ra;
+	double mdec = md[0].dec;
+	int i;
+
+	for (i = 1; i < M_NMOONS; i++) {
+	    double dra  = mrad * md[i].x;
+	    double ddec = mrad * md[i].y;
+	    md[i].ra  = mra + dra;
+	    md[i].dec = mdec - ddec;
+	}
+}
+
+/* set svis according to whether moon is in sun light */
+static void
+moonSVis(
+Obj *sop,		/* SUN */
+Obj *mop,		/* mars */
+MoonData md[M_NMOONS])
+{
+	double esd = sop->s_edist;
+	double eod = mop->s_edist;
+	double sod = mop->s_sdist;
+	double soa = degrad(mop->s_elong);
+	double esa = asin(esd*sin(soa)/sod);
+	double   h = sod*mop->s_hlat;
+	double nod = h*(1./eod - 1./sod);
+	double sca = cos(esa), ssa = sin(esa);
+	int i;
+
+	for (i = 1; i < M_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    double xp =  sca*mdp->x + ssa*mdp->z;
+	    double yp =  mdp->y;
+	    double zp = -ssa*mdp->x + sca*mdp->z;
+	    double ca = cos(nod), sa = sin(nod);
+	    double xpp = xp;
+	    double ypp = ca*yp - sa*zp;
+	    double zpp = sa*yp + ca*zp;
+	    int outside = xpp*xpp + ypp*ypp > 1.0;
+	    int infront = zpp > 0.0;
+	    mdp->svis = outside || infront;
+	}
+}
+
+/* set evis according to whether moon is geometrically visible from earth */
+static void
+moonEVis (MoonData md[M_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < M_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
+	    int infront = mdp->z > 0.0;
+	    mdp->evis = outside || infront;
+	}
+}
+
+/* set pshad and sx,sy shadow info */
+static void
+moonPShad(
+Obj *sop,             /* SUN */
+Obj *mop,             /* mars */
+MoonData md[M_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < M_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->pshad = !plshadow (mop, sop, POLE_RA, POLE_DEC, mdp->x,
+					  mdp->y, mdp->z, &mdp->sx, &mdp->sy);
+	}
+}
+
+/* set whether moons are transiting */
+static void
+moonTrans (MoonData md[M_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < M_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
+	}
+}
+
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: marsmoon.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/misc.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/misc.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/misc.c	(revision 3445)
@@ -0,0 +1,503 @@
+/* misc handy functions.
+ * every system has such, no?
+ *  4/20/98 now_lst() always just returns apparent time
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "astro.h"
+
+/* zero from loc for len bytes */
+void
+zero_mem (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 (double min, double 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 < (int)(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 (Obj *op)
+{
+	typedef struct {
+	    char classcode;
+	    char *desc;
+	} CC;
+
+#define	NFCM	((int)(sizeof(fixed_class_map)/sizeof(fixed_class_map[0])))
+	static CC fixed_class_map[] = {
+	    {'A', "Cluster of Galaxies"},
+	    {'B', "Binary System"},
+	    {'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"},
+	    {'Y', "Supernova"},
+	};
+
+#define	NBCM	((int)(sizeof(binary_class_map)/sizeof(binary_class_map[0])))
+	static CC binary_class_map[] = {
+	    {'a', "Astrometric binary"},
+	    {'c', "Cataclysmic variable"},
+	    {'e', "Eclipsing binary"},
+	    {'x', "High-mass X-ray binary"},
+	    {'y', "Low-mass X-ray binary"},
+	    {'o', "Occultation binary"},
+	    {'s', "Spectroscopic binary"},
+	    {'t', "1-line spectral binary"},
+	    {'u', "2-line spectral binary"},
+	    {'v', "Spectrum binary"},
+	    {'b', "Visual binary"},
+	    {'d', "Visual binary, apparent"},
+	    {'q', "Visual binary, optical"},
+	    {'r', "Visual binary, physical"},
+	    {'p', "Exoplanet"},
+	};
+
+	switch (op->o_type) {
+	case FIXED:
+	    if (op->f_class) {
+		int i;
+		for (i = 0; i < NFCM; i++)
+		    if (fixed_class_map[i].classcode == op->f_class)
+			return (fixed_class_map[i].desc);
+	    }
+	    return ("Fixed");
+	case PARABOLIC:
+	    return ("Solar - Parabolic");
+	case HYPERBOLIC:
+	    return ("Solar - Hyperbolic");
+	case ELLIPTICAL:
+	    return ("Solar - Elliptical");
+	case BINARYSTAR:
+	    if (op->f_class) {
+		int i;
+		for (i = 0; i < NFCM; i++)
+		    if (binary_class_map[i].classcode == op->f_class)
+			return (binary_class_map[i].desc);
+	    }
+	    return ("Binary system");
+	case PLANET: {
+	    static char nsstr[16];
+	    static Obj *biop;
+
+	    if (op->pl_code == SUN)
+		return ("Star");
+	    if (op->pl_code == MOON)
+		return ("Moon of Earth");
+	    if (op->pl_moon == X_PLANET)
+		return ("Planet");
+	    if (!biop)
+		getBuiltInObjs (&biop);
+	    sprintf (nsstr, "Moon of %s", biop[op->pl_code].o_name);
+	    return (nsstr);
+	    }
+	case EARTHSAT:
+	    return ("Earth Sat");
+	default:
+	    printf ("obj_description: unknown type: 0x%x\n", op->o_type);
+	    abort();
+	    return (NULL);	/* for lint */
+	}
+}
+
+/* given a Now *, find the local apparent sidereal time, in hours.
+ */
+void
+now_lst (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 0..2*PI
+ * need dec too if not already apparent.
+ */
+void
+radec2ha (Now *np, double ra, double 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 < 0)
+	    ha += 2*PI;
+	*hap = ha;
+}
+
+/* find Greenwich Hour Angle of the given object at the given time, 0..2*PI.
+ */
+void
+gha (Now *np, Obj *op, double *ghap)
+{
+	Now n = *np;
+	Obj o = *op;
+	double tmp;
+
+	n.n_epoch = EOD;
+	n.n_lng = 0.0;
+	n.n_lat = 0.0;
+	obj_cir (&n, &o);
+	now_lst (&n, &tmp);
+	tmp = hrrad(tmp) - o.s_ra;
+	if (tmp < 0)
+	    tmp += 2*PI;
+	*ghap = tmp;
+}
+
+/* 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 (
+int cx, int cy, int cw,			/* circle bbox corner and width */
+int x1, int y1, int x2, int y2,		/* line segment endpoints */
+int *sx1, int *sy1, int *sx2, int *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 (
+double h, double 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);
+	if (Psi_1 || Psi_2) *mp -= 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 (
+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 (
+double g, double 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 (char *buf)
+{
+	return (strtod (buf, NULL));
+}
+
+/* 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 (double A, double b, double cc, double sc, double *cap, double *Bp)
+{
+	double cb = cos(b), sb = sin(b);
+	double sA, cA = cos(A);
+	double x, y;
+	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 (sc < 1e-7)
+	    B = cc < 0 ? A : PI-A;
+	else {
+	    sA = sin(A);
+	    y = sA*sb*sc;
+	    x = cb - ca*cc;
+	    B = y ? (x ? atan2(y,x) : (y>0 ? PI/2 : -PI/2)) : (x>=0 ? 0 : PI);
+	}
+
+	*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 (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 (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: 2006-11-22 13:53:29 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/mjd.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/mjd.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/mjd.c	(revision 3445)
@@ -0,0 +1,256 @@
+/* functions to manipulate the modified-julian-date used throughout xephem. */
+
+#include <stdio.h>
+#include <math.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 (int mn, double dy, int yr, double *mjp)
+{
+	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) {
+	    *mjp = 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));
+
+	*mjp = b + c + d + dy - 0.5;
+
+	last_mn = mn;
+	last_dy = dy;
+	last_yr = yr;
+	last_mjd = *mjp;
+}
+
+/* given the modified Julian date (number of days elapsed since 1900 jan 0.5,),
+ * mj, return the calendar date in months, *mn, days, *dy, and years, *yr.
+ */
+void
+mjd_cal (double mj, int *mn, double *dy, int *yr)
+{
+	static double last_mj, 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 (mj == 0.0) {
+	    *mn = 12;
+	    *dy = 31.5;
+	    *yr = 1899;
+	    return;
+	}
+
+	if (mj == last_mj) {
+	    *mn = last_mn;
+	    *yr = last_yr;
+	    *dy = last_dy;
+	    return;
+	}
+
+	d = mj + 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_mj = mj;
+}
+
+/* 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 (double mj, 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 (mj < -53798.5) {
+	    /* pre sept 14, 1752 too hard to correct |:-S */
+	    return (-1);
+	}
+	*dow = ((long)floor(mj-.5) + 1) % 7;/* 1/1/1900 (mj 0.5) is a Monday*/
+	if (*dow < 0)
+	    *dow += 7;
+	return (0);
+}
+
+/* given a year, return whether it is a leap year */
+int
+isleapyear (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 (double mj, int *ndays)
+{
+	static short dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+	int m, y;
+	double d;
+
+	mjd_cal (mj, &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 (double mj, int *yr, double *dy)
+{
+	double yrd;
+	int yri;
+	int dpy;
+
+	mjd_year (mj, &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 (double mj, double *yr)
+{
+	static double last_mj, last_yr;
+	int m, y;
+	double d;
+	double e0, e1;	/* mjd of start of this year, start of next year */
+
+	if (mj == last_mj) {
+	    *yr = last_yr;
+	    return;
+	}
+
+	mjd_cal (mj, &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 + (mj - e0)/(e1 - e0);
+
+	last_mj = mj;
+	last_yr = *yr;
+}
+
+/* given a decimal year, return mjd */
+void
+year_mjd (double y, double *mjp)
+{
+	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);
+	*mjp = e0 + (y - yf)*(e1-e0);
+}
+
+/* round a time in days, *t, to the nearest second, IN PLACE. */
+void
+rnd_second (double *t)
+{
+	*t = floor(*t*SPD+0.5)/SPD;
+}
+	
+/* given an mjd, truncate it to the beginning of the whole day */
+double
+mjd_day(double mj)
+{
+	return (floor(mj-0.5)+0.5);
+}
+
+/* given an mjd, return the number of hours past midnight of the whole day */
+double
+mjd_hr(double mj)
+{
+	return ((mj-mjd_day(mj))*24.0);
+}
+
+/* insure 0 <= *v < r.
+ */
+void
+range (double *v, double r)
+{
+	*v -= r*floor(*v/r);
+}
+
+/* insure 0 <= ra < 2PI and -PI/2 <= dec <= PI/2. if dec needs 
+ * complimenting, reflect ra too
+ */
+void
+radecrange (double *ra, double *dec)
+{
+	if (*dec < -PI/2) {
+	    *dec = -PI - *dec;
+	    *ra += PI;
+	} else if (*dec > PI/2) {
+	    *dec = PI - *dec;
+	    *ra += PI;
+	}
+	range (ra, 2*PI);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: mjd.c,v $ $Date: 2006-11-22 13:53:29 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/moon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/moon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/moon.c	(revision 3445)
@@ -0,0 +1,3467 @@
+/* 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 <stdlib.h>
+#include <stdio.h>
+#include <math.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 (double x);
+static void mean_elements (double JED);
+static int sscc (int k, double arg, int n);
+static int g2plan (double J, struct plantbl *plan, double *pobj, int flag);
+static double g1plan (double J, struct plantbl *plan);
+static int gecmoon (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(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 (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 (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 (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 (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 (double J, struct plantbl *lrtab, struct plantbl *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 (double mj, 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 (double mj, double *lam, double *bet, double *hp, double *msp,
+double *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 = mj/36525.;
+	t2 = t*t;
+
+	m1 = mj/27.32158213;
+	m1 = 360.0*(m1-(long)m1);
+	m2 = mj/365.2596407;
+	m2 = 360.0*(m2-(long)m2);
+	m3 = mj/27.55455094;
+	m3 = 360.0*(m3-(long)m3);
+	m4 = mj/29.53058868;
+	m4 = 360.0*(m4-(long)m4);
+	m5 = mj/27.21222039;
+	m5 = 360.0*(m5-(long)m5);
+	m6 = mj/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 (double mj, double *lam, double *bet, double *rho, double *msp,
+double *mdp)
+{
+	double pobj[3], dt;
+	double hp;
+
+	if (mj >= MOSHIER_BEGIN && mj <= MOSHIER_END) {
+		/* retard for light time */
+		moon_fast (mj, lam, bet, &hp, msp, mdp);
+		*rho = EarthRadius/AUKM/sin(hp);
+		dt = *rho * 5.7755183e-3;       /* speed of light in a.u/day */
+		gecmoon(mj + 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 (mj, 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: 2006-11-22 13:53:29 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/mooncolong.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/mooncolong.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/mooncolong.c	(revision 3445)
@@ -0,0 +1,236 @@
+/* code to compute lunar sunrise position and local sun angle.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void Librations (double RAD, double LAMH, double BH, double OM,
+    double F, double L, double L1, double *L0, double *B0);
+static void Moon (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 (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 (
+double jd,	/* jd */
+double lt,	/* lat of location on moon, rads +N +E */
+double lg,	/* 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 (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 (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 (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]);
+	    abort();
+	}
+
+	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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/moonnf.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/moonnf.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/moonnf.c	(revision 3445)
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void m (double t, double k, double *mj);
+
+#define	unw(w,z)	((w)-floor((w)/(z))*(z))
+
+/* given a modified Julian date, mj, return the mjd of the new
+ * and full moons about then, mjn and mjf.
+ * TODO: exactly which ones does it find? eg:
+ *   5/28/1988 yields 5/15 and 5/31
+ *   5/29             6/14     6/29
+ */
+void
+moonnf (double mj, double *mjn, double *mjf)
+{
+	int mo, yr;
+	double dy;
+	double mj0;
+	double k, tn, tf, t;
+
+	mjd_cal (mj, &mo, &dy, &yr);
+	cal_mjd (1, 0., yr, &mj0);
+	k = (yr-1900+((mj-mj0)/365))*12.3685;
+	k = floor(k+0.5);
+	tn = k/1236.85;
+	tf = (k+0.5)/1236.85;
+	t = tn;
+	m (t, k, mjn);
+	t = tf;
+	k += 0.5;
+	m (t, k, mjf);
+}
+
+static void
+m (double t, double k, double *mj)
+{
+	double t2, a, a1, b, b1, c, ms, mm, f, ddjd;
+
+	t2 = t*t;
+	a = 29.53*k;
+	c = degrad(166.56+(132.87-9.173e-3*t)*t);
+	b = 5.8868e-4*k+(1.178e-4-1.55e-7*t)*t2+3.3e-4*sin(c)+7.5933E-1;
+	ms = 359.2242+360*unw(k/1.236886e1,1)-(3.33e-5+3.47e-6*t)*t2;
+	mm = 306.0253+360*unw(k/9.330851e-1,1)+(1.07306e-2+1.236e-5*t)*t2;
+	f = 21.2964+360*unw(k/9.214926e-1,1)-(1.6528e-3+2.39e-6*t)*t2;
+	ms = unw(ms,360);
+	mm = unw(mm,360);
+	f = unw(f,360);
+	ms = degrad(ms);
+	mm = degrad(mm);
+	f = degrad(f);
+	ddjd = (1.734e-1-3.93e-4*t)*sin(ms)+2.1e-3*sin(2*ms)
+		-4.068e-1*sin(mm)+1.61e-2*sin(2*mm)-4e-4*sin(3*mm)
+		+1.04e-2*sin(2*f)-5.1e-3*sin(ms+mm)-7.4e-3*sin(ms-mm)
+		+4e-4*sin(2*f+ms)-4e-4*sin(2*f-ms)-6e-4*sin(2*f+mm)
+		+1e-3*sin(2*f-mm)+5e-4*sin(ms+2*mm);
+	a1 = (long)a;
+	b = b+ddjd+(a-a1);
+	b1 = (long)b;
+	a = a1+b1;
+	b = b-b1;
+	*mj = a + b;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: moonnf.c,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/nutation.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/nutation.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/nutation.c	(revision 3445)
@@ -0,0 +1,441 @@
+/* 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 <stdio.h>
+#include <math.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, mj, find the nutation in obliquity, *deps, and
+ * the nutation in longitude, *dpsi, each in radians.
+ */
+void
+nutation (
+double mj,
+double *deps,	/* on input:  precision parameter in arc seconds */
+double *dpsi)
+{
+	static double lastmj = -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 (mj == lastmj) {
+	    *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 = (mj - 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);
+
+	lastmj = mj;
+	*deps = lastdeps;
+	*dpsi = lastdpsi;
+}
+
+/* given the modified JD, mj, correct, IN PLACE, the right ascension *ra
+ * and declination *dec (both in radians) for nutation.
+ */
+void
+nut_eq (double mj, double *ra, double *dec)
+{
+	static double lastmj = -10000;
+	static double a[3][3];		/* rotation matrix */
+	double xold, yold, zold, x, y, z;
+
+	if (mj != lastmj) {
+	    double epsilon, dpsi, deps;
+	    double se, ce, sp, cp, sede, cede;
+
+	    obliquity(mj, &epsilon);
+	    nutation(mj, &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;
+
+	    lastmj = mj;
+	}
+
+	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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/obliq.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/obliq.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/obliq.c	(revision 3445)
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+#include "astro.h"
+
+/* given the modified Julian date, mj, find the mean obliquity of the
+ * ecliptic, *eps, in radians.
+ *
+ * IAU expression (see e.g. Astron. Almanac 1984); stern
+ */
+void
+obliquity (double mj, double *eps)
+{
+	static double lastmj = -16347, lasteps;
+
+	if (mj != lastmj) {
+	    double t = (mj - J2000)/36525.;	/* centuries from J2000 */
+	    lasteps = degrad(23.4392911 +	/* 23^ 26' 21".448 */
+			    t * (-46.8150 +
+			    t * ( -0.00059 +
+			    t * (  0.001813 )))/3600.0);
+	    lastmj = mj;
+	}
+	*eps = lasteps;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: obliq.c,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallactic.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallactic.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallactic.c	(revision 3445)
@@ -0,0 +1,54 @@
+/* compure parallactic angle: angle formed by N pole - Object - Zenith
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+/* compute parallactic angle given latitude, object dec and alt.
+ * all angles in rads.
+ * N.B. always return >= 0, caller must determine sign and degenerate cases at
+ *   pole or zenith.
+ */
+double
+parallacticLDA (double lt, double dec, double alt)
+{
+	double ca = sin(lt);
+	double cb = sin(dec);
+	double sb = cos(dec);
+	double cc = sin(alt);
+	double sc = cos(alt);
+	double cpa;
+
+	/* given three sides find an angle */
+	if (sb==0 || sc==0)
+	    return (0);
+	cpa = (ca - cb*cc)/(sb*sc);
+	if (cpa < -1) cpa = -1;
+	if (cpa >  1) cpa =  1;
+	return (acos (cpa));
+}
+
+/* compute parallactic angle given latitude, object HA and Dec.
+ * all angles in rads.
+ * return value is between -PI and PI, sign is like HA, ie +west
+ */
+double
+parallacticLHD (double lt, double ha, double dec)
+{
+	double A, b, cc, sc, B;
+
+	A = ha;
+	b = PI/2 - lt;
+	cc = sin(dec);
+	sc = cos(dec);
+	solve_sphere (A, b, cc, sc, NULL, &B);
+
+	if (B > PI)
+	    B -= 2*PI;
+	return (B);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: parallactic.c,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallax.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallax.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/parallax.c	(revision 3445)
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <math.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 (double tha, double tdec, double phi, double ht, double *rho,
+double *aha, double *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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/plans.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/plans.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/plans.c	(revision 3445)
@@ -0,0 +1,227 @@
+/* rewritten for Bureau des Longitude theories by Bretagnon and Chapront
+ * Michael Sternberg <sternberg@physik.tu-chemnitz.de>
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+#include "vsop87.h"
+#include "chap95.h"
+
+static void pluto_ell (double mj, double *ret);
+static void chap_trans (double mj, double *ret);
+static void planpos (double mj, 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 (
+double mj,	/* 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, mj, &ra, &dec);
+	obliquity(mj, &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 (
+double mj,	/* 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 */
+		mjp = 2448045.539 - MJD0,	/* epoch of perihel */
+		mjeq = 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(mjeq, mj, degrad(inc0), degrad(omeg0), degrad(Om0),
+				&inc, &omeg, &Om);
+	ma = degrad((mj - mjp) * 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 (double mj, int obj, double prec, double *ret)
+{
+	if (mj >= CHAP_BEGIN && mj <= CHAP_END) {
+	    if (obj >= JUPITER) {		/* prefer Chapront */
+		chap95(mj, obj, prec, ret);
+		chap_trans (mj, ret);
+	    } else {				/* VSOP for inner planets */
+		vsop87(mj, obj, prec, ret);
+	    }
+	} else {				/* outside Chapront time: */
+	    if (obj != PLUTO) {			/* VSOP for all but Pluto */
+		vsop87(mj, obj, prec, ret);
+	    } else {				/* Pluto mean elliptic orbit */
+		pluto_ell(mj, 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, mj, 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 (double mj, PLCode p, double *lpd0, double *psi0, double *rp0,
+double *rho0, double *lam, double *bet, double *dia, double *mag)
+{
+	static double lastmj = -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 mj */
+	if (mj != lastmj) {
+	    sunpos (mj, &lsn, &rsn, &bsn);
+	    sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn);
+            lastmj = mj;
+        }
+
+	/* first find the true position of the planet at mj.
+	 * 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(mj - 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, mj+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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/plmoon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/plmoon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/plmoon.c	(revision 3445)
@@ -0,0 +1,284 @@
+/* compute Obj fields for natural satellites.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "astro.h"
+
+/* private cache of planet ephemerides and when they were computed
+ * N.B. don't use ones in builtin[] -- they are the user's responsibility.
+ */
+static ObjPl plobj[NOBJ];
+static Now plnow[NOBJ];
+
+/* public builtin storage
+ */
+static Obj builtin[NBUILTIN];
+
+static char *moondir;
+
+static void setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp);
+static void init1BI (int idx, int pl, int moon, char *name);
+static void initPlobj(void);
+static void rotate (double a, double *x, double *y);
+
+/* directory in which to look for auxil moon data files.
+ * N.B. caller must supply persistent storage.
+ */
+void
+setMoonDir (char *dir)
+{
+	moondir = dir;
+}
+
+/* return set of builtin objects.
+ * caller can use this storage but should never try to free anything.
+ */
+int
+getBuiltInObjs (Obj **opp)
+{
+	if (!builtin[MERCURY].o_name[0]) {
+	    /* first time only */
+
+	    init1BI (MERCURY,   MERCURY, X_PLANET,    "Mercury");
+
+	    init1BI (VENUS,     VENUS,   X_PLANET,    "Venus");
+
+	    init1BI (MARS,      MARS,    X_PLANET,    "Mars");
+	    init1BI (PHOBOS,    MARS,    M_PHOBOS,    "Phobos");
+	    init1BI (DEIMOS,    MARS,    M_DEIMOS,    "Deimos");
+
+	    init1BI (JUPITER,   JUPITER, X_PLANET,    "Jupiter");
+	    init1BI (IO,        JUPITER, J_IO,        "Io");
+	    init1BI (EUROPA,    JUPITER, J_EUROPA,    "Europa");
+	    init1BI (GANYMEDE,  JUPITER, J_GANYMEDE,  "Ganymede");
+	    init1BI (CALLISTO,  JUPITER, J_CALLISTO,  "Callisto");
+
+	    init1BI (SATURN,    SATURN,  X_PLANET,    "Saturn");
+	    init1BI (MIMAS,     SATURN,  S_MIMAS,     "Mimas");
+	    init1BI (ENCELADUS, SATURN,  S_ENCELADUS, "Enceladus");
+	    init1BI (TETHYS,    SATURN,  S_TETHYS,    "Tethys");
+	    init1BI (DIONE,     SATURN,  S_DIONE,     "Dione");
+	    init1BI (RHEA,      SATURN,  S_RHEA,      "Rhea");
+	    init1BI (TITAN,     SATURN,  S_TITAN,     "Titan");
+	    init1BI (HYPERION,  SATURN,  S_HYPERION,  "Hyperion");
+	    init1BI (IAPETUS,   SATURN,  S_IAPETUS,   "Iapetus");
+
+	    init1BI (URANUS,    URANUS,  X_PLANET,    "Uranus");
+	    init1BI (ARIEL,     URANUS,  U_ARIEL,     "Ariel");
+	    init1BI (UMBRIEL,   URANUS,  U_UMBRIEL,   "Umbriel");
+	    init1BI (TITANIA,   URANUS,  U_TITANIA,   "Titania");
+	    init1BI (OBERON,    URANUS,  U_OBERON,    "Oberon");
+	    init1BI (MIRANDA,   URANUS,  U_MIRANDA,   "Miranda");
+
+	    init1BI (NEPTUNE,   NEPTUNE, X_PLANET,    "Neptune");
+
+	    init1BI (PLUTO,     PLUTO,   X_PLANET,    "Pluto");
+
+	    init1BI (SUN,       SUN,     X_PLANET,    "Sun");
+
+	    init1BI (MOON,      MOON,    X_PLANET,    "Moon");
+	}
+
+	*opp = builtin;
+	return (NBUILTIN);
+}
+
+static void
+init1BI (int idx, int pl, int moon, char *name)
+{
+	strcpy (builtin[idx].o_name, name);
+	builtin[idx].o_type = PLANET;
+	builtin[idx].pl_code = pl;
+	builtin[idx].pl_moon = moon;
+}
+
+/* find the circumstances for natural satellite object op at np.
+ * TODO: distances and helio coords just copied from parent planet.
+ */
+int
+plmoon_cir (Now *np, Obj *moonop)
+{
+	Obj *sunop = (Obj*)&plobj[SUN];
+	MoonData md[X_MAXNMOONS];
+	double sz, t1, t2;
+	double pra, pdec;
+	MoonData *mdp;
+	Obj *planop;
+
+	/* init plobj[] */
+	if (!((Obj *)&plobj[0])->o_type)
+	    initPlobj();
+
+	/* get sun @ np */
+	if (memcmp (&plnow[SUN], np, sizeof(Now))) {
+	    obj_cir (np, (Obj*)&plobj[SUN]);
+	    memcpy (&plnow[SUN], np, sizeof(Now));
+	}
+
+	/* get parent planet and moon info @ np */
+	switch (moonop->pl_code) {
+
+	case MARS:
+	case PHOBOS:
+	case DEIMOS:
+
+	    planop = (Obj*)&plobj[MARS];
+
+	    if (memcmp (&plnow[MARS], np, sizeof(Now))) {
+		obj_cir (np, planop);
+		memcpy (&plnow[MARS], np, sizeof(Now));
+	    }
+
+	    /* don't worry, this already caches based on same mjd */
+	    marsm_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md);
+	    mdp = &md[moonop->pl_moon];
+	    break;
+
+	case JUPITER:
+	case IO:
+	case EUROPA:
+	case GANYMEDE:
+	case CALLISTO:
+
+	    planop = (Obj*)&plobj[JUPITER];
+
+	    if (memcmp (&plnow[JUPITER], np, sizeof(Now))) {
+		obj_cir (np, planop);
+		memcpy (&plnow[JUPITER], np, sizeof(Now));
+	    }
+
+	    /* don't worry, this already caches based on same mjd */
+	    jupiter_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md);
+	    mdp = &md[moonop->pl_moon];
+	    moonop->pl_aux1 = t1;
+	    moonop->pl_aux2 = t2;
+	    break;
+
+	case SATURN:
+	case MIMAS:
+	case ENCELADUS:
+	case TETHYS:
+	case DIONE:
+	case RHEA:
+	case TITAN:
+	case HYPERION:
+	case IAPETUS:
+
+	    planop = (Obj*)&plobj[SATURN];
+
+	    if (memcmp (&plnow[SATURN], np, sizeof(Now))) {
+		obj_cir (np, planop);
+		memcpy (&plnow[SATURN], np, sizeof(Now));
+	    }
+
+	    /* don't worry, this already caches based on same mjd */
+	    saturn_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md);
+	    mdp = &md[moonop->pl_moon];
+	    moonop->pl_aux1 = t1;
+	    moonop->pl_aux2 = t2;
+	    break;
+
+	case URANUS:
+	case ARIEL:
+	case UMBRIEL:
+	case TITANIA:
+	case OBERON:
+	case MIRANDA:
+
+	    planop = (Obj*)&plobj[URANUS];
+
+	    if (memcmp (&plnow[URANUS], np, sizeof(Now))) {
+		obj_cir (np, planop);
+		memcpy (&plnow[URANUS], np, sizeof(Now));
+	    }
+
+	    /* don't worry, this already caches based on same mjd */
+	    uranus_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md);
+	    mdp = &md[moonop->pl_moon];
+	    break;
+
+	default:
+
+	    printf ("Called plmoon_cir with bad code: %d\n",moonop->pl_code);
+	    return (-1);
+
+	}
+
+	/* set moonop */
+	setMoon (np, moonop, planop, mdp);
+
+	return (0);
+}
+
+static void
+initPlobj()
+{
+	int i;
+
+	for (i = 0; i < NOBJ; i++) {
+	    ((Obj*)&plobj[i])->o_type = PLANET;
+	    ((Obj*)&plobj[i])->pl_code = i;
+	}
+}
+
+/* set moonop->s_* fields.
+ * np is needed to get local parallactic angle.
+ */
+static void
+setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp)
+{
+	double pa, dra, ddec;
+
+	/* just copy most fields from planet for now */
+	moonop->s_gaera = planop->s_gaera;	/* TODO */
+	moonop->s_gaedec = planop->s_gaedec;	/* TODO */
+	moonop->s_elong = planop->s_elong;	/* TODO */
+	moonop->s_size = 0;			/* TODO */
+	moonop->s_sdist = planop->s_sdist;	/* TODO */
+	moonop->s_edist = planop->s_edist;	/* TODO */
+	moonop->s_hlat = planop->s_hlat;	/* TODO */
+	moonop->s_hlong = planop->s_hlong;	/* TODO */
+	moonop->s_phase = planop->s_phase;	/* TODO */
+
+	/* new ra/dec directly from mdp */
+	moonop->s_ra = mdp->ra;
+	moonop->s_dec = mdp->dec;
+
+	/* geoemtry info */
+	moonop->pl_x = mdp->x;
+	moonop->pl_y = mdp->y;
+	moonop->pl_z = mdp->z;
+	moonop->pl_evis = mdp->evis;
+	moonop->pl_svis = mdp->svis;
+
+	/* tweak alt/az by change in ra/dec rotated by pa */
+	pa = parallacticLDA (lat, planop->s_dec, planop->s_alt);
+	if (planop->s_az < PI)
+	    pa = -pa;			/* rotation radec to altaz */
+	dra = (moonop->s_ra - planop->s_ra)*cos(planop->s_dec);
+	ddec = moonop->s_dec - planop->s_dec;
+	rotate (pa, &dra, &ddec);
+	moonop->s_alt = planop->s_alt + ddec;
+	moonop->s_az = planop->s_az - dra/cos(planop->s_alt);
+
+	/* new mag directly from mdp */
+	set_smag (moonop, mdp->mag);
+
+	/* name */
+	strcpy (moonop->o_name, mdp->full);
+}
+
+/* rotate ccw by a */
+static void
+rotate (double a, double *x, double *y)
+{
+	double sa = sin(a);
+	double ca = cos(a);
+	double xp = (*x)*ca - (*y)*sa;
+	double yp = (*x)*sa + (*y)*ca;
+	*x = xp;
+	*y = yp;
+}
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/plshadow.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/plshadow.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/plshadow.c	(revision 3445)
@@ -0,0 +1,50 @@
+#include <math.h>
+
+#include "astro.h"
+
+#undef sqr
+#define	sqr(x)		((x)*(x))
+
+/* given a planet, the sun, the planet's eq pole position and a
+ * position of a satellite (as eq x=+e y=+s z=front in planet radii) find x,y
+ * position of shadow.
+ * return 0 if ok else -1 if shadow not on planet
+ */
+int
+plshadow (Obj *op, Obj *sop, double polera, double poledec, double x,
+double y, double z, float *sxp, float *syp)
+{
+	/* equatorial to ecliptic sky-plane rotation */
+	double sa = cos(op->s_dec) * cos(poledec) *
+			(cos(op->s_ra)*sin(polera) - sin(op->s_ra)*cos(polera));
+	double ca = sqrt (1.0 - sa*sa);
+
+	/* rotate moon from equatorial to ecliptic */
+	double ex =  x*ca + y*sa;
+	double ey = -x*sa + y*ca;
+
+	/* find angle subtended by earth-sun from planet */
+	double a = asin (sin(op->s_hlong - sop->s_hlong)/op->s_edist);
+	double b = asin (-sin(op->s_hlat)/op->s_edist);
+
+	/* find displacement in sky plane */
+	double x0 = ex - z*tan(a);
+	double y0 = ey - z*tan(b);
+
+	/* projection onto unit sphere */
+	double x1 = x0 + (ex-x0)/sqrt(sqr(ex-x0)+sqr(z));
+	double y1 = y0 + (ey-y0)/sqrt(sqr(ey-y0)+sqr(z));
+
+	/* check behind or off edge */
+	if (z < 0 || sqr(x1) + sqr(y1) > 1)
+	    return (-1);
+
+	/* rotate back to equatorial */
+	*sxp = x1*ca - y1*sa;
+	*syp = x1*sa + y1*ca;
+
+	return (0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: plshadow.c,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/precess.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/precess.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/precess.c	(revision 3445)
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void precess_hiprec (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 (
+double mjd1, double mjd2,	/* initial and final epoch modified JDs */
+double *ra, double *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 (
+double mjd1, double mjd2,	/* initial and final epoch modified JDs */
+double *ra, double *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 (
+double mjd1, double mjd2,	/* initial and final epoch modified JDs */
+double *ra, double *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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/preferences.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/preferences.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/preferences.h	(revision 3445)
@@ -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 (Preferences p);
+extern int pref_set (Preferences p, int newp);
+
+#endif /* _PREFERENCES_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: preferences.h,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/reduce.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/reduce.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/reduce.c	(revision 3445)
@@ -0,0 +1,78 @@
+#include <math.h>
+
+#include <stdio.h>
+
+#include "astro.h"
+
+/* convert those orbital elements that change from epoch mj0 to epoch mj.
+ */
+void
+reduce_elements (
+double mj0,	/* initial epoch */
+double mj,	/* desired epoch */
+double inc0,	/* initial inclination, rads */
+double ap0,	/* initial argument of perihelion, as an mj */
+double om0,	/* initial long of ascending node, rads */
+double *inc,	/* resultant inclination, rads */
+double *ap,	/* resultant arg of perihelion, as an mj */
+double *om)	/* resultant 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(mj - mj0) < 1e-5) {
+	    /* sin(eta) blows for inc < 10 degrees -- anyway, no need */
+	    *inc = inc0;
+	    *ap = ap0;
+	    *om = om0;
+	    return;
+	}
+
+	t0 = mj0/365250.0;
+	t1 = mj/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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/refract.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/refract.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/refract.c	(revision 3445)
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+static void unrefractLT15 (double pr, double tr, double aa, double *ta);
+static void unrefractGE15 (double pr, double tr, double aa, double *ta);
+
+void
+unrefract (double pr, double 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 (double pr, double tr, double aa, double *ta)
+{
+	double r;
+	
+	r = 7.888888e-5*pr/((273+tr)*tan(aa));
+	*ta  =  aa - r;
+}
+
+static void
+unrefractLT15 (double pr, double 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 (double pr, double 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: 2006-11-22 13:53:30 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/rings.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/rings.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/rings.c	(revision 3445)
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "astro.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 (
+double sb, double sl, double sr,	/* Saturn hlat, hlong, sun dist */
+double el, double er,			/* Earth hlong, sun dist */
+double JD,				/* Julian date */
+double *etiltp, double *stiltp)		/* tilt from earth and sun, rads south*/
+{
+	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;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: rings.c,v $ $Date: 2006-11-22 13:53:30 $ $Revision: 1.5 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset.c	(revision 3445)
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+
+/* given the true geocentric ra and dec of an object, the observer's latitude,
+ *   lt, 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 (double ra, double dec, double lt, double dis, double *lstr,
+double *lsts, double *azr, double *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 lt and dec if in southern hemisphere, then az back later */
+	if ((shemi= (lt < 0.)) != 0) {
+	    lt = -lt;
+	    dec = -dec;
+	}
+
+	/* establish zenith angle, and its extrema */
+	z = (PI/2.) + dis;
+	zmin = fabs (dec - lt);
+	zmax = PI - fabs(dec + lt);
+
+	/* 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(lt)*sin(dec))/(cos(lt)*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(lt)-cos(dec)*cos(h)*sin(lt);
+	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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset_cir.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset_cir.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/riset_cir.c	(revision 3445)
@@ -0,0 +1,372 @@
+/* find rise and set circumstances, ie, riset_cir() and related functions. */
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "astro.h"
+
+#define	TMACC	(10./3600./24.0)	/* convergence accuracy, days */
+
+static void e_riset_cir (Now *np, Obj *op, double dis, RiseSet *rp);
+static int find_0alt (double dt, double dis, Now *np, Obj *op);
+static int find_transit (double dt, Now *np, Obj *op);
+static int find_max (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 (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 if dis is above horizon 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+(dis>.01 ? 0 : .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 (Now *np, double dis, double *dawn, double *dusk, int *status)
+{
+	RiseSet rs;
+	Obj o;
+
+	memset (&o, 0, sizeof(o));
+	o.o_type = PLANET;
+	o.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 (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 (
+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 && !find_0alt (dt+24, dis, np, op))
+	    return (0);
+	mjd = mjdn;
+	if (dt > 12.0 && !find_0alt (dt-24, dis, np, op))
+	    return (0);
+	mjd = mjdn;
+	
+	/* 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 (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 (
+Now *np,
+Obj *op,
+double tr, double ts,		/* times of rise and set */
+double *tp, double *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: 2006-11-22 13:53:30 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/satlib.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/satlib.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/satlib.h	(revision 3445)
@@ -0,0 +1,206 @@
+#ifndef __SATLIB_H
+#define __SATLIB_H
+
+/* $Id: satlib.h,v 1.6 2006-11-22 13:53:31 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/satmoon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/satmoon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/satmoon.c	(revision 3445)
@@ -0,0 +1,510 @@
+/* saturn moon info */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include "astro.h"
+#include "bdl.h"
+
+static int use_bdl (double JD, char *dir, MoonData md[S_NMOONS]);
+static void bruton_saturn (Obj *sop, double JD, MoonData md[S_NMOONS]);
+static void moonradec (double satsize, MoonData md[S_NMOONS]);
+static void moonSVis (Obj *eop, Obj *sop, MoonData md[S_NMOONS]);
+static void moonEVis (MoonData md[S_NMOONS]);
+static void moonPShad (Obj *eop, Obj *sop, MoonData md[S_NMOONS]);
+static void moonTrans (MoonData md[S_NMOONS]);
+
+/* moon table and a few other goodies and when it was last computed */
+static double mdmjd = -123456;
+static MoonData smd[S_NMOONS] = {
+    {"Saturn",	NULL},
+    {"Mimas",	"I"},
+    {"Enceladus","II"},
+    {"Tethys",	"III"},
+    {"Dione",	"IV"},
+    {"Rhea",	"V"},
+    {"Titan",	"VI"},
+    {"Hyperion","VII"},
+    {"Iapetus",	"VIII"},
+};
+static double sizemjd;
+static double etiltmjd;
+static double stiltmjd;
+
+/* These values are from the Explanatory Supplement.
+ * Precession degrades them gradually over time.
+ */
+#define POLE_RA         degrad(40.58)   /* RA of Saturn's north pole */
+#define POLE_DEC        degrad(83.54)   /* Dec of Saturn's north pole */
+
+
+/* get saturn info in md[0], moon info in md[1..S_NMOONS-1].
+ * if !dir always use bruton model.
+ * if !sop caller just wants md[] for names
+ * N.B. we assume eop and sop are updated.
+ */
+void
+saturn_data (
+double Mjd,			/* mjd */
+char dir[],			/* dir in which to look for helper files */
+Obj *eop,			/* earth == Sun */
+Obj *sop,			/* saturn */
+double *sizep,			/* saturn's angular diam, rads */
+double *etiltp, double *stiltp,	/* earth and sun tilts -- +S */
+double *polera, double *poledec,/* pole location */
+MoonData md[S_NMOONS])		/* return info */
+{
+	double JD;
+
+	/* always copy back at least for name */
+	memcpy (md, smd, sizeof(smd));
+
+	/* pole */
+	if (polera) *polera = POLE_RA;
+	if (poledec) *poledec = POLE_DEC;
+
+	/* nothing else if repeat call or just want names */
+	if (Mjd == mdmjd || !sop) {
+	    if (sop) {
+		*sizep = sizemjd;
+		*etiltp = etiltmjd;
+		*stiltp = stiltmjd;
+	    }
+	    return;
+	}
+	JD = Mjd + MJD0;
+
+	/* planet in [0] */
+	md[0].ra = sop->s_ra;
+	md[0].dec = sop->s_dec;
+	md[0].mag = get_mag(sop);
+	md[0].x = 0;
+	md[0].y = 0;
+	md[0].z = 0;
+	md[0].evis = 1;
+	md[0].svis = 1;
+
+	/* size is straight from sop */
+	*sizep = degrad(sop->s_size/3600.0);
+
+	/*  Visual Magnitude of the Satellites */
+
+	md[1].mag = 13; md[2].mag = 11.8; md[3].mag = 10.3; md[4].mag = 10.2;
+	md[5].mag = 9.8; md[6].mag = 8.4; md[7].mag = 14.3; md[8].mag = 11.2;
+
+	/* get tilts from sky and tel code */
+	satrings (sop->s_hlat, sop->s_hlong, sop->s_sdist, eop->s_hlong,
+					    eop->s_edist, JD, etiltp, stiltp);
+
+	/* get moon x,y,z from BDL if possible, else Bruton's model */
+	if (dir && use_bdl (JD, dir, md) < 0)
+	    bruton_saturn (sop, JD, md);
+
+	/* set visibilities */
+	moonSVis (eop, sop, md);
+	moonPShad (eop, sop, md);
+	moonEVis (md);
+	moonTrans (md);
+
+	/* fill in moon ra and dec */
+	moonradec (*sizep, md);
+
+	/* save */
+	mdmjd = Mjd;
+	etiltmjd = *etiltp;
+	stiltmjd = *stiltp;
+	sizemjd = *sizep;
+	memcpy (smd, md, sizeof(smd));
+}
+
+/* hunt for BDL file in dir[] and use if possible.
+ * return 0 if ok, else -1
+ */
+static int
+use_bdl (
+double JD,		/* julian date */
+char dir[],		/* directory */
+MoonData md[S_NMOONS])	/* fill md[1..NM-1].x/y/z for each moon */
+{
+#define	SATRAU	.0004014253	/* saturn radius, AU */
+	double x[S_NMOONS], y[S_NMOONS], z[S_NMOONS];
+	char buf[1024];
+	FILE *fp;
+	char *fn;
+	int i;
+
+	/* check ranges and appropriate data file */
+	if (JD < 2451179.50000)		/* Jan 1 1999 UTC */
+	    return (-1);
+	if (JD < 2455562.5)		/* Jan 1 2011 UTC */
+	    fn = "saturne.9910";
+	else if (JD < 2459215.5)	/* Jan 1 2021 UTC */
+	    fn = "saturne.1020";
+	else
+	    return (-1);
+
+	/* open */
+	(void) sprintf (buf, "%s/%s", dir, fn);
+	fp = fopen (buf, "r");
+	if (!fp) {
+	    fprintf (stderr, "%s: %s\n", fn, strerror(errno));
+	    return (-1);
+	}
+
+	/* use it */
+	if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) {
+	    fprintf (stderr, "%s: %s\n", fn, buf);
+	    fclose (fp);
+	    return (-1);
+	}
+	if (i != S_NMOONS-1) {
+	    fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn,
+								i, S_NMOONS-1);
+	    fclose (fp);
+	    return (-1);
+	}
+
+	/* copy into md[1..NM-1] with our scale and sign conventions */
+	for (i = 1; i < S_NMOONS; i++) {
+	    md[i].x =  x[i-1]/SATRAU;	/* we want sat radii +E */
+	    md[i].y = -y[i-1]/SATRAU;	/* we want sat radii +S */
+	    md[i].z = -z[i-1]/SATRAU;	/* we want sat radii +front */
+	}
+
+	/* ok */
+	fclose (fp);
+	return (0);
+}
+
+/*  */
+/*     SS2TXT.BAS                     Dan Bruton, astro@tamu.edu */
+/*  */
+/*       This is a text version of SATSAT2.BAS.  It is smaller, */
+/*    making it easier to convert other languages (250 lines */
+/*    compared to 850 lines). */
+/*  */
+/*       This BASIC program computes and displays the locations */
+/*    of Saturn's Satellites for a given date and time.  See */
+/*    "Practical Astronomy with your Calculator" by Peter */
+/*    Duffett-Smith and the Astronomical Almanac for explanations */
+/*    of some of the calculations here.  The code is included so */
+/*    that users can make changes or convert to other languages. */
+/*    This code was made using QBASIC (comes with DOS 5.0). */
+/*  */
+/*    ECD: merged with Sky and Tel, below, for better earth and sun ring tilt */
+/*  */
+
+/* ECD: BASICeze */
+#define	FOR	for
+#define	IF	if
+#define	ELSE	else
+#define	COS	cos
+#define	SIN	sin
+#define	TAN	tan
+#define ATN	atan
+#define ABS	fabs
+#define SQR	sqrt
+
+/* find saturn moon data from Bruton's model */
+/* this originally computed +X:East +Y:North +Z:behind in [1..8] indeces.
+ * and +tilt:front south, rads
+ * then we adjust things in md[].x/y/z/mag to fit into our MoonData format.
+ */
+static void
+bruton_saturn (
+Obj *sop,		/* saturn */
+double JD,		/* julian date */
+MoonData md[S_NMOONS])	/* fill md[1..NM-1].x/y/z for each moon */
+{
+     /* ECD: code does not use [0].
+      * ECD and why 11 here? seems like 9 would do
+      */
+     double SMA[11], U[11], U0[11], PD[11];
+     double X[S_NMOONS], Y[S_NMOONS], Z[S_NMOONS];
+
+     double P,TP,TE,EP,EE,RE0,RP0,RS;
+     double JDE,LPE,LPP,LEE,LEP;
+     double NN,ME,MP,VE,VP;
+     double LE,LP,RE,RP,DT,II,F,F1;
+     double RA,DECL;
+     double TVA,PVA,TVC,PVC,DOT1,INC,TVB,PVB,DOT2,INCI;
+     double TRIP,GAM,TEMPX,TEMPY,TEMPZ;
+     int I;
+
+     /* saturn */
+     RA = sop->s_ra;
+     DECL = sop->s_dec;
+
+     /*  ******************************************************************** */
+     /*  *                                                                  * */
+     /*  *                        Constants                                 * */
+     /*  *                                                                  * */
+     /*  ******************************************************************** */
+     P = PI / 180;
+     /*  Orbital Rate of Saturn in Radians per Days */
+     TP = 2 * PI / (29.45771 * 365.2422);
+     /*  Orbital Rate of Earth in Radians per Day */
+     TE = 2 * PI / (1.00004 * 365.2422);
+     /*  Eccentricity of Saturn's Orbit */
+     EP = .0556155;
+     /*  Eccentricity of Earth's Orbit */
+     EE = .016718;
+     /*  Semimajor axis of Earth's and Saturn's orbit in Astronomical Units */
+     RE0 = 1; RP0 = 9.554747;
+     /*  Semimajor Axis of the Satellites' Orbit in Kilometers */
+     SMA[1] = 185600; SMA[2] = 238100; SMA[3] = 294700; SMA[4] = 377500;
+     SMA[5] = 527200; SMA[6] = 1221600; SMA[7] = 1483000; SMA[8] = 3560100;
+     /*  Eccentricity of Satellites' Orbit [Program uses 0] */
+     /*  Synodic Orbital Period of Moons in Days */
+     PD[1] = .9425049;
+     PD[2] = 1.3703731;
+     PD[3] = 1.8880926;
+     PD[4] = 2.7375218;
+     PD[5] = 4.5191631;
+     PD[6] = 15.9669028;
+     PD[7] = 21.3174647;
+     PD[8] = 79.9190206;	/* personal mail 1/14/95 */
+     RS = 60330; /*  Radius of planet in kilometers */
+    
+     /*  ******************************************************************** */
+     /*  *                                                                  * */
+     /*  *                      Epoch Information                           * */
+     /*  *                                                                  * */
+     /*  ******************************************************************** */
+     JDE = 2444238.5; /*  Epoch Jan 0.0 1980 = December 31,1979 0:0:0 UT */
+     LPE = 165.322242 * P; /*  Longitude of Saturn at Epoch */
+     LPP = 92.6653974 * P; /*  Longitude of Saturn`s Perihelion */
+     LEE = 98.83354 * P; /*  Longitude of Earth at Epoch */
+     LEP = 102.596403 * P; /*  Longitude of Earth's Perihelion */
+     /*  U0[I] = Angle from inferior geocentric conjuction */
+     /*          measured westward along the orbit at epoch */
+     U0[1] = 18.2919 * P;
+     U0[2] = 174.2135 * P;
+     U0[3] = 172.8546 * P;
+     U0[4] = 76.8438 * P;
+     U0[5] = 37.2555 * P;
+     U0[6] = 57.7005 * P;
+     U0[7] = 266.6977 * P;
+     U0[8] = 195.3513 * P;	/* from personal mail 1/14/1995 */
+    
+     /*  ******************************************************************** */
+     /*  *                                                                  * */
+     /*  *                    Orbit Calculations                            * */
+     /*  *                                                                  * */
+     /*  ******************************************************************** */
+     /*  ****************** FIND MOON ORBITAL ANGLES ************************ */
+     NN = JD - JDE; /*  NN = Number of days since epoch */
+     ME = ((TE * NN) + LEE - LEP); /*  Mean Anomoly of Earth */
+     MP = ((TP * NN) + LPE - LPP); /*  Mean Anomoly of Saturn */
+     VE = ME; VP = MP; /*  True Anomolies - Solve Kepler's Equation */
+     FOR (I = 1; I <= 3; I++) {
+	 VE = VE - (VE - (EE * SIN(VE)) - ME) / (1 - (EE * COS(VE)));
+	 VP = VP - (VP - (EP * SIN(VP)) - MP) / (1 - (EP * COS(VP)));
+     }
+     VE = 2 * ATN(SQR((1 + EE) / (1 - EE)) * TAN(VE / 2));
+     IF (VE < 0) VE = (2 * PI) + VE;
+     VP = 2 * ATN(SQR((1 + EP) / (1 - EP)) * TAN(VP / 2));
+     IF (VP < 0) VP = (2 * PI) + VP;
+     /*   Heliocentric Longitudes of Earth and Saturn */
+     LE = VE + LEP; IF (LE > (2 * PI)) LE = LE - (2 * PI);
+     LP = VP + LPP; IF (LP > (2 * PI)) LP = LP - (2 * PI);
+     /*   Distances of Earth and Saturn from the Sun in AU's */
+     RE = RE0 * (1 - EE * EE) / (1 + EE * COS(VE));
+     RP = RP0 * (1 - EP * EP) / (1 + EP * COS(VP));
+     /*   DT = Distance from Saturn to Earth in AU's - Law of Cosines */
+     DT = SQR((RE * RE) + (RP * RP) - (2 * RE * RP * COS(LE - LP)));
+     /*   II = Angle between Earth and Sun as seen from Saturn */
+     II = RE * SIN(LE - LP) / DT;
+     II = ATN(II / SQR(1 - II * II)); /*   ArcSIN and Law of Sines */
+     /*    F = NN - (Light Time to Earth in days) */
+     F = NN - (DT / 173.83);
+     F1 = II + MP - VP;
+     /*  U(I) = Angle from inferior geocentric conjuction measured westward */
+     FOR (I = 1; I < S_NMOONS; I++) {
+	U[I] = U0[I] + (F * 2 * PI / PD[I]) + F1;
+	U[I] = ((U[I] / (2 * PI)) - (int)(U[I] / (2 * PI))) * 2 * PI;
+
+     }
+
+     /*  **************** FIND INCLINATION OF RINGS ************************* */
+     /*  Use dot product of Earth-Saturn vector and Saturn's rotation axis */
+     TVA = (90 - 83.51) * P; /*  Theta coordinate of Saturn's axis */
+     PVA = 40.27 * P; /*  Phi coordinate of Saturn's axis */
+     TVC = (PI / 2) - DECL;
+     PVC = RA;
+     DOT1 = SIN(TVA) * COS(PVA) * SIN(TVC) * COS(PVC);
+     DOT1 = DOT1 + SIN(TVA) * SIN(PVA) * SIN(TVC) * SIN(PVC);
+     DOT1 = DOT1 + COS(TVA) * COS(TVC);
+     INC = ATN(SQR(1 - DOT1 * DOT1) / DOT1); /*    ArcCOS */
+     IF (INC > 0) INC = (PI / 2) - INC; ELSE INC = -(PI / 2) - INC;
+
+     /*  ************* FIND INCLINATION OF IAPETUS' ORBIT ******************* */
+     /*  Use dot product of Earth-Saturn vector and Iapetus' orbit axis */
+     /*  Vector B */
+     TVB = (90 - 75.6) * P; /*  Theta coordinate of Iapetus' orbit axis (estimate) */
+     PVB = 21.34 * 2 * PI / 24; /*  Phi coordinate of Iapetus' orbit axis (estimate) */
+     DOT2 = SIN(TVB) * COS(PVB) * SIN(TVC) * COS(PVC);
+     DOT2 = DOT2 + SIN(TVB) * SIN(PVB) * SIN(TVC) * SIN(PVC);
+     DOT2 = DOT2 + COS(TVB) * COS(TVC);
+     INCI = ATN(SQR(1 - DOT2 * DOT2) / DOT2); /*    ArcCOS */
+     IF (INCI > 0) INCI = (PI / 2) - INCI; ELSE INCI = -(PI / 2) - INCI;
+
+     /*  ************* FIND ROTATION ANGLE OF IAPETUS' ORBIT **************** */
+     /*  Use inclination of Iapetus' orbit with respect to ring plane */
+     /*  Triple Product */
+     TRIP = SIN(TVC) * COS(PVC) * SIN(TVA) * SIN(PVA) * COS(TVB);
+     TRIP = TRIP - SIN(TVC) * COS(PVC) * SIN(TVB) * SIN(PVB) * COS(TVA);
+     TRIP = TRIP + SIN(TVC) * SIN(PVC) * SIN(TVB) * COS(PVB) * COS(TVA);
+     TRIP = TRIP - SIN(TVC) * SIN(PVC) * SIN(TVA) * COS(PVA) * COS(TVB);
+     TRIP = TRIP + COS(TVC) * SIN(TVA) * COS(PVA) * SIN(TVB) * SIN(PVB);
+     TRIP = TRIP - COS(TVC) * SIN(TVB) * COS(PVB) * SIN(TVA) * SIN(PVA);
+     GAM = -1 * ATN(TRIP / SQR(1 - TRIP * TRIP)); /*  ArcSIN */
+    
+     /*  ******************************************************************** */
+     /*  *                                                                  * */
+     /*  *                     Compute Moon Positions                       * */
+     /*  *                                                                  * */
+     /*  ******************************************************************** */
+     FOR (I = 1; I < S_NMOONS - 1; I++) {
+	 X[I] = -1 * SMA[I] * SIN(U[I]) / RS;
+	 Z[I] = -1 * SMA[I] * COS(U[I]) / RS;	/* ECD */
+	 Y[I] = SMA[I] * COS(U[I]) * SIN(INC) / RS;
+     }
+     /*  ************************* Iapetus' Orbit *************************** */
+     TEMPX = -1 * SMA[8] * SIN(U[8]) / RS;
+     TEMPZ = -1 * SMA[8] * COS(U[8]) / RS;
+     TEMPY = SMA[8] * COS(U[8]) * SIN(INCI) / RS;
+     X[8] = TEMPX * COS(GAM) + TEMPY * SIN(GAM); /*       Rotation */
+     Z[8] = TEMPZ * COS(GAM) + TEMPY * SIN(GAM);
+     Y[8] = -1 * TEMPX * SIN(GAM) + TEMPY * COS(GAM);
+    
+#ifdef SHOWALL
+     /*  ******************************************************************** */
+     /*  *                                                                  * */
+     /*  *                          Show Results                            * */
+     /*  *                                                                  * */
+     /*  ******************************************************************** */
+     printf ("                           Julian Date : %g\n", JD);
+     printf ("             Right Ascension of Saturn : %g Hours\n", RA * 24 / (2 * PI));
+     printf ("                 Declination of Saturn : %g\n", DECL / P);
+     printf ("   Ring Inclination as seen from Earth : %g\n", -1 * INC / P);
+     printf ("      Heliocentric Longitude of Saturn : %g\n", LP / P);
+     printf ("       Heliocentric Longitude of Earth : %g\n", LE / P);
+     printf ("                Sun-Saturn-Earth Angle : %g\n", II / P);
+     printf ("     Distance between Saturn and Earth : %g AU = %g million miles\n", DT, (DT * 93));
+     printf ("       Light time from Saturn to Earth : %g minutes\n", DT * 8.28);
+     TEMP = 2 * ATN(TAN(165.6 * P / (2 * 3600)) / DT) * 3600 / P;
+     printf ("                Angular Size of Saturn : %g arcsec\n", TEMP);
+     printf ("  Major Angular Size of Saturn's Rings : %g arcsec\n", RS4 * TEMP / RS);
+     printf ("  Minor Angular Size of Saturn's Rings : %g arcsec\n", ABS(RS4 * TEMP * SIN(INC) / RS));
+#endif
+
+     /* copy into md[1..S_NMOONS-1] with our sign conventions */
+     for (I = 1; I < S_NMOONS; I++) {
+	md[I].x =  X[I];	/* we want +E */
+	md[I].y = -Y[I];	/* we want +S */
+	md[I].z = -Z[I];	/* we want +front */
+     }
+}
+
+/* given saturn loc in md[0].ra/dec and size, and location of each moon in 
+ * md[1..NM-1].x/y in sat radii, find ra/dec of each moon in md[1..NM-1].ra/dec.
+ */
+static void
+moonradec (
+double satsize,		/* sat diameter, rads */
+MoonData md[S_NMOONS])	/* fill in RA and Dec */
+{
+	double satrad = satsize/2;
+	double satra = md[0].ra;
+	double satdec = md[0].dec;
+	int i;
+
+	for (i = 1; i < S_NMOONS; i++) {
+	    double dra  = satrad * md[i].x;
+	    double ddec = satrad * md[i].y;
+	    md[i].ra  = satra + dra;
+	    md[i].dec = satdec - ddec;
+	}
+}
+
+/* set svis according to whether moon is in sun light */
+static void
+moonSVis(
+Obj *eop,		/* earth == SUN */
+Obj *sop,		/* saturn */
+MoonData md[S_NMOONS])
+{
+	double esd = eop->s_edist;
+	double eod = sop->s_edist;
+	double sod = sop->s_sdist;
+	double soa = degrad(sop->s_elong);
+	double esa = asin(esd*sin(soa)/sod);
+	double   h = sod*sop->s_hlat;
+	double nod = h*(1./eod - 1./sod);
+	double sca = cos(esa), ssa = sin(esa);
+	int i;
+
+	for (i = 1; i < S_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    double xp =  sca*mdp->x + ssa*mdp->z;
+	    double yp =  mdp->y;
+	    double zp = -ssa*mdp->x + sca*mdp->z;
+	    double ca = cos(nod), sa = sin(nod);
+	    double xpp = xp;
+	    double ypp = ca*yp - sa*zp;
+	    double zpp = sa*yp + ca*zp;
+	    int outside = xpp*xpp + ypp*ypp > 1.0;
+	    int infront = zpp > 0.0;
+	    mdp->svis = outside || infront;
+	}
+}
+
+/* set evis according to whether moon is geometrically visible from earth */
+static void
+moonEVis (MoonData md[S_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < S_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
+	    int infront = mdp->z > 0.0;
+	    mdp->evis = outside || infront;
+	}
+}
+
+/* set pshad and sx,sy shadow info */
+static void
+moonPShad(
+Obj *eop,             /* earth == SUN */
+Obj *sop,             /* saturn */
+MoonData md[S_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < S_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->pshad = !plshadow (sop, eop, POLE_RA, POLE_DEC, mdp->x,
+					  mdp->y, mdp->z, &mdp->sx, &mdp->sy);
+	}
+}
+
+
+/* set whether moons are transiting */
+static void
+moonTrans (MoonData md[S_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < S_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: satmoon.c,v $ $Date: 2006-11-22 13:53:31 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/satspec.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/satspec.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/satspec.h	(revision 3445)
@@ -0,0 +1,43 @@
+#ifndef __SATSPEC_H
+#define __SATSPEC_H
+
+/* $Id: satspec.h,v 1.6 2006-11-22 13:53:31 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/sattypes.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/sattypes.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/sattypes.h	(revision 3445)
@@ -0,0 +1,28 @@
+#ifndef __SATTYPES_H
+#define __SATTYPES_H
+
+/* $Id: sattypes.h,v 1.6 2006-11-22 13:53:31 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/sdp4.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/sdp4.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/sdp4.c	(revision 3445)
@@ -0,0 +1,430 @@
+#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 (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=0,
+	COSIK,COSNOK,COSU,COSUK,E,ECOSE,ELSQ,EM=0,EPW,ESINE,OMGADF,PL,
+	R,RDOT,RDOTK,RFDOT,RFDOTK,RK,SIN2U,SINEPW=0,SINIK,SINNOK,
+	SINU,SINUK,TEMP,TEMP1,TEMP2,TEMP3=0,TEMP4=0,TEMP5=0,TEMP6=0,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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/sgp4.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/sgp4.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/sgp4.c	(revision 3445)
@@ -0,0 +1,401 @@
+#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(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=0, THETA2, THETA4, TSI, X1M5TH,
+	XHDOT1;
+
+    double A, AXN, AYN, AYNL, BETA, BETAL, CAPU, COS2U, COSEPW=0, COSIK,
+	COSNOK, COSU, COSUK, DELM, DELOMG, E, ECOSE, ELSQ, EPW, ESINE,
+	OMEGA, OMGADF, PL, R, RDOT, RDOTK, RFDOT, RFDOTK, RK, SIN2U,
+	SINEPW=0, SINIK, SINNOK, SINU, SINUK, TCUBE, TEMP4=0, TEMP5=0, TEMP6=0,
+	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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/smakefile	(revision 3445)
@@ -0,0 +1,183 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+all: libxastro.a
+
+clean:
+	rm -f libxastro.a *.o testxephem
+
+OBJASTRO = aa_hadec.o aberration.o actan.o airmass.o anomaly.o ap_as.o atlas.o auxil.o bdl.o chap95.o chap95_data.o circum.o comet.o constel.o dbfmt.o deep.o deltat.o earthsat.o eq_ecl.o eq_gal.o formats.o helio.o jupmoon.o libration.o magdecl.o marsmoon.o misc.o mjd.o moon.o mooncolong.o moonnf.o nutation.o obliq.o parallactic.o parallax.o plans.o plmoon.o plshadow.o precess.o reduce.o refract.o rings.o riset.o riset_cir.o satmoon.o sdp4.o sgp4.o sphcart.o sun.o thetag.o twobody.o umoon.o utc_gst.o vsop87.o vsop87_data.o
+
+libxastro.a : $(OBJASTRO)
+	$(AR) $(ARFLAGS) $@ $?
+
+aa_hadec.o: aa_hadec.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ aa_hadec.c
+
+aberration.o: aberration.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ aberration.c
+
+actan.o: actan.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ actan.c
+
+airmass.o: airmass.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ airmass.c
+
+anomaly.o: anomaly.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ anomaly.c
+
+ap_as.o: ap_as.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ ap_as.c
+
+atlas.o: atlas.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ atlas.c
+
+auxil.o: auxil.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ auxil.c
+
+bdl.o: bdl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ bdl.c
+
+chap95.o: chap95.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ chap95.c
+
+chap95_data.o: chap95_data.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ chap95_data.c
+
+circum.o: circum.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ circum.c
+
+comet.o: comet.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ comet.c
+
+constel.o: constel.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ constel.c
+
+dbfmt.o: dbfmt.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ dbfmt.c
+
+deep.o: deep.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ deep.c
+
+deltat.o: deltat.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ deltat.c
+
+earthsat.o: earthsat.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ earthsat.c
+
+eq_ecl.o: eq_ecl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ eq_ecl.c
+
+eq_gal.o: eq_gal.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ eq_gal.c
+
+formats.o: formats.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ formats.c
+
+helio.o: helio.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ helio.c
+
+jupmoon.o: jupmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ jupmoon.c
+
+libration.o: libration.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ libration.c
+
+magdecl.o: magdecl.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ magdecl.c
+
+marsmoon.o: marsmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ marsmoon.c
+
+misc.o: misc.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ misc.c
+
+mjd.o: mjd.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ mjd.c
+
+moon.o: moon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ moon.c
+
+mooncolong.o: mooncolong.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ mooncolong.c
+
+moonnf.o: moonnf.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ moonnf.c
+
+nutation.o: nutation.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ nutation.c
+
+obliq.o: obliq.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ obliq.c
+
+parallactic.o: parallactic.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ parallactic.c
+
+parallax.o: parallax.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ parallax.c
+
+plans.o: plans.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plans.c
+
+plmoon.o: plmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plmoon.c
+
+plshadow.o: plshadow.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ plshadow.c
+
+precess.o: precess.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ precess.c
+
+reduce.o: reduce.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ reduce.c
+
+refract.o: refract.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ refract.c
+
+rings.o: rings.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ rings.c
+
+riset.o: riset.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ riset.c
+
+riset_cir.o: riset_cir.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ riset_cir.c
+
+satmoon.o: satmoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ satmoon.c
+
+sdp4.o: sdp4.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sdp4.c
+
+sgp4.o: sgp4.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sgp4.c
+
+sphcart.o: sphcart.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sphcart.c
+
+sun.o: sun.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ sun.c
+
+thetag.o: thetag.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ thetag.c
+
+twobody.o: twobody.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ twobody.c
+
+umoon.o: umoon.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ umoon.c
+
+utc_gst.o: utc_gst.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ utc_gst.c
+
+vsop87.o: vsop87.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ vsop87.c
+
+vsop87_data.o: vsop87_data.c astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h sattypes.h vector.h vsop87.h
+	$(CCOMPILE) -o $@ vsop87_data.c
+
+testxephem: testxephem.o
+	$(CLINK) -o $@ testxephem.o -L./ -lxastro -lc -lm
+
+testxephem.o: testxephem.c astro.h
+	$(CCOMPILE) -o $@ testxephem.c
+
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/sphcart.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/sphcart.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/sphcart.c	(revision 3445)
@@ -0,0 +1,43 @@
+#include <math.h>
+#include <stdio.h>
+
+#include "astro.h"
+
+/* transformation from spherical to cartesian coordinates */
+void
+sphcart (
+double l, double b, double r,		/* source: spherical coordinates */
+double *x, double *y, double *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 (
+double x, double y, double z,		/* source: rectangular coordinates */
+double *l, double *b, double *r)	/* result: spherical coordinates */
+{
+	double rho = x*x + y*y;
+
+	if (rho > 0) {	/* 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/sun.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/sun.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/sun.c	(revision 3445)
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "astro.h"
+#include "vsop87.h"
+
+/* given the modified JD, mj, 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 (double mj, double *lsn, double *rsn, double *bsn)
+{
+	static double last_mj = -3691, last_lsn, last_rsn, last_bsn;
+	double ret[6];
+
+	if (mj == last_mj) {
+	    *lsn = last_lsn;
+	    *rsn = last_rsn;
+	    if (bsn) *bsn = last_bsn;
+	    return;
+	}
+
+	vsop87(mj, 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_mj = mj;
+
+	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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/testxephem.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/testxephem.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/testxephem.c	(revision 3445)
@@ -0,0 +1,40 @@
+/* Pour faire des tests de Xephem Librairie */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+/* include "P_.h" */
+#include "astro.h"
+
+#define R2D (180./PI)
+
+int main(int narg,char** arg)
+{
+ int year=1989,month=7,day=21; /* UTC*/
+ double hour=12.5;
+ int npnum=8, pnum[8]={MERCURY,VENUS,MARS,JUPITER,SATURN,URANUS,NEPTUNE,PLUTO};
+ int i;
+ double mymjd,sunecl,sunecb,sundist,geodist,geoecl,geoecb,diamang,mag,msp,mdp;
+
+ cal_mjd(month,day+hour/24.,year,&mymjd);
+ printf("date %d/%d/%d %gh  -> mjd=%f\n",day,month,year,hour,mymjd);
+
+ /* Soleil */
+ sunpos(mymjd,&geoecl,&geodist,&geoecb);
+ printf("Sun: geo ecl=%g ecb=%g dist=%g\n",geoecl*R2D,geoecb*R2D,geodist);
+
+ /* Lune */
+ moon(mymjd,&geoecl,&geoecb,&geodist,&msp,&mdp);
+ printf("Moon: geo ecl=%g ecb=%g dist=%g\n",geoecl*R2D,geoecb*R2D,geodist);
+
+ /* Planete */
+ printf("--- Planets\n");
+ for(i=0;i<npnum;i++) {
+   plans(mymjd,pnum[i],&sunecl,&sunecb,&sundist,&geodist,&geoecl,&geoecb,&diamang,&mag);
+   printf("pnum=%d: sun ecl=%g ecb=%g dist=%g,",pnum[i],sunecl*R2D,sunecb*R2D,sundist);
+   printf(" geo ecl=%g ecb=%g dist=%g,",geoecl*R2D,geoecb*R2D,geodist);
+   printf(" diamang=%g\"/1UA mag=%g\n",diamang,mag);
+ }
+
+ exit(0);
+}
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/thetag.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/thetag.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/thetag.c	(revision 3445)
@@ -0,0 +1,90 @@
+#include <math.h>
+
+#include "deepconst.h"
+
+/* @(#) $Id: thetag.c,v 1.6 2006-11-22 13:53:31 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/twobody.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/twobody.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/twobody.c	(revision 3445)
@@ -0,0 +1,243 @@
+/*
+ *
+ * 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 */
+#undef  EPSILON
+#define EPSILON   3E-8
+#undef  INFINITY
+#define INFINITY  1E+10
+ 
+/* Math constants */
+#undef  PI
+#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 */
+ 
+ 
+/* return 0 if ok, else -1 */
+int 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 0;
+    }
+ 
+ 
+    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 );
+		return -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 0;  /* 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) );
+    }
+    return 0;
+ 
+} /* vrc */
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: twobody.c,v $ $Date: 2006-11-22 13:53:31 $ $Revision: 1.5 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/umoon.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/umoon.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/umoon.c	(revision 3445)
@@ -0,0 +1,270 @@
+/* uranus moon info */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include "astro.h"
+#include "bdl.h"
+
+static int use_bdl (double jd, char *dir, MoonData md[U_NMOONS]);
+static void moonradec (double usize, MoonData md[U_NMOONS]);
+static void moonSVis (Obj *sop, Obj *uop, MoonData md[U_NMOONS]);
+static void moonEVis (MoonData md[U_NMOONS]);
+static void moonPShad (Obj *sop, Obj *uop, MoonData md[U_NMOONS]);
+static void moonTrans (MoonData md[U_NMOONS]);
+
+/* moon table and a few other goodies and when it was last computed */
+static double mdmjd = -123456;
+static MoonData umd[U_NMOONS] = {
+    {"Uranus", NULL},
+    {"Ariel", "I"},
+    {"Umbriel", "II"},
+    {"Titania", "III"},
+    {"Oberon", "IV"},
+    {"Miranda", "V"},
+};
+static double sizemjd;	/* size at last mjd */
+
+/* These values are from the Explanatory Supplement.
+ * Precession degrades them gradually over time.
+ */
+#define POLE_RA         degrad(257.43)  /* RA of Uranus' north pole */
+#define POLE_DEC        degrad(-15.10)  /* Dec of Uranus' north pole */
+
+
+/* get uranus info in md[0], moon info in md[1..U_NMOONS-1].
+ * if !uop caller just wants md[] for names
+ * N.B. we assume sop and uop are updated.
+ */
+void
+uranus_data (
+double Mjd,		/* mjd */
+char dir[],             /* dir in which to look for helper files */
+Obj *sop,               /* Sun */
+Obj *uop,		/* uranus */
+double *sizep,		/* u angular diam, rads */
+double *polera, double *poledec,      /* pole location */
+MoonData md[U_NMOONS])	/* return info */
+{
+        double JD;
+
+	/* always copy back at least for name */
+	memcpy (md, umd, sizeof(umd));
+
+	/* pole */
+	if (polera) *polera = POLE_RA;
+	if (poledec) *poledec = POLE_DEC;
+
+	/* nothing else if repeat call or just want names */
+	if (Mjd == mdmjd || !uop) {
+	    if (uop) {
+		*sizep = sizemjd;
+	    }
+	    return;
+	}
+	JD = Mjd + MJD0;
+
+	/* planet in [0] */
+	md[0].ra = uop->s_ra;
+	md[0].dec = uop->s_dec;
+	md[0].mag = get_mag(uop);
+	md[0].x = 0;
+	md[0].y = 0;
+	md[0].z = 0;
+	md[0].evis = 1;
+	md[0].svis = 1;
+
+	/* size is straight from uop */
+	*sizep = degrad(uop->s_size/3600.0);
+
+        /* from Pasachoff/Menzel */
+
+	md[1].mag = 14.2;
+	md[2].mag = 14.8;
+	md[3].mag = 13.7;
+	md[4].mag = 14.0;
+	md[5].mag = 16.3;
+
+	/* get moon x,y,z from BDL if possible */
+	if (!dir || use_bdl (JD, dir, md) < 0) {
+	    int i;
+	    for (i = 1; i < U_NMOONS; i++)
+		md[i].x = md[i].y = md[i].z = 0.0;
+	    fprintf (stderr, "No uranus model available\n");
+	}
+
+	/* set visibilities */
+	moonSVis (sop, uop, md);
+	moonPShad (sop, uop, md);
+	moonEVis (md);
+	moonTrans (md);
+
+	/* fill in moon ra and dec */
+	moonradec (*sizep, md);
+
+	/* save */
+	mdmjd = Mjd;
+	sizemjd = *sizep;
+	memcpy (umd, md, sizeof(umd));
+}
+
+/* hunt for BDL file in dir[] and use if possible
+ * return 0 if ok, else -1
+ */
+static int
+use_bdl (
+double JD,		/* julian date */
+char dir[],		/* directory */
+MoonData md[U_NMOONS])	/* fill md[1..NM-1].x/y/z for each moon */
+{
+#define URAU    .0001597        /* Uranus radius, AU */
+	double x[U_NMOONS], y[U_NMOONS], z[U_NMOONS];
+	char buf[1024];
+	FILE *fp;
+	char *fn;
+	int i;
+
+	/* check ranges and appropriate data file */
+	if (JD < 2451179.50000)		/* Jan 1 1999 UTC */
+	    return (-1);
+	if (JD < 2455562.5)		/* Jan 1 2011 UTC */
+	    fn = "uranus.9910";
+	else if (JD < 2459215.5)	/* Jan 1 2021 UTC */
+	    fn = "uranus.1020";
+	else
+	    return (-1);
+
+	/* open */
+	(void) sprintf (buf, "%s/%s", dir, fn);
+	fp = fopen (buf, "r");
+	if (!fp) {
+	    fprintf (stderr, "%s: %s\n", fn, strerror(errno));
+	    return (-1);
+	}
+
+	/* use it */
+	if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) {
+	    fprintf (stderr, "%s: %s\n", fn, buf);
+	    fclose (fp);
+	    return (-1);
+	}
+	if (i != U_NMOONS-1) {
+	    fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, 
+								i, U_NMOONS-1);
+	    fclose (fp);
+	    return (-1);
+	}
+
+	/* copy into md[1..NM-1] with our scale and sign conventions */
+	for (i = 1; i < U_NMOONS; i++) {
+	    md[i].x =  x[i-1]/URAU;	/* we want u radii +E */
+	    md[i].y = -y[i-1]/URAU;	/* we want u radii +S */
+	    md[i].z = -z[i-1]/URAU;	/* we want u radii +front */
+	}
+
+	/* ok */
+	fclose (fp);
+	return (0);
+}
+
+/* given uranus loc in md[0].ra/dec and size, and location of each moon in 
+ * md[1..NM-1].x/y in ura radii, find ra/dec of each moon in md[1..NM-1].ra/dec.
+ */
+static void
+moonradec (
+double usize,		/* ura diameter, rads */
+MoonData md[U_NMOONS])	/* fill in RA and Dec */
+{
+	double urad = usize/2;
+	double ura = md[0].ra;
+	double udec = md[0].dec;
+	int i;
+
+	for (i = 1; i < U_NMOONS; i++) {
+	    double dra  = urad * md[i].x;
+	    double ddec = urad * md[i].y;
+	    md[i].ra  = ura + dra;
+	    md[i].dec = udec - ddec;
+	}
+}
+
+/* set svis according to whether moon is in sun light */
+static void
+moonSVis(
+Obj *sop,		/* SUN */
+Obj *uop,		/* uranus */
+MoonData md[U_NMOONS])
+{
+	double esd = sop->s_edist;
+	double eod = uop->s_edist;
+	double sod = uop->s_sdist;
+	double soa = degrad(uop->s_elong);
+	double esa = asin(esd*sin(soa)/sod);
+	double   h = sod*uop->s_hlat;
+	double nod = h*(1./eod - 1./sod);
+	double sca = cos(esa), ssa = sin(esa);
+	int i;
+
+	for (i = 1; i < U_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    double xp =  sca*mdp->x + ssa*mdp->z;
+	    double yp =  mdp->y;
+	    double zp = -ssa*mdp->x + sca*mdp->z;
+	    double ca = cos(nod), sa = sin(nod);
+	    double xpp = xp;
+	    double ypp = ca*yp - sa*zp;
+	    double zpp = sa*yp + ca*zp;
+	    int outside = xpp*xpp + ypp*ypp > 1.0;
+	    int infront = zpp > 0.0;
+	    mdp->svis = outside || infront;
+	}
+}
+
+/* set evis according to whether moon is geometrically visible from earth */
+static void
+moonEVis (MoonData md[U_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < U_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
+	    int infront = mdp->z > 0.0;
+	    mdp->evis = outside || infront;
+	}
+}
+
+/* set pshad and sx,sy shadow info */
+static void
+moonPShad(
+Obj *sop,             /* SUN */
+Obj *uop,             /* uranus */
+MoonData md[U_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < U_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->pshad = !plshadow (uop, sop, POLE_RA, POLE_DEC, mdp->x,
+					  mdp->y, mdp->z, &mdp->sx, &mdp->sy);
+	}
+}
+
+/* set whether moons are transiting */
+static void
+moonTrans (MoonData md[U_NMOONS])
+{
+	int i;
+
+	for (i = 1; i < U_NMOONS; i++) {
+	    MoonData *mdp = &md[i];
+	    mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
+	}
+}
+
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: umoon.c,v $ $Date: 2006-11-22 13:53:31 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/utc_gst.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/utc_gst.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/utc_gst.c	(revision 3445)
@@ -0,0 +1,95 @@
+#include "astro.h"
+
+static double gmst0 (double mj);
+
+/* given a modified julian date, mj, and a universally coordinated time, utc,
+ * return greenwich mean siderial time, *gst.
+ * N.B. mj must be at the beginning of the day.
+ */
+void
+utc_gst (double mj, double utc, double *gst)
+{
+	static double lastmj = -18981;
+	static double t0;
+
+	if (mj != lastmj) {
+	    t0 = gmst0(mj);
+	    lastmj = mj;
+	}
+	*gst = (1.0/SIDRATE)*utc + t0;
+	range (gst, 24.0);
+}
+
+/* given a modified julian date, mj, and a greenwich mean siderial time, gst,
+ * return universally coordinated time, *utc.
+ * N.B. mj must be at the beginning of the day.
+ */
+void
+gst_utc (double mj, double gst, double *utc)
+{
+	static double lastmj = -10000;
+	static double t0;
+
+	if (mj != lastmj) {
+	    t0 = gmst0 (mj);
+	    lastmj = mj;
+	}
+	*utc = gst - t0;
+	range (utc, 24.0);
+	*utc *= SIDRATE;
+}
+
+/* gmst0() - return Greenwich Mean Sidereal Time at 0h UT; stern
+ */
+static double
+gmst0 (
+double mj)	/* date at 0h UT in julian days since MJD0 */
+{
+	double T, x;
+
+	T = ((int)(mj - 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 (mj)
+double mj;	/* julian days since 1900 jan 0.5 */
+{
+	double dmj;
+	int m, y;
+	double d;
+	double t, t0;
+
+	mjd_cal (mj, &m, &d, &y);
+	cal_mjd (1, 0., y, &dmj);
+	t = dmj/36525;
+	t0 = 6.57098e-2 * (mj - dmj) - 
+	     (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 mj, gst;
+	while (scanf("%lf", &mj) == 1) {
+		mj -= MJD0;
+		gst = tnaught(mj);
+		printf("%17.9f %10.7f %10.7f\n", mj + MJD0, gst, gmst0(mj));
+	}
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: utc_gst.c,v $ $Date: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/vector.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/vector.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/vector.h	(revision 3445)
@@ -0,0 +1,19 @@
+#ifndef __SATVECTOR_H
+#define __SATVECTOR_H
+
+/* $Id: vector.h,v 1.6 2006-11-22 13:53:31 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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.c	(revision 3445)
@@ -0,0 +1,209 @@
+/* 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 "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 :
+ *
+ *    mj       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 (double mj, 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] = (mj - 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: 2006-11-22 13:53:31 $ $Revision: 1.7 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.h
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87.h	(revision 3445)
@@ -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 (double mj, int obj, double prec, double *ret);
+
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: vsop87.h,v $ $Date: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87_data.c
===================================================================
--- /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87_data.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaExt/XephemAstroLib/vsop87_data.c	(revision 3445)
@@ -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: 2006-11-22 13:53:31 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Nov2007/SophyaLib/BaseTools/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/Makefile	(revision 3445)
@@ -0,0 +1,91 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libBaseTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dvlist.o $(SOPHYAOBJP)fiondblock.o $(SOPHYAOBJP)mutyv.o $(SOPHYAOBJP)ndatablock.o $(SOPHYAOBJP)pexceptions.o $(SOPHYAOBJP)ppersist.o $(SOPHYAOBJP)ppfbinstream.o $(SOPHYAOBJP)ppftpointerio.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)srandgen.o
+	rm -f $(SOPHYALIBP)libBaseTools.a
+ 
+$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dvlist.o $(SOPHYAOBJP)fiondblock.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)mutyv.o $(SOPHYAOBJP)ndatablock.o $(SOPHYAOBJP)pexceptions.o $(SOPHYAOBJP)ppersist.o $(SOPHYAOBJP)ppfbinstream.o $(SOPHYAOBJP)ppftpointerio.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)srandgen.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)datatype.o: datatype.cc datatype.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatype.cc
+ 
+$(SOPHYAOBJP)dvlist.o: dvlist.cc $(SOPHYAINCP)machdefs.h \
+  dvlist.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h mutyv.h timestamp.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dvlist.cc
+ 
+$(SOPHYAOBJP)fiondblock.o: fiondblock.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  datatype.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiondblock.cc
+ 
+$(SOPHYAOBJP)mutyv.o: mutyv.cc sopnamsp.h mutyv.h \
+  $(SOPHYAINCP)machdefs.h timestamp.h objfio.h \
+  anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mutyv.cc
+ 
+$(SOPHYAOBJP)ndatablock.o: ndatablock.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  ndatablock.h anydataobj.h thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ndatablock.cc
+ 
+$(SOPHYAOBJP)pexceptions.o: pexceptions.cc sopnamsp.h pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pexceptions.cc
+ 
+$(SOPHYAOBJP)ppersist.o: ppersist.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  ppersist.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppersist.cc
+ 
+$(SOPHYAOBJP)ppfbinstream.o: ppfbinstream.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ppfbinstream.h \
+  rawstream.h pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppfbinstream.cc
+ 
+$(SOPHYAOBJP)ppftpointerio.o: ppftpointerio.cc \
+  $(SOPHYAINCP)machdefs.h ppftpointerio.h \
+  ppersist.h pexceptions.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppftpointerio.cc
+ 
+$(SOPHYAOBJP)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rawstream.cc
+ 
+$(SOPHYAOBJP)sophyainit.o: sophyainit.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h sophyainit.h \
+  pexceptions.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h fiondblock.h ndatablock.h anydataobj.h dvlist.h objfio.h \
+  mutyv.h timestamp.h stsrand.h fiosegdb.h segdatablock.h thsafeop.h \
+  ppftpointerio.h ppfwrapstlv.h sversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sophyainit.cc
+ 
+$(SOPHYAOBJP)stsrand.o: stsrand.cc stsrand.h \
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h \
+  ppersist.h pexceptions.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h thsafeop.h fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  stsrand.cc
+ 
+$(SOPHYAOBJP)timestamp.o: timestamp.cc $(SOPHYAINCP)machdefs.h \
+  timestamp.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timestamp.cc
+ 
+$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h \
+  bithelp.h gnumd5.h
+	$(CCOMPILE) -o $@  gnumd5.c
+ 
+$(SOPHYAOBJP)srandgen.o: srandgen.c $(SOPHYAINCP)machdefs.h \
+  srandgen.h smathconst.h
+	$(CCOMPILE) -o $@  srandgen.c
+ 
Index: /tags/V_Nov2007/SophyaLib/BaseTools/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/Makefile.mgr	(revision 3445)
@@ -0,0 +1,52 @@
+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)ppfbinstream.o $(OBJ)ppftpointerio.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)timestamp.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)ppfbinstream.o $(OBJ)ppftpointerio.o $(OBJ)rawstream.o $(OBJ)sophyainit.o $(OBJ)srandgen.o $(OBJ)timestamp.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)datatype.o: datatype.cc sopnamsp.h datatype.h \
+  $(INC)machdefs.h
+$(OBJ)dvlist.o: dvlist.cc sopnamsp.h $(INC)machdefs.h \
+  dvlist.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h mutyv.h \
+  $(INC)strutil.h
+$(OBJ)fiondblock.o: fiondblock.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h datatype.h \
+  fiondblock.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h anydataobj.h
+$(OBJ)mutyv.o: mutyv.cc sopnamsp.h mutyv.h \
+  $(INC)machdefs.h
+$(OBJ)ndatablock.o: ndatablock.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h ndatablock.h \
+  anydataobj.h
+$(OBJ)pexceptions.o: pexceptions.cc sopnamsp.h pexceptions.h \
+  $(INC)machdefs.h
+$(OBJ)ppersist.o: ppersist.cc sopnamsp.h \
+  $(INC)machdefs.h pexceptions.h ppersist.h \
+  gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h anydataobj.h
+$(OBJ)ppfbinstream.o: ppfbinstream.cc sopnamsp.h \
+  $(INC)machdefs.h ppfbinstream.h rawstream.h \
+  pexceptions.h
+$(OBJ)ppftpointerio.o: ppftpointerio.cc \
+  $(INC)machdefs.h sopnamsp.h ppftpointerio.h \
+  ppersist.h pexceptions.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h
+$(OBJ)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
+  $(INC)machdefs.h pexceptions.h
+$(OBJ)sophyainit.o: sophyainit.cc sopnamsp.h \
+  $(INC)machdefs.h sophyainit.h pexceptions.h \
+  ppersist.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  fiondblock.h ndatablock.h anydataobj.h dvlist.h objfio.h mutyv.h \
+  fiosegdb.h segdatablock.h ppftpointerio.h ppfwrapstlv.h sversion.h
+$(OBJ)timestamp.o: timestamp.cc sopnamsp.h \
+  $(INC)machdefs.h timestamp.h pexceptions.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_Nov2007/SophyaLib/BaseTools/anydataobj.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/anydataobj.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/anydataobj.h	(revision 3445)
@@ -0,0 +1,25 @@
+// 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() { }
+
+//! Return a process wide unique identifier 
+  static uint_8 getUniqueId();
+};
+
+}
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/basetools.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/basetools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/basetools.h	(revision 3445)
@@ -0,0 +1,26 @@
+#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 "ppfnametag.h"
+#include "ndatablock.h"
+#include "fiondblock.h"
+#include "anydataobj.h"
+#include "dvlist.h"
+#include "perrors.h"
+#include "srandgen.h"
+#include "stsrand.h"
+#include "datatype.h"
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/bithelp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/bithelp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/bithelp.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/complexios.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/complexios.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/complexios.h	(revision 3445)
@@ -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>
+
+#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_Nov2007/SophyaLib/BaseTools/datatype.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/datatype.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/datatype.cc	(revision 3445)
@@ -0,0 +1,203 @@
+// 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 <typeinfo>
+
+#include <complex>
+
+namespace SOPHYA {
+
+template <class T>
+DataTypeInfo<T>::DataTypeInfo()
+{
+}
+#if defined(__SGICC__)
+template <class T>
+string DataTypeInfo<T>::getTypeName()
+{
+  if (typeid(T) == typeid(uint_1)) return("uint_1");
+  else if (typeid(T) == typeid(uint_2)) return("uint_2");
+  else if (typeid(T) == typeid(int_2)) return("int_2");
+  else if (typeid(T) == typeid(int_4)) return("int_4");
+  else if (typeid(T) == typeid(int_8)) return("int_8");
+  else if (typeid(T) == typeid(uint_4)) return("uint_4");
+  else if (typeid(T) == typeid(uint_8)) return("uint_8");
+  else if (typeid(T) == typeid(r_4)) return("r_4");
+  else if (typeid(T) == typeid(r_8)) return("r_8");
+  else if (typeid(T) == typeid(complex<r_4>)) return(" complex<r_4> ");
+  else if (typeid(T) == typeid(complex<r_8>)) return(" complex<r_8> ");
+  else return("???unknowntype???");
+}
+template <class T>
+int DataTypeInfo<T>::getTypeId()
+{
+  if (typeid(T) == typeid(uint_1)) return(1);
+  else if (typeid(T) == typeid(int_1)) return(2);
+  else if (typeid(T) == typeid(uint_2)) return(3);
+  else if (typeid(T) == typeid(int_2)) return(4);
+  else if (typeid(T) == typeid(uint_4)) return(5);
+  else if (typeid(T) == typeid(int_4)) return(6);
+  else if (typeid(T) == typeid(uint_8)) return(7);
+  else if (typeid(T) == typeid(int_8)) return(8);
+  else if (typeid(T) == typeid(r_4)) return(9);
+  else if (typeid(T) == typeid(r_8)) return(10);
+  else if (typeid(T) == typeid(complex<r_4>)) return(11);
+  else if (typeid(T) == typeid(complex<r_8>)) return(12);
+  else return(0);
+}
+#else
+//! Return the type name of T, as a string, (Example: T=uint_8 --> "uint_8")
+template <class T>
+string DataTypeInfo<T>::getTypeName() { return("???unknowntype???"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<uint_1>::getTypeName() { return("uint_1"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<int_1>::getTypeName() { return("int_1"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<uint_2>::getTypeName() { return("uint_2"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<int_2>::getTypeName() { return("int_2"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<uint_4>::getTypeName() { return("uint_4"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<int_4>::getTypeName() { return("int_4"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<uint_8>::getTypeName() { return("uint_8"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<int_8>::getTypeName() { return("int_8"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<r_4>::getTypeName() { return("r_4"); }
+DECL_TEMP_SPEC
+string DataTypeInfo<r_8>::getTypeName() { return("r_8"); }
+DECL_TEMP_SPEC
+string DataTypeInfo< complex<r_4> >::getTypeName() { return(" complex<r_4> "); }
+DECL_TEMP_SPEC
+string DataTypeInfo< complex<r_8> >::getTypeName() { return(" complex<r_8> "); }
+
+/*! 
+  \ brief Return an identifier associated to T 
+  uint_1 -> 1  , int_1 -> 2
+  uint_2 -> 3  , int_2 -> 4
+  uint_4 -> 5  , int_4 -> 6
+  uint_8 -> 7  , int_8 -> 8
+  r_4    -> 9  , r_8   -> 10
+  complex<r_4> -> 11 , complex<r_8> -> 12
+*/
+template <class T>
+int DataTypeInfo<T>::getTypeId() { return(0); }
+DECL_TEMP_SPEC
+int DataTypeInfo<uint_1>::getTypeId() { return(1); }
+DECL_TEMP_SPEC
+int DataTypeInfo<int_1>::getTypeId() { return(2); }
+DECL_TEMP_SPEC
+int DataTypeInfo<uint_2>::getTypeId() { return(3); }
+DECL_TEMP_SPEC
+int DataTypeInfo<int_2>::getTypeId() { return(4); }
+DECL_TEMP_SPEC
+int DataTypeInfo<uint_4>::getTypeId() { return(5); }
+DECL_TEMP_SPEC
+int DataTypeInfo<int_4>::getTypeId() { return(6); }
+DECL_TEMP_SPEC
+int DataTypeInfo<uint_8>::getTypeId() { return(7); }
+DECL_TEMP_SPEC
+int DataTypeInfo<int_8>::getTypeId() { return(8); }
+DECL_TEMP_SPEC
+int DataTypeInfo<r_4>::getTypeId() { return(9); }
+DECL_TEMP_SPEC
+int DataTypeInfo<r_8>::getTypeId() { return(10); }
+DECL_TEMP_SPEC
+int DataTypeInfo< complex<r_4> >::getTypeId() { return(11); }
+DECL_TEMP_SPEC
+int DataTypeInfo< complex<r_8> >::getTypeId() { return(12); }
+#endif
+
+
+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<int_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<int_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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/BaseTools/datatype.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/datatype.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/datatype.h	(revision 3445)
@@ -0,0 +1,28 @@
+// 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 {
+
+//! class returning type name for usual numrical types (int_2,int_4,r_4,r_8 ...)
+template <class T>
+class DataTypeInfo {
+public:
+  static string getTypeName();
+  static int    getTypeId();
+  DataTypeInfo();
+};
+
+string DecodeGCCTypeName(string gcctype);
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.cc	(revision 3445)
@@ -0,0 +1,637 @@
+//  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"
+
+namespace SOPHYA {
+
+//++
+// 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 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) or time/date (TimeStamp). 
+   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>
+   \sa SOPHYA::MuTyV
+
+   \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("ToDay") = TimeStamp();    
+   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-- */
+/*! Appends or sets the TimeStamp value \b val in the list with name \b key */
+void        DVList::SetT(string const& key, TimeStamp 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)  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];
+TimeStamp ts; 
+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;
+    case MuTyV::MTVTimeStamp :
+      ts.Set((*it).second.elval.GetRealPart());
+      sprintf(buff, "%s = %s (TimeStamp) %s\n", (*it).first.substr(0,64).c_str(), 
+		ts.ToString().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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
+{
+if (dobj == NULL)
+  throw NullPtrError("ObjFileIO<DVList>::WriteSelf() dobj=NULL");
+
+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;
+    case MuTyV::MTVTimeStamp : 
+      sprintf(buf,"T %s %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetRealPart() );
+      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-Variable-List------"; s.PutStr(sfw);
+}
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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';
+if (dobj == NULL) dobj = new DVList; 
+else 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;
+    case 'T' :
+      dv = atof(buf+j+1);
+      key = buf+2;
+      dobj->SetT(key, TimeStamp(dv));
+      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
+
+} // FIN namespace SOPHYA 
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/dvlist.h	(revision 3445)
@@ -0,0 +1,118 @@
+// 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>
+
+#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              SetT(string const& key, TimeStamp 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;
+
+//!  \cond  
+// 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; 
+//!  \endcond
+/*! Returns an iterator pointing on the first variable in the list */
+  inline ValList::const_iterator Begin() const { return(mvlist.begin()); } 
+/*! Returns the iterator end value */
+  inline ValList::const_iterator End() const { 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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<DVList>
+
+} // namespace SOPHYA
+
+#endif /* DVLIST_H__SEEN */
+
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/fiondblock.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/fiondblock.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/fiondblock.cc	(revision 3445)
@@ -0,0 +1,212 @@
+// Classe pour la gestion de persistance pour NDataBlock<T>
+//                         C.Magneville          04/99-03/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <complex>
+#include "pexceptions.h"
+#include "datatype.h"
+#include "fiondblock.h"
+#include <typeinfo>
+
+////////////////////////////////////////////////////////////////
+// -------------------------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// -------------------------------------------------------------------------
+/*!
+   \class SOPHYA::FIO_NDataBlock
+   \ingroup BaseTools
+   Handler for PPF persistence of NDataBlock<T> classes. 
+*/
+
+/*
+template <class T>
+void ObjFileIO< NDataBlock<T> >::ReadSelf(PInPersist& is)
+template <class T>
+void ObjFileIO< NDataBlock<T> >::WriteSelf(POutPersist& os)
+*/
+
+
+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);
+}
+
+//---------------------------------------------------------------------------
+// Pour compatibilite de lecture avec PPF V2 
+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); }
+//---------------------------------------------------------------------------
+
+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) { 
+  if (itab[1] > 0) dobj = new NDataBlock<T>(itab[1]);
+  else dobj = new NDataBlock<T>(); 
+}
+else { 
+  if (itab[1] != dobj->Size()) { 
+    if (itab[1] > 0)  dobj->ReSize(itab[1]);
+    else dobj->Dealloc(); 
+  }
+}
+if (dobj->Size() < 1)  return;  // Pas de donnees a lire ...
+// On lit le tableau de nombres
+if (is.Version() <= 2)   // lecture ancienne version PPF
+  PIOSReadArray(is, dobj->Data(), dobj->Size()); 
+else is.Get(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 
+if (dobj->Size() > 0)   // On ecrit les donnees, s'il y en a ... (sz>0)
+  os.Put(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)
+namespace SOPHYA {
+// 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_Nov2007/SophyaLib/BaseTools/fiondblock.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/fiondblock.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/fiondblock.h	(revision 3445)
@@ -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>
+
+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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/fiosegdb.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/fiosegdb.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/fiosegdb.h	(revision 3445)
@@ -0,0 +1,155 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour la gestion de persistance PPF des SegDataBlock 
+//                         R. Ansari - Avril 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef FIOSEGDATABLOCK_H
+#define FIOSEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "ppersist.h"
+#include "segdatablock.h"
+#include "ppftpointerio.h"
+#include <typeinfo> 
+
+/*!
+   \class SOPHYA::FIO_SegDataBlock
+   \ingroup BaseTools
+   Class implementing PPF persistence (PPersist handler) for segmented data structures
+   (class SegDataBlock).
+   \sa PPersist
+*/
+
+namespace SOPHYA {
+
+   
+template <class T>
+class FIO_SegDataBlock : public  PPersist  {
+public:
+  FIO_SegDataBlock()
+  {
+    dobj = NULL ;
+    ownobj=true;    
+  }
+
+  //   FIO_SegDataBlock(string const & filename);
+  FIO_SegDataBlock(SegDataBlock<T> & obj)
+  {
+    dobj = &obj;
+    ownobj = false;
+  }
+
+  FIO_SegDataBlock(SegDataBlock<T> * obj)
+  {
+    if (obj == NULL)  
+      throw ParmError("FIO_SegDataBlock<T>::FIO_SegDataBlock(* obj) obj=NULL (ppfwrapstlv.h)");
+    dobj = obj;
+    ownobj = false;
+  }
+  virtual ~FIO_SegDataBlock()
+  {
+    if (ownobj && dobj)    delete dobj;
+  }
+  virtual AnyDataObj* DataObj() { return dobj; }
+  virtual void        SetDataObj(AnyDataObj & o)
+  {
+    SegDataBlock<T> * po = dynamic_cast< SegDataBlock<T> * >(&o);
+    if (po == NULL) {
+      char buff[160];
+      sprintf(buff,"FIO_SegDataBlock<%s>::SetDataObj(%s) - Object type  error ! ",
+	      typeid(T).name(), typeid(o).name());
+      throw TypeMismatchExc(PExcLongMessage(buff));    
+    }
+    if (ownobj && dobj) delete dobj;
+    dobj = po; ownobj = false;
+  } 
+
+  inline operator SegDataBlock<T>()  { return(*dobj); }
+
+  // Les methodes suivantes implementent les fonctionalites necessaires
+  // au  partage de reference ds les fichiers PPF 
+  uint_8 getMemOId() const
+  {
+    return ( (dobj) ? dobj->DRefId() : 0 );
+  }
+  void ShareDataReference(PPersist & pp)
+  {
+    FIO_SegDataBlock<T> *ppo = dynamic_cast< FIO_SegDataBlock<T> * >(&pp);
+    if (ppo == NULL) throw TypeMismatchExc("FIO_SegDataBlock<T>::ShareDataReference() - Type Mismatch Error");
+    if (ppo->dobj) {
+      if (dobj) dobj->Share(*(ppo->dobj));
+      else { dobj = new SegDataBlock<T>(*(ppo->dobj)); ownobj = true; } 
+    }
+  }
+  PPersist* CloneSharedReference()
+  {
+    FIO_SegDataBlock<T> * ppo = new FIO_SegDataBlock<T>;
+    ppo->dobj = new SegDataBlock<T>(*(dobj));
+    ppo->ownobj = true;
+    return(ppo); 
+  }
+
+protected :
+  virtual void       ReadSelf(PInPersist& is)
+  {
+    // On lit les 4 premiers uint_8
+    // 0: Numero de version   , 3 : reserve 
+    // 1: SegmentSize  2: NbSegments  
+    uint_8 itab[4];
+    is.Get(itab, 4);
+    if (dobj == NULL) {
+      dobj = new SegDataBlock<T>(itab[1], itab[2]);
+      ownobj = true;
+    }
+    else dobj->SetSize(itab[1], itab[2]);
+    // On lit les donnees par paquet ...
+    for(uint_8 k=0; k<itab[2]; k++) 
+      PPF_TPointer_IO<T>::Read(is, dobj->GetSegment(k), itab[1]);
+    // On lit la table des tags de positionnement ...
+    vector<int_8> postags;
+    is.GetPosTagTable(postags);
+  }         
+  virtual void       WriteSelf(POutPersist& os) const
+  {
+    if (dobj == NULL) 
+      throw ParmError("FIO_SegDataBlock<T>::WriteSelf() dobj=NULL (fiosegdb.h)");
+    // On ecrit les 4  uint_8
+    // 0: Numero de version   , 3 : reserve 
+    // 1: SegmentSize  2: NbSegments  
+    uint_8 itab[4];
+    itab[0] = 1;
+    itab[1] = dobj->SegmentSize();
+    itab[2] = dobj->NbSegments();
+    itab[3] = 0;
+    os.Put(itab, 4);
+    // On ecrit les donnees par paquets ...
+    vector<int_8> postags;
+    int_8 tag;
+    for(uint_8 k=0; k<itab[2]; k++) {
+      tag = os.WritePositionTag();
+      PPF_TPointer_IO<T>::Write(os, dobj->GetSegment(k), itab[1]);
+      postags.push_back(tag);
+    }
+    // On ecrit la table des tags de positionnement 
+    // au cas ou on voudrait l'utiliser en mode swap
+    os.PutPosTagTable(postags);
+  }
+
+  // Variables membres 
+  SegDataBlock<T> * dobj;  // Le vecteur de la STL 
+  bool ownobj;  // true -> objet cree par le wrapper 
+};
+
+/*! Writes the segmented data structure \b obj in the POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, SegDataBlock<T> & obj)
+{ FIO_SegDataBlock<T> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads in and initializes the segmented data structure \b obj  
+  from the PInPersist stream \b is */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, SegDataBlock<T> & obj)
+{ FIO_SegDataBlock<T> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/gnumd5.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/gnumd5.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/gnumd5.c	(revision 3445)
@@ -0,0 +1,421 @@
+/* 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 IS_BIG_ENDIAN==1
+#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
+#if defined(Darwin)
+#define X(a) do { *p++ = (*hd).a	  ; *p++ = (*hd).a >> 8;      \
+		      *p++ = (*hd).a >> 16; *p++ = (*hd).a >> 24; } while(0)
+#else 
+#define X(a) do { *p++ = hd->##a	  ; *p++ = hd->##a >> 8;      \
+		      *p++ = hd->##a >> 16; *p++ = hd->##a >> 24; } while(0)
+#endif
+#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.6 $)";
+
+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_Nov2007/SophyaLib/BaseTools/gnumd5.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/gnumd5.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/gnumd5.h	(revision 3445)
@@ -0,0 +1,36 @@
+#ifndef GNUMD5_H
+#define GNUMD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! \cond */
+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;
+/*! \endcond */
+
+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_Nov2007/SophyaLib/BaseTools/hashtable.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/hashtable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/hashtable.h	(revision 3445)
@@ -0,0 +1,196 @@
+// 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 {
+
+//! \cond
+template <class T, class K>
+struct HashtableEntry {
+  uint_4         hash;
+  K              key;
+  T              value;
+  HashtableEntry<T,K> *next;
+};
+//! \endcond
+
+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_Nov2007/SophyaLib/BaseTools/history_eros
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/history_eros	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/history_eros	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/machdefs_ac.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/machdefs_ac.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/machdefs_ac.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/machdefs_mkmf.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/machdefs_mkmf.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/machdefs_mkmf.h	(revision 3445)
@@ -0,0 +1,290 @@
+#ifndef MACHDEFS_SEEN
+#define MACHDEFS_SEEN
+
+/* -------------- List of flags (and description) ------------------- 
+  - SO_ARCH64 : select 64 bits architecture (default 32 bits)
+  - SO_NOFPIC  : disable fPIC flag (Position Independent Code) default fPIC enabled 
+  - SO_SASIZET64 : select 64 bits size for array indices (default 32 bits)
+  - SO_BOUNDCHECKING : activate bound checking (in accessing array elements)
+  - SOPHYA_DEBUG : debug flag ( --> if set, SO_BOUNDCHECKING is also set)
+  ------------------------------------------------------------------  */
+
+#ifdef SOPHYA_DEBUG
+#define SO_BOUNDCHECKING
+#endif
+
+/***********************************************************************/
+/* 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
+
+#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__
+#ifdef __POWERPC__
+#define MACH_POWERPC
+#else
+#define MACH_INTEL
+#endif
+#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
+#define MACH_AMD
+/* $CHECK$ (Reza Avril 2007):  Il faut affiner ce test pour 
+   determiner correctement le type de  processeur        */
+#endif
+#define OS_LINUX
+#endif
+
+/***********************************************************************/
+/* Hardware/OS dependent stuff                                         */
+/***********************************************************************/
+
+/* --------------------------------------------------------------- */
+/* 1/     typedefs for different size integers and floats          */
+/* --------------------------------------------------------------- */
+
+/* --- Avr2007: The following typdefs should be OK for most system */
+/* and compilers:  OSF, Linux, AIX, SGI, MacOSX, Sun, HP           */
+
+typedef signed char int_1;
+typedef unsigned char uint_1;
+typedef short int_2;
+typedef unsigned short uint_2;
+typedef int int_4;
+typedef unsigned int uint_4;
+typedef long long int_8;
+typedef unsigned long long uint_8;
+typedef float r_4;
+typedef double r_8;
+
+/* --------------------------------------------------------------- */
+/* 2/     Endiannes (/ byteswap for different processors)          */
+/* --------------------------------------------------------------- */
+/*  
+    ==> POWERPC, IBMRS, HP_UX, IRIX64, SunSPARC (?) : 
+           BigEndian    ( SWAP=SWAPDEFAUT=0)
+    ==> ALPHA, INTEL, AMD :
+           LittleEndian ( SWAP=SWAPDEFAUT=1)        
+*/                                      
+
+#if defined(MACH_ALPHA) || defined(MACH_INTEL) || defined(MACH_AMD) 
+#define IS_BIG_ENDIAN 0
+#else 
+#define IS_BIG_ENDIAN 1
+#endif
+
+/* ---- La taille des index des tableaux ---- */
+#ifdef SO_SASIZET64 
+typedef int_8 sa_size_t ;
+#else
+typedef int_4 sa_size_t ;
+#endif
+
+
+/***********************************************************************/
+/* Find Compiler                                                       */
+/***********************************************************************/
+
+/*    __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                          */
+/*    __INTEL_COMPILER :   : INTEL compiler                            */
+/*    __IBMCPP__   : AIX (IBM) xlC c++ compiler                        */
+
+/***********************************************************************/
+/* Compiler-specific stuff                                             */
+/***********************************************************************/
+  
+/*   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                       */
+/*   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 */
+/*   DECL_TEMP_SPEC        : Template specialization declaration           */
+/*   TSNMLUPG4             : Two stage name look-up scheme (g++>3.4)       */
+
+
+/* (STREAMPOS_IS_CLASS non-active: ca compile sans sur gcc3.2 et cxx)
+   rz+cmv 11/02/03 */
+
+/* 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
+
+
+#ifndef DECL_TEMP_SPEC
+#define DECL_TEMP_SPEC
+#endif
+
+/* Most compilers dot not implement two level name lookup for templates 
+   introduced by gcc >= 3.4 
+*/
+#ifdef TSNMLUPG4
+#undef TSNMLUPG4
+#endif
+
+/* now the specific things */
+
+#ifdef __GNUC__
+#define GCC_VERSION (__GNUC__ * 1000 \
+                               + __GNUC_MINOR__ * 100 \
+                               + __GNUC_PATCHLEVEL__)
+#define ANSI_TEMPLATES
+/*
+if (__GNUC__ >= 3) 
+define STREAMPOS_IS_CLASS
+endif
+*/
+#define GNU_TEMPLATES
+#define HAS_STR_NPOS
+#define HAS_IOS_BIN
+#define HAS_IOS_NOCREATE
+#if ( GCC_VERSION >= 3000 ) 
+#undef  DECL_TEMP_SPEC
+#define DECL_TEMP_SPEC template <>
+#endif
+#if ( GCC_VERSION >= 3400 )
+/* Two level name look-up scheme for templates introduced from gcc 3.4 */
+#define TSNMLUPG4
+#endif
+
+#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
+#undef  DECL_TEMP_SPEC
+#define DECL_TEMP_SPEC template <>
+#endif
+
+#if defined(__IBMCPP__)
+/* IBM xlC compiler support Added : dec 2005 */
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#undef  DECL_TEMP_SPEC
+#define DECL_TEMP_SPEC template <>
+#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 HAS_IOS_BIN
+#define IOS_BIN ios::binary
+#else
+#define IOS_BIN 0
+#endif
+
+
+#ifdef OS_MACOSX
+#define NO_VALUES_H
+#include "osx_values.h"
+#endif
+
+
+#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;                 */
+/* Please use instead: sopnamsp.h          */
+/*******************************************/
+#endif
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/mutyv.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/mutyv.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/mutyv.cc	(revision 3445)
@@ -0,0 +1,212 @@
+// Classe MuTyV : Variable multi-type numerique
+//                  R. Ansari  1997-2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+
+#include "sopnamsp.h"
+#include "mutyv.h"
+#include <stdio.h>
+
+#include <iostream>
+#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), float (\b r_8), complex and 
+   date/time (TimeStamp). Date/time values are kept internally 
+   as double precision values and are thus less precise than 
+   TimeStamp objects. 
+   It provides also easy conversion methods between these types. 
+
+   \sa SOPHYA::TimeStamp
+
+   \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 !"
+   TimeStamp ts;      // Current date/time
+   MuTyV mvt = ts;
+   s = mvt;           // s contains the current date in string format
+   \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(TimeStamp const& ts)
+{
+  typ = MTVTimeStamp;
+  dv = ts.ToDays();
+  dv_im = 0.;
+  iv = (int_8)dv;
+  strv = NULL;
+}
+
+/* --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-- */
+const char * MuTyV::operator= (const 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 const & MuTyV::operator= (string const& 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-- */
+TimeStamp const & MuTyV::operator= (TimeStamp const& ts)
+{
+  typ = MTVTimeStamp;
+  dv = ts.ToDays();
+  dv_im = 0.;
+  iv = (int_8)dv;
+  return(ts);
+}
+
+
+/* --Methode-- */
+MuTyV::operator string() const 
+{
+  if (typ == MTVString)  return(*strv);
+  else if (typ == MTVTimeStamp) { return TimeStamp(dv).ToString(); }
+  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));
+  }
+}
+
+/* --Methode-- */
+string & MuTyV::Convert(string & x) const 
+{
+  if (typ == MTVString)  x = *strv;
+  else if (typ == MTVTimeStamp) { x = TimeStamp(dv).ToString(); }
+  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';
+    x = buff;
+  }
+  return x;
+}
+
+/* --Methode-- */
+MuTyV::operator TimeStamp() const 
+{
+  return TimeStamp(dv);
+}
+
+/* --Methode-- */
+TimeStamp& MuTyV::Convert(TimeStamp& x) const 
+{
+  x = TimeStamp(dv);
+  return x;
+}
+
+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_Nov2007/SophyaLib/BaseTools/mutyv.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/mutyv.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/mutyv.h	(revision 3445)
@@ -0,0 +1,121 @@
+// 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 "timestamp.h"
+
+#include <iostream>
+
+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,
+    MTVTimeStamp
+  };
+
+  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(TimeStamp const& ts); 
+
+         ~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_4 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_2 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); }
+         const char*  operator= (const char* s);
+         string const& operator= (string const & s);
+         TimeStamp const& operator= (TimeStamp const & 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_2()  const { return((int_2)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 ; 
+         operator TimeStamp() const ; 
+
+  inline uint_2 Convert(uint_2& x) const { x = (uint_2)iv; return x; }
+  inline uint_4 Convert(uint_4& x) const { x = (uint_4)iv; return x; }
+  inline uint_8 Convert(uint_8& x) const { x = (uint_8)iv; return x; }
+  inline int_4 Convert(int_2& x) const { x = (int_2)iv; return x; }
+  inline int_4 Convert(int_4& x) const { x = (int_4)iv; return x; }
+  inline int_8 Convert(int_8& x) const { x = iv; return x; }
+  inline r_4 Convert(r_4& x) const { x = (r_4)dv; return x; }
+  inline r_8 Convert(r_8& x) const { x = dv; return x; }
+  inline complex<r_4> Convert(complex<r_4> & x) const 
+    { x = complex< r_4 > ((r_4)dv, (r_4)dv_im); return x; }
+  inline complex<r_8> Convert(complex<r_8> & x) const 
+    { x = complex< r_8 > (dv, dv_im); return x; }
+  
+  string&  Convert(string& x) const ; 
+  TimeStamp& Convert(TimeStamp& x) 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_Nov2007/SophyaLib/BaseTools/ndatablock.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ndatablock.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ndatablock.cc	(revision 3445)
@@ -0,0 +1,838 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <complex>
+#include "pexceptions.h"
+#include "ndatablock.h"
+#include "thsafeop.h"  //  for ThreadSafe operations (Ref.Count/Share) 
+
+/* ---- Pour renvoyer un identificateur unique ---- */
+static uint_8 _ndrefid_ = 0; // Identificateur de NDREF cree 
+uint_8 AnyDataObj::getUniqueId()
+{
+  _ndrefid_++;
+  return ( _ndrefid_ );
+}
+
+/*!
+  \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;
+template <class T> ThSafeOp* NDataBlock<T>::gThsop        = NULL;
+
+//! 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. if \b zero=true, filled with zeros
+template <class T>
+NDataBlock<T>::NDataBlock(size_t n, bool fzero)
+// Createur d'une structure de "n" donnees
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this<<",n="<<n<<")"<<endl;
+if (gThsop == NULL) gThsop = new ThSafeOp;
+
+Alloc(n, NULL, NULL, fzero);   // 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;
+if (gThsop == NULL) gThsop = new ThSafeOp;
+
+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;
+if (gThsop == NULL) gThsop = new ThSafeOp;
+}
+
+//! 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;
+
+Dealloc();  // ThreadSafe version of 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"));
+//--- Start of atomic (in one block) operation for thread safety 
+gThsop->lock();   //  (ThreadSafe)
+if(mSRef) Delete();
+mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
+gThsop->unlock();   //  (ThreadSafe)
+//--- End of atomic operation 
+
+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
+ */
+
+
+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"));
+//--- Start of atomic (in one block) operation for thread safety (ThreadSafe)
+gThsop->lock();   //  (ThreadSafe)
+if(mSRef) Delete();
+mSz = n;
+mSRef = new NDREF;
+mSRef->nref = 1;
+mSRef->dsid = AnyDataObj::getUniqueId(); 
+if(data) mSRef->data = data;
+else {mSRef->data = new T[n]; if (zero) memset(mSRef->data,0,n*sizeof(T));}
+mSRef->bridge = br;
+gThsop->unlock();   //  (ThreadSafe)
+//--- End of atomic operation (ThreadSafe)
+
+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 (NOT thread-safe)
+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) {
+  if(Debug_NDataBlock>1)
+    cout<<"...?_NDataBlock::Delete() Bridge "<<mSRef->bridge<<" deleted"<<endl;
+  delete mSRef->bridge;
+} else {
+  if(Debug_NDataBlock>1)
+    cout<<"...?_NDataBlock::Delete() data "<<mSRef->data<<" deleted"<<endl;
+  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
+}
+
+/*! 
+  \brief Calls the protected Delete() method to set the size to zero
+  This is the public - thread safe version - of the Delete() method
+  The memory is freed if last referenced structure. 
+*/
+template <class T>
+void NDataBlock<T>::Dealloc()
+{
+  gThsop->lock();
+  Delete();
+  gThsop->unlock();
+}
+
+////////////////
+// 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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/BaseTools/ndatablock.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ndatablock.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ndatablock.h	(revision 3445)
@@ -0,0 +1,240 @@
+// 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>
+
+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 ThSafeOp; //forward class declaration for ThreadSafe operations (Ref.Count/Share) 
+
+////////////////////////////////////////////////////////////////
+//// ----------------- 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, bool fzero=true);
+  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 si fzero=true. 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 if \b fzero=true .
+    The new data structure has only one reference (itself!). */
+  inline void ReSize(size_t n, bool fzero=true) {Alloc(n,NULL,NULL,fzero);}
+
+  void Realloc(size_t nnew,bool force=false);
+  
+  //  Public, thread safe interface to Delete() (set the size to zero)
+  void Dealloc();
+
+  // 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 mSRef->nref;  else return 0; }
+
+  // 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;
+
+  //! Return thye associated object Id (or DataRef Id)
+  inline uint_8 DRefId() { return ((mSRef)?mSRef->dsid:0); }
+  //! assign a new object Id (or DataRef Id) - useful for PPF write operations 
+  inline void RenewDRefId() { if (mSRef) mSRef->dsid = AnyDataObj::getUniqueId(); } 
+  //! assign a new object Id (or DataRef Id) - useful for PPF write operations 
+  inline void RenewObjId() { if (mSRef) mSRef->dsid = AnyDataObj::getUniqueId(); }
+  
+
+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)
+  static ThSafeOp* gThsop;  //!< Mutex For thread safe operation 
+
+  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_Nov2007/SophyaLib/BaseTools/objfio.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/objfio.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/objfio.h	(revision 3445)
@@ -0,0 +1,70 @@
+// 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"
+
+/*!
+   \class SOPHYA::ObjFileIO
+   \ingroup BaseTools
+   Template class to ease implementation of PPersist handlers for a 
+   class T , inheriting from AnyDataObj. The methodes ReadSelf() and 
+   WriteSelf() must be implemented.
+   \sa PPersist
+*/
+
+namespace SOPHYA {
+
+
+template <class T>
+class ObjFileIO : public PPersist {
+
+public :
+	    ObjFileIO() { dobj=NULL; 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); is.SkipToNextObject(); fio.Read(is); return(is); }  
+*/
+
+
+} // Fin namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/objlist.list	(revision 3445)
@@ -0,0 +1,15 @@
+datatype.o
+dvlist.o
+fiondblock.o
+gnumd5.o
+mutyv.o
+ndatablock.o
+pexceptions.o
+ppersist.o
+ppfbinstream.o
+ppftpointerio.o
+rawstream.o
+sophyainit.o
+srandgen.o
+stsrand.o
+timestamp.o
Index: /tags/V_Nov2007/SophyaLib/BaseTools/osx_values.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/osx_values.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/osx_values.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/perrors.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/perrors.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/perrors.h	(revision 3445)
@@ -0,0 +1,1 @@
+#include "pexceptions.h"
Index: /tags/V_Nov2007/SophyaLib/BaseTools/pexceptions.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/pexceptions.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/pexceptions.cc	(revision 3445)
@@ -0,0 +1,35 @@
+#include "sopnamsp.h"
+#include "pexceptions.h"
+#include <iostream>
+#include <stdio.h>
+
+void PFailHandler(void); 
+
+// egcs ne semble pas connaitre set_new_handler (Reza 26/04/99)
+// ca ne passe plus avec SGI-CC -LANG:std $CHECK$ Reza 14/02/2003
+#if defined( __GNUG__ ) || defined(__SGICC__)
+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_Nov2007/SophyaLib/BaseTools/pexceptions.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/pexceptions.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/pexceptions.h	(revision 3445)
@@ -0,0 +1,245 @@
+// 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) {}
+    explicit PThrowable(const char* 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) {}
+    explicit PError(const char* 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) {}
+    explicit AllocationError(const char* 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) {}
+    explicit NullPtrError(const char* 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) {}
+    explicit ForbiddenError(const char* 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) {}
+    explicit AssertionFailedError(const char* 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) {}
+    explicit IOExc(const char* 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) {}
+    explicit FileFormatExc(const char* 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) {}
+    explicit SzMismatchError(const char* 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) {}
+    explicit RangeCheckError(const char* 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) {}
+    explicit ParmError(const char* 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) {}
+    explicit NotAvailableOperation(const char* 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) {}
+    explicit TypeMismatchExc(const char* 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) {}
+    explicit MathExc(const char* 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) {}
+    explicit SingMatrixExc(const char* 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) {}
+    explicit DuplicateIdExc(const char* 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) {}
+    explicit NotFoundExc(const char* 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) {}
+    explicit CaughtSignalExc(const char* 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 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 DBASSERT(_x_) ASSERT(_x_)
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppersist.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppersist.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppersist.cc	(revision 3445)
@@ -0,0 +1,748 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include "pexceptions.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+#include <iostream>
+#include <iomanip>
+#include <typeinfo>
+
+// ------------------------- Historique ---------------------------
+// Le code de ppersist a ete separe en deux en Decembre 2003
+// a partir de la version CVS (1.26 - ppersist.cc) et 
+// (1.19 - ppersist.h) .  
+// la partie sur l'ecriture des donnees de base et leurs tableaux
+// a ete mis dans les fichiers ppfbinstream.h .cc 
+// (Classes PPFBinaryInputStream et PPFBinaryOutputStream
+// -----------------------------------------------------------------
+
+
+
+/*!
+   \class SOPHYA::PIOPersist
+   \ingroup BaseTools
+   Handles (statically) the registration of PPF Sophya Persistence) handler classes. 
+   \sa PPersist
+*/
+
+
+//++
+// Class	PIOPersist
+// Lib		Outils++
+// include	ppersist.h
+//
+//	Root class for persistant files. Handles the registration of
+//	persistant classes
+//--
+
+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;
+}
+
+/*!
+  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
+*/
+void
+PIOPersist::RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f)
+{
+  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;
+}
+
+/*!
+  Register a new DataObj class corresponding to a PPersist classId
+  class_typename should be typeid(DataObject).name() 
+*/
+void
+PIOPersist::RegisterDataObjClass(uint_8 classId, string class_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.
+
+//! Lists the registered PPersist handler classes and the corresponding class id.
+void
+PIOPersist::ListPPHandlers()
+{
+  cout << " PIOPersist::ListPPHandlers() - List of registered PPersist handler classes " << endl;
+  map<string, uint_8>::iterator it;
+  int k = 0;
+  for (it = (*ppclassNameList).begin(); it != (*ppclassNameList).end(); it++) {
+    cout << ++k << ":   " << (*it).first << "\n" << "          ClassId: Hex=  " 
+	 << hex << (*it).second << "  (Dec= " << dec << (*it).second << ")" << endl;   
+  }
+}
+
+//! Lists the registered DataObj classes with the corresponding PPHandler name
+void
+PIOPersist::ListDataObjClasses()
+{
+  cout << " PIOPersist::ListDataObjClasses() : Registered DataObj class list " << endl;
+  map<string, uint_8>::iterator it;
+  int k = 0;
+  for (it = (*dobjclassNameList).begin(); it != (*dobjclassNameList).end(); it++) {
+    cout << ++k << "- "  << (*it).first << "  ->  " << getPPClassName((*it).second) << endl; 
+  }
+}
+
+//! Returns the PPersist class creator function for the specified classId
+PIOPersist::ClassCreatorFunc
+PIOPersist::FindCreatorFunc(uint_8 classId)
+{
+  ClassList::iterator i = ppclassList->find(classId);
+  if (i == ppclassList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc() Not found classId"));
+  return (*i).second;
+}
+
+//! Returns the PPersist class name for the specified classId
+string 
+PIOPersist::getPPClassName(uint_8 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"));
+}
+
+//! Returns the classId for the specified PPersist class type name
+uint_8
+PIOPersist::getPPClassId(string const & typ_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;
+}
+
+//! Returns the classId for the specified PPersist class 
+uint_8
+PIOPersist::getPPClassId(PPersist const & ppo)
+{
+  string typ_name = typeid(ppo).name() ;
+  return (getPPClassId(typ_name) );
+}
+
+
+//! Returns the PPersist class name for the specified classId
+string 
+PIOPersist::getDataObjClassName(uint_8 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"));
+}
+
+//! Returns the classId for the specified PPersist class type name
+uint_8
+PIOPersist::getDataObjClassId(string const & typ_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;
+}
+
+//! Returns the classId for the specified PPersist class 
+uint_8
+PIOPersist::getDataObjClassId(AnyDataObj const & o)
+{
+  string typ_name = typeid(o).name() ;
+  return (getDataObjClassId(typ_name) );
+}
+
+//! \cond
+static inline void bswap8_hash(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));
+}
+
+//! \endcond
+
+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_hash(&hash1);
+	bswap8_hash(&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.
+//	- 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.
+//--
+
+/*!
+   \class SOPHYA::PPersist
+   \ingroup BaseTools
+   Ancestor (base) class for SOPHYA persistence (PPF) handlers. 
+   In order to have provide a PPF handler for an object :
+   - Inherit from PPersist
+   - Implement WriteSelf() and ReadSelf()
+
+   \sa PInPersist POutPersist PIOPersist
+*/
+
+//! Writes the object into a new PPF file named \b fn 
+void
+PPersist::Write(string const& fn) const
+{
+  POutPersist of(fn);
+  Write(of);
+}
+
+//! Reads the object from a PInPersist stream created from file \b fn 
+void
+PPersist::Read(string const& fn) 
+{
+  PInPersist inf(fn);
+  inf.SkipToNextObject();
+  Read(inf);
+}
+
+//! Writes the object to the output PPF stream \b s
+void
+PPersist::Write(POutPersist& s) const
+{
+   s.PutPPObject(this);
+}
+
+
+//! Reads the object from the input PPF stream \b s
+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");
+
+}
+
+//! Writes a name tag (\b tag) and then the object to the output PPF stream \b s
+void
+PPersist::Write(POutPersist& s, string const& tag) const
+{
+  s.WriteNameTag(tag);
+  s.PutPPObject(this);
+}
+
+//! Try to position at the name tag \b tag and then reads the object from the input stream \b s
+void
+PPersist::ReadAtTag(PInPersist& s, string const& tag)
+{
+  if (!s.GotoNameTag(tag))
+    throw NotFoundExc("PPersist::ReadAtTag  tag not found");
+  Read(s);
+}
+
+// Renvoie l'identificateur de l'objet  - par defaut=0
+/*! Return the object identifier (default: return 0)
+  (used for handling of PPF I/O for objects with reference sharing).
+*/
+uint_8 
+PPersist::getMemOId() const
+{
+  return(0);
+}
+
+// Ces deux methodes doivent etre redefinies si   getMemOId() renvoie non nul (>0)
+// ShareDataReference() et CloneSharedReference()
+/*! 
+  This method should be re-implemented if getMemOId() non zero value.
+  (used for handling of PPF I/O for objects with reference sharing).
+*/
+void 
+PPersist::ShareDataReference(PPersist & pcs)
+{
+  throw NotAvailableOperation("PPersist::ShareDataReference() - Unsupported operation !");
+}
+
+/*! 
+  This method should be re-implemented if getMemOId() non zero value.
+  (used for handling of PPF I/O for objects with reference sharing).
+*/
+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.
+//--
+
+/*!
+   \class SOPHYA::PInPersist
+   \ingroup BaseTools
+   This class implements the I/O read services necessary for SOPHYA
+   persistence (PPF) by extending the services provided by PPFBinaryInputStream.
+   \sa PPersist
+*/
+
+/*! Constructor from a RawInOutStream pointer
+  \param is : pointer to RawInOutStream
+  \param ad : if true, the RawInOutStream \b is is deleted by the destructor 
+  \param scan : if true, try to read the name-tags table from the end of the input stream
+*/ 
+PInPersist::PInPersist(RawInOutStream * is, bool ad, bool scan)
+  : PPFBinaryInputStream(is, ad, scan)
+{
+}
+
+/*! Constructor 
+  \param  flnm : input file name
+  \param scan : if true, try to read the name-tags table from the end of the input stream
+*/  
+PInPersist::PInPersist(string const& flnm, bool scan)
+  : PPFBinaryInputStream(flnm, scan)
+{
+}
+
+
+
+PInPersist::~PInPersist()
+{
+  ObjList::iterator i;
+  for(i=objList.begin(); i!= objList.end(); i++)  
+    if ((*i).second)  delete (*i).second;
+}
+
+
+
+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("");
+}
+
+/*! Skip to next object in the streams, reads it and return 
+  the corresponding PPersist handler 
+*/
+PPersist*
+PInPersist::ReadObject()
+{
+  SkipToNextObject();
+  return(GetPPObject());
+}
+
+/*! 
+  Tries to read in from the stream into object \b o
+*/
+void 
+PInPersist::GetObject(AnyDataObj & o)
+{
+  GetPPObject(&o);
+  return;
+}
+
+/*! 
+  Tries to move to \b nametag and then read in from the stream into object \b o
+*/
+void 
+PInPersist::GetObject(AnyDataObj & o, string tagname)
+{
+  GotoNameTag(tagname);
+  GetPPObject(&o);
+  return;
+}
+
+/*! 
+  Reading of objects - used by GetObject() and ReadObject()
+*/
+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) {
+    PPersist* ppr = ReadReference();
+    PPersist* pprc = ppr->CloneSharedReference();
+    if (po) {  // We have to read it into an object 
+      pprc->SetDataObj(*po);
+      pprc->ShareDataReference(*ppr);  // On met a jour la reference de pprc
+    }
+    return pprc;
+  }
+  else throw FileFormatExc("PInPersist::ReadObject invalide Tag Type !");  
+}
+
+
+
+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;
+    cpos = s->tellg();
+    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 GotoNameTag)
+    //  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);  // On met a jour la reference des donnees de ppo
+  }
+  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.
+//--
+
+
+/*!
+   \class SOPHYA::POutPersist
+   \ingroup BaseTools
+   This class implements the I/O write services necessary for SOPHYA
+   persistence (PPF) by extending the services provided by PPFBinaryOutputStream.
+   \sa PPersist
+*/
+
+//++
+//  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.
+//--
+
+/*! Constructor from a RawInOutStream pointer
+  \param os : pointer to RawInOutStream
+  \param ad : if true, the RawInOutStream \b os is deleted by the destructor 
+  \param endianness : Endianness selector  PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN 
+*/ 
+POutPersist::POutPersist(RawInOutStream* os, bool ad, int endianness)
+  : PPFBinaryOutputStream(os, ad, endianness)
+{
+  pps_OId = 0;
+  wobj_level = 0;
+}
+
+/*! Constructor 
+  \param flnm : output file name 
+  \param endianness : Endianness selector  PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN 
+*/ 
+POutPersist::POutPersist(string const& flnm, int endianness)
+  : PPFBinaryOutputStream(flnm, endianness)
+{
+  // PPS (POutPersist stream) Object Id initialisation
+  pps_OId = 0;
+  wobj_level = 0;
+}
+
+POutPersist::~POutPersist()
+{
+}
+
+
+//! Writes the object \b o to the stream
+void
+POutPersist::PutObject(AnyDataObj & o)
+{
+  ClassCreatorFunc f = FindCreatorFunc(getDataObjClassId(o));
+  if (!f) 
+      throw NotFoundExc("POutPersist::PutObject()   class not registered");
+  PPersist* ppo = f();
+  ppo->SetDataObj(o);
+  PutPPObject(ppo);
+}
+
+//! Writes the nametag \b tagname and then the object \b o to the stream
+void
+POutPersist::PutObject(AnyDataObj & o, string tagname)
+{
+  WriteNameTag(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
+  wobj_level++;  // Niveau d'imbrication d'ecriture d'objets
+  PutRawU8(getPPClassId(*obj));    // Writing the PPersist ClassId
+  PutRawU8(oid);                   // Write the PPS Object Id 
+  obj->WriteSelf(*this);
+  //  Comptage d'objets ecrits
+  _nbobjs++;
+  if (wobj_level > _maxnestlevel)  _maxnestlevel = wobj_level;
+  if (wobj_level == 1) _nbtlobjs++;
+  wobj_level--;  
+  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 
+    _nbrefs++;         // Compteur de nombre de reference ecrits
+    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;
+    //    cout << " DBG-rt.ppspos = s->tellp(); " << endl;
+    rt.ppspos = s->tellp();
+    // cout << " DBG-rt.ppspos = s->tellp(); = " << rt.ppspos << endl;
+    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_Nov2007/SophyaLib/BaseTools/ppersist.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppersist.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppersist.h	(revision 3445)
@@ -0,0 +1,258 @@
+// 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
+
+// -------------------- Historique -----------------------
+//  Separe en deux (CVS version 1.19 - ppersist.h)  
+//  Classes PPFBinaryIn/OutputStream ds ppfbinstream.h
+// -------------------------------------------------------
+
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "gnumd5.h"
+#include "ppfbinstream.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() {}
+
+    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;
+  };
+
+
+
+// Handles (statically) the registration of classes.
+
+  class PIOPersist {
+  public:
+    typedef PPersist*            (*ClassCreatorFunc)();
+  
+    static void                  RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f);
+    static void                  RegisterDataObjClass(uint_8 classId, string class_name);
+
+    static void			 ListPPHandlers();
+    static void			 ListDataObjClasses();
+
+    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
+
+
+  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)
+
+  };
+
+
+// TBD : use hash tables instead of maps. Check hashtbl status in STL.
+
+//! Input stream for PPersit objects.
+  class PInPersist : public PPFBinaryInputStream, public PIOPersist  {
+  public:
+    PInPersist(RawInOutStream * is, bool ad, bool scan=false);
+    PInPersist(string const& flnm, bool scan=true);
+    virtual ~PInPersist();
+
+    // A faire - Reza Dec 2003
+    string     GetTagClassName(int itag);
+    //   Object Reading 
+    PPersist*  ReadObject();
+    void       GetObject(AnyDataObj & o);
+    void       GetObject(AnyDataObj & o, string  tagname);
+    PPersist*  GetPPObject(AnyDataObj * po=NULL);
+
+    //  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:
+
+    // already read objects 
+    typedef map<uint_8, PPersist * > ObjList;
+    ObjList objList;
+    friend class PPersist;
+  };
+
+//! Output stream for PPersit objects.
+  class POutPersist : public PPFBinaryOutputStream, public PIOPersist  {
+  public:
+    POutPersist(RawInOutStream* os, bool ad, int endianness = PPS_NATIVE);
+    POutPersist(string const& flnm, int endianness = PPS_NATIVE);
+    virtual ~POutPersist();
+
+    //    void   Put(PPersist const* x) {PutPPObject(x);}
+
+    // Objet Write - Ecriture des objets
+    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);
+
+
+  protected:
+    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 
+    int    wobj_level; // Niveau d'imbrication lors de l'ecriture d'objet
+  };
+  
+//! \cond
+// Le macro suivant permettent de simplifier la declaration 
+// des operateurs >> << sur les POutPersist et  PInPersist
+#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;                                                                     \
+  }                                                                               
+
+// On utilise le macro RAWPERSISTIO pour declarer POutPersist << et PInPersist >> 
+// pour les types de base r_4 r_8 int_4 int_8 ...
+  RAWPERSISTIO(int_8,I8);
+  RAWPERSISTIO(uint_8,U8);
+  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);
+  RAWPERSISTIO(complex<r_4>,Z4);
+  RAWPERSISTIO(complex<r_8>,Z8);
+  RAWPERSISTIO(string,Str);
+  
+#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
+
+//! \endcond  
+
+// --- 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 SOPHYA
+
+// La classe PPFNameTag facilite la manipulation des Nametag ds les fichiers
+// PPersist - definie ds ppfnametag.h
+#include "ppfnametag.h"
+
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.cc	(revision 3445)
@@ -0,0 +1,1857 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include "ppfbinstream.h"
+#include "pexceptions.h"
+#include <iostream>
+
+
+//  strptime n'est pas defini sous Linux avec g++ avant gcc 3.x - Reza Mars 2000
+#if defined(OS_LINUX) && defined(__GNUG__) && (__GNUC__ < 3) 
+extern "C" {
+char *strptime(const char *buf, const char *format, struct tm *tm);
+}
+#endif
+
+#define MAXTAGLEN_V2 255
+
+
+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);
+}
+
+//-------------------------------------------------------------------------
+//----------------------  Classe PPFBinaryIOStream ------------------------
+//-------------------------------------------------------------------------
+
+/*!
+   \class SOPHYA::PPFBinaryIOStream
+   \ingroup BaseTools
+   Base class for SOPHYA PPF input / output stream
+*/
+
+
+PPFBinaryIOStream::PPFBinaryIOStream()
+{
+  version = 0;     // PPersist(In/Out) version 
+  //  creationdate = time(NULL);   // Date de creation du fichier
+  _nbpostag = 0;     // Nb de tag de positionnement
+  _nbobjs = 0;       // Nb total d'objets
+  _nbtlobjs = 0;     // Nb d'objets de niveau 1 
+  _nbrefs = 0;       // Nb de reference d'objets
+  _maxnestlevel = 0; // Niveau maximum d'objets emboites
+}
+
+PPFBinaryIOStream::~PPFBinaryIOStream()
+{
+}
+
+//! Return the creation date/time of the associated stream as a string 
+string 
+PPFBinaryIOStream::CreationDateStr()
+{
+  time_t cdt = CreationDate();
+  string cdate = ctime(&cdt);
+  return(cdate);
+}
+
+//! Return a string with information about the stream (creation-date, version ...)
+string 
+PPFBinaryIOStream::InfoString()
+{
+  string rs;
+  char buff[256];
+  sprintf(buff,"PPFStream Version= %d  CreationDate= ", Version());
+  rs += buff;
+  rs += CreationDateStr();
+  sprintf(buff,"\n NbObjs= %ld NbTopLevObjs= %ld NbRefs= %ld MaxNest= %d ", 
+	  (long)NbObjects(), (long)NbTopLevelObjects(), 
+	  (long)NbReferences(), MaxNestedObjsLevel());
+  rs += buff;
+  sprintf(buff,"\n NbPosTag= %ld NbNameTag= %ld ", (long)NbPosTags(), 
+	  (long)NbNameTags());
+   rs += buff;
+   return rs;
+}
+
+
+//! Return the name tag number \b itag
+string
+PPFBinaryIOStream::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);
+}
+
+
+//! Return a reference to a vector<string> containing all name-tags associated with the stream
+static vector<string> * ret_tag_names = NULL;
+vector<string> const &
+PPFBinaryIOStream::GetNameTags()
+{
+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);  
+}
+
+//-------------------------------------------------------------------------
+//--------------------  Classe PPFBinaryInputStream -----------------------
+//-------------------------------------------------------------------------
+
+/*!
+   \class SOPHYA::PPFBinaryInputStream
+   \ingroup BaseTools
+   PPF Input stream implementing read operations
+*/
+
+/*! Constructor from a RawInOutStream pointer
+  \param is : pointer to RawInOutStream
+  \param ad : if true, the RawInOutStream \b is is deleted by the destructor 
+  \param scan : if true, try to read the name-tags table from the end of the input stream
+*/ 
+PPFBinaryInputStream::PPFBinaryInputStream(RawInOutStream * is, bool ad, bool scan)
+{
+  s = is;
+  _ads = ad;
+  Init(scan);
+}
+
+/*! Constructor 
+  \param  flnm : input file name
+  \param scan : if true, try to read the name-tags table from the end of the input stream
+*/  
+PPFBinaryInputStream::PPFBinaryInputStream(string const& flnm, bool scan)
+//
+//	Constructeur. Ouvre le fichier.
+//--
+{
+  s = new RawInFileStream(flnm.c_str());
+  _ads = true;
+  Init(scan);
+}
+
+PPFBinaryInputStream::~PPFBinaryInputStream()
+{
+  if (_ads && (s!=NULL) ) delete s;
+}
+
+void
+PPFBinaryInputStream::Init(bool scan)
+{
+  // Read and check header
+
+  char rbuf[36];
+  GetRawBytes(rbuf, 32);
+  if (strncmp(rbuf,"SOS-SOPHYA-PPersistFile", 23) != 0)  {
+    throw FileFormatExc("PPFBinaryInputStream::PPFBinaryInputStream  bad header");
+  }
+  rbuf[32] = '\0';
+  version = atoi(rbuf+25);
+  if (version < 2) {
+    cerr << "PPFBinaryInputStream::PPFBinaryInputStream(" << FileName() << ") Version(=" << version 
+	 << ") < 2 not supported !" << endl;
+    throw FileFormatExc("PPFBinaryInputStream::PPFBinaryInputStream() - 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("PPFBinaryInputStream::PPFBinaryInputStream  bad header - endianness");
+  }
+
+  // read creation date
+  GetRawBytes(rbuf, 32);
+  rbuf[32] = '\0'; 
+  struct tm tm;
+  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);
+  seqread = true;   // To flag non sequential reads
+  if (scan && s->isSeekable()) { 
+    if (Version() >= 3) ReadNameTagTable();
+    else ReadNameTagTableV2();
+  }
+}
+
+
+void
+PPFBinaryInputStream::ReadNameTagTable()
+{
+  unsigned char ppstype;
+  int_8 debut;
+  debut = s->tellg();
+
+  s->seekg(-(sizeof(int_8)+1), ios::end);
+  // Lecture position NameTagTable et tag EOF
+  int_8 pos;
+  GetRawI8(pos);
+  GetRawUByte(ppstype);
+  if (ppstype != PPS_EOF)
+    throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable()  Corrupted file, no EOF tag at end of file");
+  
+  // On se positionne au debut du NameTagTable
+  s->seekg(pos);
+  GetRawUByte(ppstype);
+  if (ppstype != PPS_NAMETAG_TABLE)
+    throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable()  Corrupted file PPS_NAMETAG_TABLE not found");
+  // Lecture nb de PosTag et nb d'objets dans le flot
+  int_8 stats[8] = {0,0,0,0,0,0,0,0};
+  GetI8s(stats, 8);
+  _nbpostag = stats[0];
+  _nbobjs = stats[1];
+  _nbtlobjs = stats[2];
+  _nbrefs = stats[3];
+  _maxnestlevel = stats[4];
+
+  uint_8 ttsz,it;
+  // Lecture nombre de NameTag
+  GetRawU8(ttsz);
+  if (ttsz > 0) {
+    for(it=0; it<ttsz; it++) {
+      int_8 tpos;
+      string tname;
+      GetRawI8(tpos);
+      GetStr(tname);
+      tags[tname] = tpos;
+    }
+  }
+  // On revient au debut du float, juste apres l'entete
+  s->seekg(debut);
+}
+
+void
+PPFBinaryInputStream::ReadNameTagTableV2()
+{
+  // On cherche la liste des tags, a la fin du fichier
+
+  unsigned char ppstype;
+  int_8 debut;
+  debut = s->tellg();
+
+  s->seekg(-(sizeof(int_8)+1), ios::end);
+
+  GetRawUByte(ppstype);
+  if (ppstype != PPS_EOF)
+    throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() 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_V2+1];
+  s->seekg(pos);
+  while (true) {
+    GetRawUByte(ppstype);
+    if (ppstype == PPS_EOF) break;
+    
+    if (ppstype != PPS_NAMETAG_TABLE)
+      throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() Corrupted file, bad tag entry");
+
+    GetRawI8(pos);
+    int_4 len;
+    GetRawI4(len);
+    if (len > MAXTAGLEN_V2) 
+      throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() Corrupted file, tag name too long");
+    GetRawBytes(buffer, len);
+    buffer[len] = '\0';
+
+    tags[buffer] = pos;
+  }
+  s->seekg(debut);
+}
+
+
+bool 
+PPFBinaryInputStream::GotoPositionTag(int_8 pos)
+{
+  s->seekg(pos);
+  unsigned char ppstag;
+  GetRawUByte(ppstag);
+  if (ppstag != PPS_POSTAG_MARK)
+    throw FileFormatExc("PPFBinaryInputStream::GotoPositionTag() - PPS_POSTAG_MARK not found!");    
+  int_8 tpos;
+  GetRawI8(tpos);
+  if (tpos != pos) 
+    throw FileFormatExc("PPFBinaryInputStream::GotoPositionTag() - Wrong tag position!");
+  return true;
+}
+
+bool 
+PPFBinaryInputStream::GotoNameTag(string const& name)
+{
+  map<string, int_8>::iterator i = tags.find(name);
+  if (i == tags.end()) 
+    return false;
+      //    throw NotFoundExc("PPFBinaryInputStream::GotoNameTag   tag not found");
+  s->seekg((*i).second);
+  seqread = false;
+  //  objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
+  return(true); 
+}
+
+
+bool
+PPFBinaryInputStream::GotoNameTagNum(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);
+}
+
+
+bool
+PPFBinaryInputStream::SkipToNextObject()
+{
+  if (! s->isSeekable())  return false;
+  unsigned char ppstag=0;
+  // int kss;
+  while ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF)) {
+    // kss++;
+    GetRawUByte(ppstag);
+    //    cout << " DBG--SkipToNextObject(" << kss << ")" << (int)ppstag << "," 
+    //	 << (int)PPS_OBJECT << " fpos=" << s->tellg() << endl;
+    if  ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF))
+      SkipItem(false, ppstag);
+  }
+  s->seekg(-1, ios::cur);
+  if (ppstag == PPS_OBJECT) return true;
+  else return false;
+  
+}
+
+bool
+PPFBinaryInputStream::SkipNextItem()
+{
+  if (! s->isSeekable())  return false;
+  SkipItem();
+  return true;
+}
+
+char
+PPFBinaryInputStream::NextItemTag(short & datasz, size_t & asz)
+{
+  int_8 cpos;
+  cpos = s->tellg();
+
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3,ppst30;
+  GetRawUByte(ppstag);
+  ppst1 = ppstag&0x0f;  // bits 0123
+  ppst2 = ppstag&0x30;  // bits     45
+  ppst3 = ppstag&0xc0;  // bits       67
+  ppst30 = ppstag&0xc1; // bits 0     67
+  
+  datasz = 0;
+  asz = 0;
+
+  int_4 i4;
+  uint_8 ui8;
+
+  if ((ppst2 == 0) && (ppst3 == 0) ) {
+    switch (ppst1) {
+    case PPS_STRING :
+      GetRawI4(i4);
+      datasz = 1;
+      asz = i4;
+      break;
+      
+    case PPS_NULL :
+    case PPS_OBJECT :
+    case PPS_REFERENCE :
+    case PPS_NAMETAG_MARK :
+    case PPS_POSTAG_MARK :
+    case PPS_ENDOBJECT :
+    case PPS_POSTAG_TABLE :
+    case PPS_NAMETAG_TABLE :
+    case PPS_EOF :
+      datasz = 0;
+      asz = 0;
+      break;
+
+    default :
+      throw FileFormatExc("PPFBinaryInputStream::NextItemTag() - Unexpected tag value !");
+      break;
+    }
+  }
+  else {
+    int_4 dsize = ppst1;
+    if (ppst30 == PPS_DATATYPE_COMPLEX) { 
+      dsize--;
+    }
+    switch (ppst2) {      
+    case PPS_SIMPLE :
+      datasz = dsize;
+      asz = 1;      
+      break;
+
+    case PPS_SIMPLE_ARRAY4 :
+      GetRawI4(i4);
+      datasz = dsize;
+      asz = i4;      
+      break;
+
+    case PPS_SIMPLE_ARRAY8 :
+      GetRawU8(ui8);
+      datasz = dsize;
+      asz = ui8;      
+      break;
+    }
+  }
+
+  s->seekg(cpos,ios::beg);
+  return(ppstag);
+}
+
+void 
+PPFBinaryInputStream::SkipItem(bool fgrdt, unsigned char itag)
+{
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3,ppst30;
+  uint_8 ui8;
+  int_4 i4;
+  int_8 i8;
+  
+  if (fgrdt)  GetRawUByte(ppstag);
+  else ppstag = itag;
+
+  ppst1 = ppstag&0x0f;  // bits 0123
+  ppst2 = ppstag&0x30;  // bits     45
+  ppst3 = ppstag&0xc0;  // bits       67
+  ppst30 = ppstag&0xc1; // bits 0     67
+  if ((ppst2 == 0) && (ppst3 == 0) ) {
+    switch (ppst1) {  
+    case PPS_NULL :
+    case PPS_NAMETAG_MARK :
+      break;
+
+    case PPS_STRING :
+      GetRawI4(i4);
+      s->seekg(i4,ios::cur);
+      break;
+
+    case PPS_OBJECT :
+      GetRawU8(ui8);
+      GetRawU8(ui8);
+      break;
+      
+    case PPS_REFERENCE :
+      GetRawU8(ui8);
+      GetRawI8(i8);
+      break;
+
+    case PPS_POSTAG_MARK :
+      GetRawI8(i8);	
+      break;
+     
+    case PPS_ENDOBJECT :
+      GetRawU8(ui8);
+      break;
+
+    case PPS_POSTAG_TABLE :
+      GetRawI4(i4);
+      //      for(int kkt=0; kkt<i4; kkt++)  GetRawI8(i8);	
+      s->seekg((int_8)i4*8,ios::cur);
+      break;
+
+    case PPS_NAMETAG_TABLE :
+      if (Version() < 3) {
+	GetRawI8(i8);
+	GetRawI4(i4);
+	s->seekg(i4,ios::cur);
+	}
+      else {
+	GetI8(i8);  // nb pos tag
+	GetI8(i8);  // nb d'objets
+	GetI8(i8);  // nb objets toplevel
+	GetU8(ui8); // nb de nametag
+	for(int kt=0; kt<ui8; kt++) {
+	  GetRawI4(i4);
+	  s->seekg(i4,ios::cur);
+	}
+	GetI8(i8);  // position debut NameTagTable
+      }
+      break;
+      
+
+    case PPS_EOF :
+      if (Version() < 3) GetRawI8(i8);	
+      break;
+      
+    default :
+      cerr << "PPFBinaryInputStream::SkipItem() ERROR : Unexpected tag value " 
+	   << hex << ppstag << " At position" << s->tellg() << dec << endl;
+      throw FileFormatExc("PPFBinaryInputStream::SkipItem() - Unexpected tag value !");
+    }
+  }
+  else {
+    string dtype = "???? x";
+    int_4 dsize = ppst1;
+    int_8 dsizeskip = dsize;
+    if (ppst30 == PPS_DATATYPE_COMPLEX) { 
+      dsize--;
+      dsizeskip = 2*dsize;
+    }
+
+    switch (ppst2) {
+    case PPS_SIMPLE :
+      s->seekg(dsizeskip, ios::cur);
+      break;
+
+    case PPS_SIMPLE_ARRAY4 :
+      GetRawI4(i4);
+      s->seekg(dsizeskip*(int_8)i4, ios::cur);
+      break;
+      
+    case PPS_SIMPLE_ARRAY8 :
+      GetRawU8(ui8);
+      s->seekg(dsizeskip*ui8, ios::cur);
+      break;
+    }
+  }
+return;
+}
+
+//++
+// void PPFBinaryInputStream::GetByte(char& c)
+// void PPFBinaryInputStream::GetBytes(void* ptr, size_t bytes)
+// void PPFBinaryInputStream::GetR4   (r_4& result)
+// void PPFBinaryInputStream::GetR4s  (r_4* tab, size_t n)
+// void PPFBinaryInputStream::GetR8   (r_8& result)
+// void PPFBinaryInputStream::GetR8s  (r_8* tab, size_t n)
+// void PPFBinaryInputStream::GetI2   (int_2& result)
+// void PPFBinaryInputStream::GetI2s  (int_2* tab, size_t n)
+// void PPFBinaryInputStream::GetU2   (uint_2& result)
+// void PPFBinaryInputStream::GetU2s  (uint_2* tab, size_t n)
+// void PPFBinaryInputStream::GetI4   (int_4& result)
+// void PPFBinaryInputStream::GetI4s  (int_4* tab, size_t n)
+// void PPFBinaryInputStream::GetU4   (uint_4& result)
+// void PPFBinaryInputStream::GetU4s  (uint_4* tab, size_t n)
+// void PPFBinaryInputStream::GetI8   (int_8& result)
+// void PPFBinaryInputStream::GetI8s  (int_8* tab, size_t n)
+// void PPFBinaryInputStream::GetU8   (uint_8& result)
+// void PPFBinaryInputStream::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 PPFBinaryInputStream::GetLine(char* ptr, size_t len)
+//	Lecture d'une ligne de texte depuis le fichier PPersist.
+//--
+
+
+void
+PPFBinaryInputStream::GetTypeTag(unsigned char& c) 
+{
+  int_8 tpos;
+  c = PPS_NAMETAG_MARK;
+  while ( (c == PPS_NAMETAG_MARK) || (c == PPS_POSTAG_MARK) ) {
+    GetRawUByte(c);
+    if (c == PPS_POSTAG_MARK)  GetRawI8(tpos);
+  } 
+  //  while (c == PPS_NAMETAG_MARK) {    Il ne faut plus faire ca !
+  //    objList.clear();             $CHECK$ Reza 03/2000
+  //    GetRawByte(c);
+  //  }
+}
+
+
+void
+PPFBinaryInputStream::GetRawByte(char& c)
+{
+  GetRawBytes(&c, 1);
+}
+
+void
+PPFBinaryInputStream::GetRawUByte(unsigned char& c)
+{
+  GetRawBytes(&c, 1);
+}
+
+void
+PPFBinaryInputStream::GetRawBytes(void* ptr, size_t bytes)
+{
+  s->read((char*)ptr, bytes);
+}
+
+void
+PPFBinaryInputStream::GetRawI2   (int_2& result)
+{
+  GetRawBytes(&result, sizeof(int_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PPFBinaryInputStream::GetRawI4   (int_4& result)
+{
+  GetRawBytes(&result, sizeof(int_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PPFBinaryInputStream::GetRawI8   (int_8& result)
+{
+  GetRawBytes(&result, sizeof(int_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PPFBinaryInputStream::GetRawU8   (uint_8& result)
+{
+  GetRawBytes(&result, sizeof(uint_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PPFBinaryInputStream::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("PPFBinaryInputStream::CheckTag   bad type in ppersist file");
+}
+
+void
+PPFBinaryInputStream::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("PPFBinaryInputStream::CheckArrayTag   bad type in ppersist file");
+    int_4 ff;
+    GetRawI4(ff); filesz=ff;
+  } else {
+    if (ppstype != PPS_SIMPLE_ARRAY8 + datasz + datatype)
+      throw FileFormatExc("PPFBinaryInputStream::CheckArrayTag   bad type in ppersist file");
+    uint_8 ff;
+    GetRawU8(ff); filesz=ff;
+  }
+  if (filesz != sz)
+    throw FileFormatExc("PPFBinaryInputStream::CheckArrayTag   bad array size in ppersist file");
+}
+
+void
+PPFBinaryInputStream::GetByte(char& c)
+{
+  CheckTag(1,PPS_DATATYPE_CHAR);
+  GetRawBytes(&c, 1);
+}
+
+
+void
+PPFBinaryInputStream::GetBytes(void* ptr, size_t bytes)
+{
+  CheckArrayTag(1, bytes, PPS_DATATYPE_CHAR);
+  GetRawBytes(ptr, bytes);
+}
+void
+PPFBinaryInputStream::GetR4   (r_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_FLOAT);
+  GetRawBytes(&result, sizeof(r_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetR8   (r_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_FLOAT);
+  GetRawBytes(&result, sizeof(r_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetI1   (int_1& result)
+{
+  CheckTag(1,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_1));
+}
+
+void
+PPFBinaryInputStream::GetI1s  (int_1* tab, size_t n)
+{
+  CheckArrayTag(1,n,PPS_DATATYPE_INTEGER);
+  GetRawBytes(tab, n*sizeof(int_1));
+}
+
+void
+PPFBinaryInputStream::GetU1   (uint_1& result)
+{
+  CheckTag(1,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_1));
+}
+
+void
+PPFBinaryInputStream::GetU1s  (uint_1* tab, size_t n)
+{
+  CheckArrayTag(1,n,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(tab, n*sizeof(uint_1));
+}
+
+void
+PPFBinaryInputStream::GetI2   (int_2& result)
+{
+  CheckTag(2,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetU2   (uint_2& result)
+{
+  CheckTag(2,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetI4   (int_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetU4   (uint_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetI8   (int_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetU8   (uint_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PPFBinaryInputStream::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
+PPFBinaryInputStream::GetLine(char* ptr, size_t len)
+{
+  string str;
+  GetStr(str);
+  strncpy(ptr, str.c_str(), len);
+  ptr[len] = '\0';
+}
+
+void
+PPFBinaryInputStream::GetStr(string& str)
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_STRING) 
+    throw FileFormatExc("PPFBinaryInputStream::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;
+}
+
+void
+PPFBinaryInputStream::GetZ4   (complex<r_4>& result)
+{
+  CheckTag(4,PPS_DATATYPE_COMPLEX);
+  r_4 reim[2];
+  GetRawBytes(reim, 2*sizeof(r_4));
+  if (bigEndian != IS_BIG_ENDIAN) {
+    bswap4(reim);
+    bswap4(reim+1);
+  }
+  result = complex<r_4>(reim[0], reim[1]);
+}
+
+void
+PPFBinaryInputStream::GetZ4s  (complex<r_4>* tab, size_t n)
+{  
+  CheckArrayTag(4,n,PPS_DATATYPE_COMPLEX);
+  GetRawBytes(tab, n*2*sizeof(r_4));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  r_4 * p = (r_4 *)tab;
+  for (unsigned int i=0; i<n; i++) {
+    bswap4(p);  p++;
+    bswap4(p);  p++;
+  }
+  return;
+}
+
+void
+PPFBinaryInputStream::GetZ8   (complex<r_8>& result)
+{
+  CheckTag(8,PPS_DATATYPE_COMPLEX);
+  r_8 reim[2];
+  GetRawBytes(reim, 2*sizeof(r_8));
+  if (bigEndian != IS_BIG_ENDIAN) {
+    bswap8(reim);
+    bswap8(reim+1);
+  }
+  result = complex<r_8>(reim[0], reim[1]);
+}
+
+void
+PPFBinaryInputStream::GetZ8s  (complex<r_8>* tab, size_t n)
+{
+  CheckArrayTag(8,n,PPS_DATATYPE_COMPLEX);
+  GetRawBytes(tab, n*2*sizeof(r_8));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  r_8 * p = (r_8 *)tab;
+  for (unsigned int i=0; i<n; i++) {
+    bswap8(p);  p++;
+    bswap8(p);  p++;
+  }
+  return;
+}
+
+
+void
+PPFBinaryInputStream::GetPosTagTable(int_8* ptab, size_t sz)
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_POSTAG_TABLE) 
+    throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable  bad type in ppersist stream");
+  int_4 tsz;
+  GetRawI4(tsz);
+  if (tsz != sz)
+    throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable Size mismatch ");
+  for(int kk=0; kk<tsz; kk++)
+    GetRawI8(ptab[kk]);
+  return;
+}
+
+void
+PPFBinaryInputStream::GetPosTagTable(vector<int_8>& ptab)
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_POSTAG_TABLE) 
+    throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable  bad type in ppersist stream");
+  ptab.clear();
+  int_4 tsz;
+  GetRawI4(tsz);
+  int_8 tpos;
+  for(int kk=0; kk<tsz; kk++) {
+    GetRawI8(tpos);
+    ptab.push_back(tpos);
+  }
+  return;
+}
+
+/*! Scans the streams and prints in text format to standard output (cout) the PPF 
+   stream content. 
+   \param lev : print level (level of details) = 0,1,2,3
+*/
+void
+PPFBinaryInputStream::AnalyseTags(int lev)
+{
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3,ppst30;
+  int_8 cpos,fsize;
+  uint_8 ui8,cid,oid;
+  int_4 i4;
+  int_8 i8;
+  char * buff;
+  string str;
+  // Pour indenter lors de l'impression 
+  #define _MXINDENT_ 10 
+  char * indents[_MXINDENT_+1] = {"","  ", "    ", "      ", "        ", "          ",
+				    "            ", "              ", "                ",
+				    "                  ", "                    "};
+  int idxindent = 0;
+  int idxind = 0;
+  cout << "\n ---------------------------------------------------------- " << endl;
+  cout << " PPFBinaryInputStream::AnalyseTags(Level= " << lev << ")" << endl; 
+
+
+  cpos = s->tellg();
+  s->seekg(0,ios::end);
+  fsize = s->tellg();
+  s->seekg(cpos,ios::beg);
+
+  cout << "   FileName= " << FileName() << endl;
+  cout << "   Version= " << Version() << " FileSize= " << fsize 
+       << " Creation Date= " << CreationDateStr() <<  endl;
+  cout << " NbPosTag=" << NbPosTags() << " NbNameTag=" << tags.size() 
+       << " NbObjs=" << NbObjects() << " NbTopLevObjs=" << NbTopLevelObjects()
+       << " NbRefs=" << NbReferences() << " MaxNest=" << MaxNestedObjsLevel()
+       << endl << endl;
+
+  uint_8 totntags = 0;
+  bool eofok = false;
+
+  while ( (ppstag != PPS_EOF) &&  (cpos < fsize) ) {
+    cpos = s->tellg();
+    GetRawUByte(ppstag);
+    totntags++;
+
+    ppst1 = ppstag&0x0f;  // bits 0123
+    ppst2 = ppstag&0x30;  // bits     45
+    ppst3 = ppstag&0xc0;  // bits       67
+    ppst30 = ppstag&0xc1; // bits 0     67
+    if ((ppst2 == 0) && (ppst3 == 0) ) {
+      switch (ppst1) {
+
+      case PPS_NULL :
+	if (lev > 1)  cout << indents[idxindent] 
+			   << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
+	break;
+
+      case PPS_STRING :
+	GetRawI4(i4);
+	if (lev > 1)  cout << indents[idxindent]
+			   << "<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 << indents[idxindent] 
+	     << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid 
+	     << "  ObjectId= " << oid << dec << endl;
+	idxind++;
+	idxindent = (idxind <= _MXINDENT_) ? idxind : _MXINDENT_;
+	break;
+
+      case PPS_REFERENCE :
+	GetRawU8(oid);
+	GetRawI8(i8);
+	cout << indents[idxindent] 
+	     << "<PPS_REFERENCE> tag at position " << hex << cpos << "  ObjectId= " 
+	     << oid << "  OrigPos=" << i8 << dec << endl;
+	break;
+
+      case PPS_NAMETAG_MARK :
+	cout << indents[idxindent] 
+	     << "<PPS_NAMETAG_MARK> tag at position " << hex << cpos << dec << endl; 
+	break;
+
+      case PPS_POSTAG_MARK :
+	GetRawI8(i8);	
+	cout << indents[idxindent] 
+	     << "<PPS_POSTAG_MARK> tag at position " << hex << cpos 
+	     << " TPos=" << i8 << dec << endl; 
+	break;
+     
+      case PPS_ENDOBJECT :
+	GetRawU8(oid);
+	idxind--;
+	idxindent = (idxind >= 0) ? idxind : 0;
+	cout << indents[idxindent] 
+	     << "<PPS_ENDOBJECT> tag at position " << hex << cpos << "  ObjectId= " 
+	     << oid << dec << endl;
+	break;
+
+      case PPS_POSTAG_TABLE :
+	GetRawI4(i4);
+	for(int kkt=0; kkt<i4; kkt++)  GetRawI8(i8);	
+	cout << indents[idxindent]
+	     << "<PPS_POSTAG_TABLE> tag at position " << hex << cpos << dec << endl; 
+	break;
+
+      case PPS_NAMETAG_TABLE :
+	if (Version() < 3) {
+	  GetRawI8(i8);
+	  GetRawI4(i4);
+	  buff = new char[i4+1];
+	  GetRawBytes(buff, i4); 
+	  buff[i4] = '\0';  str = buff;
+	  delete[] buff;
+	  cout << indents[idxindent]
+	       << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec 
+	       << " Name= " << str << endl; 
+	}
+	else {
+	  cout << indents[idxindent]
+	       << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec << endl;
+	  int_8 stats[8];
+	  GetI8s(stats,8); 
+	  GetRawU8(ui8); // nb de nametag
+	  for(int kt=0; kt<ui8; kt++) {
+	    string tname;
+	    GetRawI8(i8);
+	    GetStr(tname);
+	    if (lev > 0)  
+	      cout << "<PPS_NAMETAG_ENTRY>  NameTag=" << tname 
+		   << " NameTagMark Position=" << hex << i8 << dec << endl; 
+	  }
+	  GetRawI8(i8);  // position debut NameTagTable
+	}
+	break;
+
+      case PPS_EOF :
+	if (Version() < 3) GetRawI8(i8);	
+	cout << indents[idxindent]
+	     << "<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("PPFBinaryInputStream::AnalyseTags() - Unexpected tag value !");
+      }
+    }
+    else {
+      string dtype = "???? x";
+      if (ppst30 == PPS_DATATYPE_COMPLEX) dtype = "COMPLEX x";
+      else 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;
+      int_8 dsizeskip = dsize;
+      if (ppst30 == PPS_DATATYPE_COMPLEX) { 
+	dsize--;
+	dsizeskip = 2*dsize;
+      }
+      char sb[16];
+      sprintf(sb, "%d", dsize);
+      dtype += sb;
+
+      switch (ppst2) {
+
+      case PPS_SIMPLE :
+	if (lev > 2)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << endl;
+	s->seekg(dsizeskip, ios::cur);
+	break;
+
+      case PPS_SIMPLE_ARRAY4 :
+	GetRawI4(i4);
+	if (lev > 0)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << " NElts= " << i4 << endl;
+	s->seekg(dsizeskip*(int_8)i4, ios::cur);
+	break;
+
+      case PPS_SIMPLE_ARRAY8 :
+	GetRawU8(ui8);
+	if (lev > 0)  cout << indents[idxindent]
+			   << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << " NElts= " << ui8 << endl;
+	s->seekg(dsizeskip*ui8, ios::cur);
+	break;
+      }
+    }
+  }
+  if (!eofok) 
+    throw FileFormatExc("PPFBinaryInputStream::AnalyseTags() - Not found <PPS_EOF> tag ");
+
+  cout << " PPFBinaryInputStream::AnalyseTags() - End - Total Number of Tags= " << totntags << endl; 
+  cout << " ---------------------------------------------------------- \n" << endl;
+  return;
+}
+
+
+//-------------------------------------------------------------------------
+//-------------------  Classe PPFBinaryOutputStream -----------------------
+//-------------------------------------------------------------------------
+
+
+//++
+// 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.
+//--
+
+/*!
+   \class SOPHYA::PPFBinaryInputStream
+   \ingroup BaseTools
+   PPF output stream implementing write operations. The byte-ordering (endianess) 
+   of the output stream can be selected at creation. By default, the native endianness 
+   of the machine is used.  
+*/
+
+/*! Constructor from a RawInOutStream pointer
+  \param os : pointer to RawInOutStream
+  \param ad : if true, the RawInOutStream \b os is deleted by the destructor 
+  \param endianness : Endianness selector  PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN 
+*/ 
+PPFBinaryOutputStream::PPFBinaryOutputStream(RawInOutStream* os, bool ad, int endianness)
+{
+  s = os;
+  _ads = ad;
+  Init(endianness);
+}
+
+/*! Constructor 
+  \param flnm : output file name 
+  \param endianness : Endianness selector  PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN 
+*/ 
+PPFBinaryOutputStream::PPFBinaryOutputStream(string const& flnm, int endianness)
+{
+  // Output stream creation
+  s = new RawOutFileStream(flnm.c_str());
+  _ads = true;
+  Init(endianness);
+}
+
+PPFBinaryOutputStream::~PPFBinaryOutputStream()
+{
+  WriteNameTagTable();
+  if (_ads && (s != NULL)) delete s;   // Close the stream
+}
+
+void
+PPFBinaryOutputStream::Init(int endianness)
+{
+  if (endianness == -1)
+    bigEndian = IS_BIG_ENDIAN;
+  else
+    bigEndian = endianness;
+
+  version = 3;
+  // Header
+  PutRawBytes("SOS-SOPHYA-PPersistFile V3               ",32);
+  PutRawBytes(bigEndian 
+	   ? "BIG-ENDIAN                             "
+	   : "LITTLE-ENDIAN                          ",32);
+
+// ---- GMT creation date of the file
+  time_t tm = time(NULL);
+  creationdate = tm;
+  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);
+}
+
+void
+PPFBinaryOutputStream::WriteNameTagTable()
+{  
+  int_8 tagPos;
+  tagPos = s->tellp();
+  PutRawUByte(PPS_NAMETAG_TABLE);  //   NameTagTable tag
+  // Ecriture nb de PosTag et nb d'objets dans le flot
+  int_8 stats[8] = {0,0,0,0,0,0,0,0};
+  stats[0] = _nbpostag;
+  stats[1] = _nbobjs;
+  stats[2] = _nbtlobjs;
+  stats[3] = _nbrefs;
+  stats[4] = _maxnestlevel;
+  PutI8s(stats, 8);
+  // Ecriture nb de tag et les tags
+  PutRawU8((uint_8)tags.size());    // Number of tags
+  if (tags.size() > 0) {
+    for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
+      int_8 pos = (*i).second;
+      PutRawI8(pos);
+      PutStr((*i).first);
+    }
+  }
+  PutRawI8(tagPos);
+  PutRawUByte(PPS_EOF);
+  return;
+}
+
+void
+PPFBinaryOutputStream::WriteNameTagTableV2()
+{
+  if (tags.size() == 0) {
+    PutRawUByte(PPS_EOF);
+    PutRawI8(-1);
+  } else {
+    int_8 tagPos;
+    tagPos = s->tellp();
+    for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
+      string name = (*i).first;
+      int_8 pos = (*i).second;
+      PutRawUByte(PPS_NAMETAG_TABLE);                       // 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);
+  }
+
+}
+
+
+int_8
+PPFBinaryOutputStream::WritePositionTag()
+{
+  int_8 tagpos;
+  tagpos = s->tellp();
+  PutRawByte(PPS_POSTAG_MARK);
+  PutRawI8(tagpos);
+  _nbpostag++;  // Compteur de nombre de tags 
+  return(tagpos);
+}
+
+void
+PPFBinaryOutputStream::WriteNameTag(string const& name)
+{
+  //  if (name.length() > MAXTAGLEN_V2) 
+  //  throw ParmError("PPFBinaryOutputStream::WriteNameTag   tag name too long");
+
+  if (tags.find(name) != tags.end())
+    throw DuplicateIdExc("PPFBinaryOutputStream::WriteNameTag   duplicate tag name");
+
+  // Get current file position
+  int_8 tagPos;
+  tagPos = s->tellp();
+
+  tags[name] = tagPos;
+  PutRawUByte(PPS_NAMETAG_MARK);                       // This is a tag
+  //  objList.clear(); // $CHECK$ EA 171199  - Ne pas faire ? Reza 03/2000
+}
+
+//++
+// void PPFBinaryOutputStream::PutByte(char& c)
+// void PPFBinaryOutputStream::PutBytes(void const* ptr, size_t bytes)
+// void PPFBinaryOutputStream::PutR4   (r_4 result)
+// void PPFBinaryOutputStream::PutR4s  (r_4 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutR8   (r_8 result)
+// void PPFBinaryOutputStream::PutR8s  (r_8 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutI2   (int_2 result)
+// void PPFBinaryOutputStream::PutI2s  (int_2 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutU2   (uint_2 result)
+// void PPFBinaryOutputStream::PutU2s  (uint_2 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutI4   (int_4 result)
+// void PPFBinaryOutputStream::PutI4s  (int_4 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutU4   (uint_4 result)
+// void PPFBinaryOutputStream::PutU4s  (uint_4 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutI8   (int_8 result)
+// void PPFBinaryOutputStream::PutI8s  (int_8 const* tab, size_t n)
+// void PPFBinaryOutputStream::PutU8   (uint_8 result)
+// void PPFBinaryOutputStream::PutU8s  (uint_8 const* tab, size_t n)
+// void PPFBinaryOutputStream::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 PPFBinaryOutputStream::PutLine(char const* ptr, size_t len)
+//	Ecriture d'une ligne de texte dans le fichier PPersist.
+//--
+
+
+
+
+void
+PPFBinaryOutputStream::PutRawBytes(void const* ptr, size_t bytes)
+{
+  s->write((char const*)ptr, bytes);
+}
+
+void
+PPFBinaryOutputStream::PutRawByte(char c)
+{
+  PutRawBytes(&c, 1);
+}
+
+void
+PPFBinaryOutputStream::PutRawUByte(unsigned char c)
+{
+  PutRawBytes(&c, 1);
+}
+
+void
+PPFBinaryOutputStream::PutRawI2   (int_2 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(int_2));
+}
+
+void
+PPFBinaryOutputStream::PutRawI4   (int_4 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(int_4));
+}
+
+void
+PPFBinaryOutputStream::PutRawI8   (int_8 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(int_8));
+}
+
+void
+PPFBinaryOutputStream::PutRawU8   (uint_8 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(uint_8));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutByte(char c)
+{
+  PutRawByte(PPS_SIMPLE + 1 + PPS_DATATYPE_CHAR);
+  PutRawBytes(&c, 1);
+}
+
+
+
+void
+PPFBinaryOutputStream::PutBytes(void const* ptr, size_t bytes)
+{
+  PutArrayTag(1, bytes, PPS_DATATYPE_CHAR);
+  PutRawBytes(ptr, bytes);
+}
+
+void
+PPFBinaryOutputStream::PutR4   (r_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_FLOAT);
+  
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(r_4));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutR8   (r_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_FLOAT);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(r_8));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutI1   (int_1 val)
+{
+  PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_INTEGER);
+  PutRawBytes(&val, sizeof(int_1));
+}
+
+void
+PPFBinaryOutputStream::PutI1s  (int_1 const* tab, size_t n)
+{
+  PutArrayTag(1, n, PPS_DATATYPE_INTEGER);
+  PutRawBytes(tab, n*sizeof(int_1));
+}
+
+void
+PPFBinaryOutputStream::PutU1   (uint_1 val)
+{
+  PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_UNSIGNED);
+  PutRawBytes(&val, sizeof(uint_1));
+}
+
+void
+PPFBinaryOutputStream::PutU1s  (uint_1 const* tab, size_t n)
+{
+  PutArrayTag(1, n, PPS_DATATYPE_UNSIGNED);
+  PutRawBytes(tab, n*sizeof(uint_1));
+}
+
+void
+PPFBinaryOutputStream::PutI2   (int_2 val)
+{
+  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(int_2));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutU2   (uint_2 val)
+{
+  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(uint_2));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutI4   (int_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(int_4));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutU4   (uint_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(uint_4));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutI8   (int_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(int_8));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutU8   (uint_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(uint_8));
+}
+
+void
+PPFBinaryOutputStream::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
+PPFBinaryOutputStream::PutStr(string const& str) 
+{
+  PutRawUByte(PPS_STRING);
+  PutRawI4(str.length());
+  PutRawBytes(str.c_str(), str.length());
+}
+
+void
+PPFBinaryOutputStream::PutLine(char const* ptr, size_t len)
+{
+  string str = ptr;
+  PutStr(str);
+}
+
+
+void
+PPFBinaryOutputStream::PutZ4   (complex<r_4> val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_COMPLEX);
+  r_4 reim[2];
+  reim[0] = val.real();
+  reim[1] = val.imag();
+  if (bigEndian != IS_BIG_ENDIAN) {
+    bswap4(reim);
+    bswap4(reim+1);
+  }
+  PutRawBytes(reim, 2*sizeof(r_4));
+}
+
+void
+PPFBinaryOutputStream::PutZ4s  (complex<r_4> const* tab, size_t n)
+{
+  PutArrayTag(4, n, PPS_DATATYPE_COMPLEX);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*2*sizeof(r_4));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      r_4 reim[2];
+      reim[0] = tab[i].real();
+      reim[1] = tab[i].imag();
+      bswap4(reim);
+      bswap4(reim+1);
+      PutRawBytes(reim, 2*sizeof(r_4));
+    }
+  }
+}
+
+void
+PPFBinaryOutputStream::PutZ8   (complex<r_8> val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_COMPLEX);
+  r_8 reim[2];
+  reim[0] = val.real();
+  reim[1] = val.imag();
+  if (bigEndian != IS_BIG_ENDIAN) {
+    bswap8(reim);
+    bswap8(reim+1);
+  }
+  PutRawBytes(reim, 2*sizeof(r_8));
+}
+
+void
+PPFBinaryOutputStream::PutZ8s  (complex<r_8> const* tab, size_t n)
+{
+  PutArrayTag(8, n, PPS_DATATYPE_COMPLEX);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*2*sizeof(r_8));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      r_8 reim[2];
+      reim[0] = tab[i].real();
+      reim[1] = tab[i].imag();
+      bswap8(reim);
+      bswap8(reim+1);
+      PutRawBytes(reim, 2*sizeof(r_8));
+    }
+  }
+}
+
+void
+PPFBinaryOutputStream::PutPosTagTable(int_8 const * ptab, size_t sz)
+{
+  PutRawUByte(PPS_POSTAG_TABLE);
+  int_4 tsz = sz;
+  PutRawI4(tsz);
+  for(int kk=0; kk<tsz; kk++)
+    PutRawI8(ptab[kk]);
+  return;
+}
+
+void
+PPFBinaryOutputStream::PutPosTagTable(vector<int_8> const& ptab)
+{
+  PutRawUByte(PPS_POSTAG_TABLE);
+  int_4 tsz = ptab.size();
+  PutRawI4(tsz);
+  for(int kk=0; kk<tsz; kk++)
+    PutRawI8(ptab[kk]);
+  return;
+}
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppfbinstream.h	(revision 3445)
@@ -0,0 +1,306 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef PPFBINSTREAM_H_SEEN
+#define PPFBINSTREAM_H_SEEN
+
+// PPF (Portable Persistence Format) Input/Output streams
+//
+// E. Aubourg     CEA DAPNIA/SPP  1999
+// R. Ansari      LAL IN2P3/CNRS  2000-2003
+
+
+#include "machdefs.h"
+#include "rawstream.h"
+
+#include <time.h>
+
+#include <complex>
+#include <string>
+#include <map>
+#include <vector>
+
+
+
+namespace SOPHYA {
+  
+class PPFBinaryIOStream {
+public:
+
+  enum  PPFByteOrdering  {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1};
+
+  // Value of item identification tags in PPF binary streams   
+  enum  PPFItemTag {
+    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_NAMETAG_TABLE = 4,    // Name tag table (Written at the end of file/stream) 
+    PPS_EOF = 5,              // Just before tag infomation, offset to PPS_TAG
+    PPS_ENDOBJECT = 6,        // marks the end of a given object information
+    PPS_NAMETAG_MARK = 7,     // To have a name tag, position marker in a file
+    PPS_POSTAG_MARK = 8,      // Position tag mark + 8 bytes (=stream position)
+    PPS_POSTAG_TABLE = 9,     // Position tag table + 8 bytes (=stream position)
+    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   PPFItemTagDataType {  
+    PPS_DATATYPE_CHAR = 0,        // 0  : DataType=character
+    PPS_DATATYPE_FLOAT = 64,      // 64 : DataType=float 
+    PPS_DATATYPE_COMPLEX = 65,    // 65 : DataType=complex 
+    PPS_DATATYPE_INTEGER = 128,   // 128 :DataType=integer 
+    PPS_DATATYPE_UNSIGNED = 192   // 192 :DataType=Unsigned integer 
+  };
+  
+  PPFBinaryIOStream();
+  virtual ~PPFBinaryIOStream();
+
+  inline int    Version() {return version;}  // PIn/OutPersist version number
+  inline time_t CreationDate() { return creationdate; }
+  string        CreationDateStr(); 
+  string        InfoString(); 
+
+  inline int_8  NbPosTags() {return _nbpostag; }
+  inline int_8  NbNameTags() {return tags.size(); }
+  inline int_8  NbObjects() {return _nbobjs; }
+  inline int_8  NbTopLevelObjects() {return _nbtlobjs; }
+  inline int_8  NbReferences() {return _nbrefs; }
+  inline int_4  MaxNestedObjsLevel() {return _maxnestlevel; }
+
+  string GetTagName(int itag);  // 0..NbTags-1
+  vector<string> const &  GetNameTags();  
+
+protected:
+  // La liste des NameTag ds le flot  
+  map<string, int_8> tags;
+  int version;     // PPersist(In/Out) version 
+  time_t creationdate;   // Date de creation du fichier
+
+  // Variables pour garder le compte des objets et des tags
+  // Le nombre d'objets a l'ecriture est mis a jour par la classe
+  // derivee POutPersist
+  int_8 _nbpostag;     // Nb de tag de positionnement
+  int_8 _nbobjs;       // Nb total d'objets
+  int_8 _nbtlobjs;     // Nb d'objets de niveau 1 
+  int_8 _nbrefs;       // Nb de references PPS_REFERENCE
+  int_4 _maxnestlevel; // Niveau maximum d'objets emboites 
+};
+  
+  
+//! Input PPF (Portable Persist Format) streams 
+class PPFBinaryInputStream : public PPFBinaryIOStream {
+public:
+  PPFBinaryInputStream(RawInOutStream * is, bool ad, bool scan=false);
+  PPFBinaryInputStream(string const& flnm, bool scan=true);
+  virtual  ~PPFBinaryInputStream();
+
+  inline string FileName() { return s->getFileName(); }   // Retourne le nom de fichier
+  
+  // Gestion des tags
+  bool   GotoPositionTag(int_8 pos);
+  bool   GotoNameTag(string const& name);
+  bool   GotoNameTagNum(int itag);  // 0..NbTags-1
+  
+  // Saut jusqu'au prochain objet 
+  bool   SkipToNextObject();
+  // Saut d'un item de base (tag+donnees correspondantes), le suivant ds le flot
+  bool   SkipNextItem();
+  // Lecture du tag de type next item + infos correspondantes
+  // Le stream est re-positionne avant le tag 
+  char   NextItemTag(short & datasz, size_t & sz);
+  
+  // Lecture donnees de base et tableaux de donnees de base
+  // Basic data type (and corresponding arrays) reading
+  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   GetI1   (int_1&);
+  void   GetI1s  (int_1*, size_t);
+  void   GetU1   (uint_1&);
+  void   GetU1s  (uint_1*, 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   GetZ4   (complex<r_4> &);
+  void   GetZ4s  (complex<r_4> *, size_t);
+  void   GetZ8   (complex<r_8> &);
+  void   GetZ8s  (complex<r_8> *, size_t);
+  
+  inline void   Get(char&   c) {GetByte(c);}
+  inline void   Get(r_4&    x) {GetR4(x);}
+  inline void   Get(r_8&    x) {GetR8(x);}
+  inline void   Get(uint_1& x) {GetU1(x);}
+  inline void   Get(int_1&  x) {GetI1(x);}
+  inline void   Get(uint_2& x) {GetU2(x);}
+  inline void   Get(int_2&  x) {GetI2(x);}
+  inline void   Get(uint_4& x) {GetU4(x);}
+  inline void   Get(int_4&  x) {GetI4(x);}
+  inline void   Get(uint_8& x) {GetU8(x);}
+  inline void   Get(int_8&  x) {GetI8(x);}
+  inline void   Get(complex<r_4> & x) {GetZ4(x);}
+  inline void   Get(complex<r_8> & x) {GetZ8(x);}
+  
+  inline void   Get(r_4*    x, size_t n) {GetR4s(x,n);}
+  inline void   Get(r_8*    x, size_t n) {GetR8s(x,n);}
+  inline void   Get(uint_1* x, size_t n) {GetU1s(x,n);}
+  inline void   Get(int_1*  x, size_t n) {GetI1s(x,n);}
+  inline void   Get(uint_2* x, size_t n) {GetU2s(x,n);}
+  inline void   Get(int_2*  x, size_t n) {GetI2s(x,n);}
+  inline void   Get(uint_4* x, size_t n) {GetU4s(x,n);}
+  inline void   Get(int_4*  x, size_t n) {GetI4s(x,n);}
+  inline void   Get(uint_8* x, size_t n) {GetU8s(x,n);}
+  inline void   Get(int_8*  x, size_t n) {GetI8s(x,n);}
+  inline void   Get(string& x) {GetStr(x);}
+  inline void   Get(complex<r_4> * x, size_t n) { GetZ4s(x, n); }
+  inline void   Get(complex<r_8> * x, size_t n) { GetZ8s(x, n); }
+  
+  // Reading a list (table) of position tags
+  void    GetPosTagTable(int_8*, size_t);
+  void    GetPosTagTable(vector<int_8>&);
+  
+  void   AnalyseTags(int lev=0);   // List (all or some) tags ...
+  
+protected:
+  void   Init(bool scan);
+  void   ReadNameTagTableV2();
+  void   ReadNameTagTable();
+
+  void   SkipItem(bool fgrdi=true, unsigned char itag=0);
+
+  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&);
+  
+  RawInOutStream* s;
+  bool _ads; // delete/close the stream at the end
+  
+  bool bigEndian;
+  // Si on a fait une lecture non sequentielle  -> seqread = false
+  bool seqread;
+};
+
+//! Output stream for PPersit objects.
+class PPFBinaryOutputStream : public PPFBinaryIOStream {
+public:
+  PPFBinaryOutputStream(RawInOutStream* os, bool ad, int endianness = PPS_NATIVE);
+  PPFBinaryOutputStream(string const& flnm, int endianness = PPS_NATIVE);
+  virtual ~PPFBinaryOutputStream();
+
+  inline string FileName() { return s->getFileName(); }   // Retourne le nom de fichier
+  
+  // Ecriture de tags
+  int_8 WritePositionTag();
+  void  WriteNameTag(string const& name);
+  inline void WriteTag(string const& name) { WriteNameTag(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 PutI1   (int_1);
+  void PutI1s  (int_1 const*, size_t);
+  void PutU1   (uint_1);
+  void PutU1s  (uint_1 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 PutZ4   (complex<r_4>);
+  void PutZ4s  (complex<r_4> const*, size_t);
+  void PutZ8   (complex<r_8>);
+  void PutZ8s  (complex<r_8> const*, size_t);
+  
+  
+  void   Put(char   c) {PutByte(c);}
+  void   Put(r_4    x) {PutR4(x);}
+  void   Put(r_8    x) {PutR8(x);}
+  void   Put(complex<r_4>   x) {PutZ4(x);}
+  void   Put(complex<r_8>   x) {PutZ8(x);}
+  void   Put(uint_1 x) {PutU1(x);}
+  void   Put(int_1  x) {PutI1(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(complex<r_4> const*    x, size_t n) {PutZ4s(x,n);}
+  void   Put(complex<r_8> const*    x, size_t n) {PutZ8s(x,n);}
+  void   Put(uint_1 const* x, size_t n) {PutU1s(x,n);}
+  void   Put(int_1 const*  x, size_t n) {PutI1s(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);}
+  
+  // Writing a list of position tag table
+  void   PutPosTagTable(int_8 const *, size_t);
+  void   PutPosTagTable(vector<int_8> const&);
+    
+  
+protected:
+  void     Init(int endianness);
+  void     WriteNameTagTable();
+  void     WriteNameTagTableV2();
+
+  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);
+
+  // Attributs, variables
+  RawInOutStream* s;
+  bool _ads; // delete/close the stream at the end
+
+  bool bigEndian;
+};
+  
+
+
+} // namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppfnametag.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppfnametag.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppfnametag.h	(revision 3445)
@@ -0,0 +1,67 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Classe PPFNameTag  - R. Ansari - Nov 2003
+//  To ease manipulation of nametags in PPF streams 
+
+#ifndef PPFNAMETAG_H_SEEN
+#define PPFNAMETAG_H_SEEN
+
+#include "ppersist.h"
+/*!
+   \class SOPHYA::PPFNameTag
+   \ingroup BaseTools
+   A simple class which can be used in conjuction with << and >> operators
+   to write nametags in POutPersist streams or position an input PInPersist
+   stream at a given nametag. 
+   Nametags are strings which can be used to identify objects for further 
+   retrieval in PPF streams.
+   Pushing a PPFNameTag(tname) to an output stream \b os corresponds to 
+   so.WriteNameTag(tname). Extracting a PPFNameTag(tname) from an input stream
+   \b is corresponds to is.GotoNameTag(tname).
+   
+   \code
+   {
+   // Writing a name tag and an object to a stream
+   NDataBlock<int_4> idb(16);
+   idb = 16;
+   POutPersist so("myfile.ppf");
+   so << PPFNameTag("MyIDB") << idb ;
+   }
+   //...
+   {
+   // Positioning and Reading from a PPF stream
+   PInPersist si("myfile.ppf");
+   NDataBlock<int_4> idb;
+   si >>  PPFNameTag("MyIDB") >> idb;
+   }
+   \endcode
+*/
+//----------------------------------------------------------------------
+namespace SOPHYA {
+//! A simple class to ease manipulation of nametags in PPF streams
+
+class PPFNameTag {
+public:
+  PPFNameTag(PPFNameTag const & ptn) { _tname = ptn._tname; }
+  PPFNameTag(string const & tn) { _tname = tn; }
+  PPFNameTag(const char * tn) { _tname = tn; }
+  ~PPFNameTag() { } 
+  inline bool GotoNameTag(PInPersist& pi) const
+  { return pi.GotoNameTag(_tname); }
+  inline void WriteTag(POutPersist& po) const
+  { po.WriteNameTag(_tname); return; }
+  inline char*  operator= (char* s) { _tname = s; return s; }
+  inline string const & operator= (string const & s)  { _tname = s; return s; } 
+  inline operator  string() const { return _tname; }
+protected:
+  string _tname; 
+};
+
+inline PInPersist& operator >> (PInPersist& si, PPFNameTag const & pnt) 
+{ pnt.GotoNameTag(si); return(si); }
+
+inline POutPersist& operator << (POutPersist& so, PPFNameTag const & pnt) 
+{ pnt.WriteTag(so); return(so); }
+
+}  // namespace SOPHYA
+
+#endif   /* PPFNAMETAG_H_SEEN */
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppfswapper.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppfswapper.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppfswapper.h	(revision 3445)
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees swapable
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef PPFSWAPPER_H
+#define PPFSWAPPER_H
+
+
+#include "machdefs.h"
+#include "swsegdb.h"
+#include "ppersist.h"
+#include "ppftpointerio.h"
+
+/*!
+  \class SOPHYA::PPFDataSwapper
+  \ingroup BaseTools
+  Implementation of SOPHYA::DataSwapperInterface interface on PPF streams 
+  (POutPersist , PInPersist) to be used with SOPHYA::SwSegDataBlock classes.
+  the identifier idx is not used in this implementation. In case of re-writing 
+  to swap, the previous position is ignored, the data is re-written to swap 
+  and a new swap position is returned.
+*/
+
+namespace SOPHYA {
+
+template <class T> 
+class PPFDataSwapper : public DataSwapperInterface<T> {
+public:
+  PPFDataSwapper() { ppfos = NULL; ppfis = NULL;}
+  PPFDataSwapper(POutPersist & os) { ppfos = &os; ppfis = NULL;}
+  PPFDataSwapper(PInPersist & is) { ppfos = NULL; ppfis = &is;}
+  PPFDataSwapper(PInPersist & is, POutPersist & os) { ppfos = &os; ppfis = &is;}
+
+  inline PInPersist & InStream() { return *ppfis; }
+  inline POutPersist & OutStream() { return *ppfos; }
+  inline void SetInStream(PInPersist & is) { ppfis = &is; }
+  inline void SetOutStream(POutPersist & os) { ppfos = &os; }
+
+  // Operateur = , on recopie les pointeurs des streams 
+  inline PPFDataSwapper<T>& operator = (PPFDataSwapper<T> const & a) 
+  { ppfis = a.ppfis;  ppfos = a.ppfos; return *this; }
+
+  virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false)
+  {
+    if (ppfos == NULL) 
+      throw NotAvailableOperation("PPFDataSwapper<T>::WriteToSwap() - No POutPersist stream !");
+    int_8 tag = ppfos->WritePositionTag();
+    PPF_TPointer_IO<T>::Write(*ppfos, d, sz);
+    return tag;
+  }
+  virtual void  ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz)
+  {
+    if (ppfis == NULL) 
+      throw NotAvailableOperation("PPFDataSwapper<T>::ReadFromSwap() - No PInPersist stream !");
+    bool ok = ppfis->GotoPositionTag(swp);
+    PPF_TPointer_IO<T>::Read(*ppfis, d, sz);
+    return;
+  }
+  virtual DataSwapperInterface<T>* Clone()
+  {
+    PPFDataSwapper<T> * rsw = new PPFDataSwapper<T> ;
+    (*rsw) = *this; 
+    return rsw;
+  }
+protected:
+  POutPersist* ppfos;
+  PInPersist* ppfis;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.cc	(revision 3445)
@@ -0,0 +1,117 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Classe pour faciliter entree-sortie PPF pour des pointeurs
+//  Implementation specifique pour certains type de pointeurs
+//       R. Ansari -  Mars 2005
+
+#include "machdefs.h"
+#include "ppftpointerio.h"
+
+namespace SOPHYA {
+
+//----------------------------------------------------------------------
+//! \cond
+// Specific implementation using table I/O in PPFBinaryIOStreams 
+/* DECL_TEMP_SPEC   equivalent a template <> , pour SGI-CC en particulier */
+void PPF_TPointer_IO<char>::Write(POutPersist & os, char const * arr, size_t n)
+  { os.PutBytes(arr,n); }
+void PPF_TPointer_IO<char>::Read(PInPersist & is, char * arr, size_t n)
+  { is.GetBytes(arr,n); }
+
+void PPF_TPointer_IO< int_1 >::Write(POutPersist & os, int_1 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_1 >::Read(PInPersist & is, int_1 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< uint_1 >::Write(POutPersist & os, uint_1 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_1 >::Read(PInPersist & is, uint_1 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_2 >::Write(POutPersist & os, int_2 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_2 >::Read(PInPersist & is, int_2 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< uint_2 >::Write(POutPersist & os, uint_2 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_2 >::Read(PInPersist & is, uint_2 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_4 >::Write(POutPersist & os, int_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_4 >::Read(PInPersist & is, int_4 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< uint_4 >::Write(POutPersist & os, uint_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_4 >::Read(PInPersist & is, uint_4 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< int_8 >::Write(POutPersist & os,  int_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< int_8 >::Read(PInPersist & is, int_8 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< uint_8 >::Write(POutPersist & os,  uint_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< uint_8 >::Read(PInPersist & is, uint_8 * arr, size_t n)
+  { is.Get(arr,n); }
+
+
+void PPF_TPointer_IO< r_4 >::Write(POutPersist & os, r_4 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< r_4 >::Read(PInPersist & is, r_4 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< r_8 >::Write(POutPersist & os,  r_8 const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< r_8 >::Read(PInPersist & is, r_8 * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< complex<r_4> >::Write(POutPersist & os, complex<r_4> const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< complex<r_4> >::Read(PInPersist & is, complex<r_4> * arr, size_t n)
+  { is.Get(arr,n); }
+
+void PPF_TPointer_IO< complex<r_8> >::Write(POutPersist & os, complex<r_8> const * arr, size_t n)
+  { os.Put(arr,n); }
+void PPF_TPointer_IO< complex<r_8> >::Read(PInPersist & is, complex<r_8> * arr, size_t n)
+  { is.Get(arr,n); }
+
+//! \endcond
+
+/*
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template PPF_TPointer_IO< char >
+#pragma define_template PPF_TPointer_IO< int_1 >
+#pragma define_template PPF_TPointer_IO< uint_1 >
+#pragma define_template PPF_TPointer_IO< int_2 >
+#pragma define_template PPF_TPointer_IO< uint_2 >
+#pragma define_template PPF_TPointer_IO< int_4 >
+#pragma define_template PPF_TPointer_IO< uint_4 >
+#pragma define_template PPF_TPointer_IO< int_8 >
+#pragma define_template PPF_TPointer_IO< uint_8 >
+#pragma define_template PPF_TPointer_IO< r_4 >
+#pragma define_template PPF_TPointer_IO< r_8 >
+#pragma define_template PPF_TPointer_IO< complex<r_4> >
+#pragma define_template PPF_TPointer_IO< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class PPF_TPointer_IO< char >;
+template class PPF_TPointer_IO< int_1 >;
+template class PPF_TPointer_IO< uint_1 >;
+template class PPF_TPointer_IO< int_2 >;
+template class PPF_TPointer_IO< uint_2 >;
+template class PPF_TPointer_IO< int_4 >;
+template class PPF_TPointer_IO< uint_4 >;
+template class PPF_TPointer_IO< int_8 >;
+template class PPF_TPointer_IO< uint_8 >;
+template class PPF_TPointer_IO< r_4 >;
+template class PPF_TPointer_IO< r_8 >;
+template class PPF_TPointer_IO< complex<r_4> >;
+template class PPF_TPointer_IO< complex<r_8> >;
+#endif
+*/
+
+}  // namespace SOPHYA
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppftpointerio.h	(revision 3445)
@@ -0,0 +1,129 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Classe pour faciliter entree-sortie PPF pour des pointeurs
+//       R. Ansari -  Mars 2005
+
+#ifndef PPFTPOINTERIO_H_SEEN
+#define PPFTPOINTERIO_H_SEEN
+
+#include "ppersist.h"
+
+//----------------------------------------------------------------------
+/*!
+  \class SOPHYA::PPF_TPointer_IO
+  \ingroup BaseTools
+  A template utility class with static methods to ease handling of array 
+  I/O in PPF streams (POutPersist and PInPersist). It is not intented for
+  direct use in user programs, but for writing PPF persistence handler 
+  classes (PPersist). 
+  The C++ I/O operators POutPersist& << and PInPersist& >> should be defined for
+  new types and classes.
+*/
+
+namespace SOPHYA {
+
+template <class T>
+class PPF_TPointer_IO {
+public:
+  //! Writes the array pointed to by \b arr (size \b n) to POutPersist stream \b os
+  static void Write(POutPersist & os,  T  const * arr, size_t n)
+  {
+    for(size_t k=0; k<n; k++) os << arr[k];
+  }
+  //! Reads from the PInPersist \b is into array pointed to by \b arr (size \b n)
+  static void Read(PInPersist & is, T * arr, size_t n)
+  {
+    for(size_t k=0; k<n; k++) is >> arr[k];
+  }
+};
+
+//! \cond
+// declaration specifique pour ecriture sous forme de tableaux PPF
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<char> {
+public:
+  static void Write(POutPersist & os,  char  const * arr, size_t n);
+  static void Read(PInPersist & is, char * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<int_1> {
+public:
+  static void Write(POutPersist & os,  int_1  const * arr, size_t n);
+  static void Read(PInPersist & is, int_1 * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<uint_1> {
+public:
+  static void Write(POutPersist & os,  uint_1  const * arr, size_t n);
+  static void Read(PInPersist & is, uint_1 * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<int_2> {
+public:
+  static void Write(POutPersist & os,  int_2  const * arr, size_t n);
+  static void Read(PInPersist & is, int_2 * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<uint_2> {
+public:
+  static void Write(POutPersist & os,  uint_2  const * arr, size_t n);
+  static void Read(PInPersist & is, uint_2 * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<int_4> {
+public:
+  static void Write(POutPersist & os,  int_4  const * arr, size_t n);
+  static void Read(PInPersist & is, int_4 * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<uint_4> {
+public:
+  static void Write(POutPersist & os,  uint_4  const * arr, size_t n);
+  static void Read(PInPersist & is, uint_4 * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<int_8> {
+public:
+  static void Write(POutPersist & os,  int_8  const * arr, size_t n);
+  static void Read(PInPersist & is, int_8 * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<uint_8> {
+public:
+  static void Write(POutPersist & os,  uint_8  const * arr, size_t n);
+  static void Read(PInPersist & is, uint_8 * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<r_4> {
+public:
+  static void Write(POutPersist & os,  r_4  const * arr, size_t n);
+  static void Read(PInPersist & is, r_4 * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO<r_8> {
+public:
+  static void Write(POutPersist & os,  r_8  const * arr, size_t n);
+  static void Read(PInPersist & is, r_8 * arr, size_t n);
+};
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO< complex<r_4> > {
+public:
+  static void Write(POutPersist & os,  complex<r_4>  const * arr, size_t n);
+  static void Read(PInPersist & is, complex<r_4> * arr, size_t n);
+};
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+class PPF_TPointer_IO< complex<r_8> > {
+public:
+  static void Write(POutPersist & os,  complex<r_8>  const * arr, size_t n);
+  static void Read(PInPersist & is, complex<r_8> * arr, size_t n);
+};
+
+//! \endcond
+}  // namespace SOPHYA
+
+#endif   /* PPFTPOINTERIO_H_SEEN */
Index: /tags/V_Nov2007/SophyaLib/BaseTools/ppfwrapstlv.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/ppfwrapstlv.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/ppfwrapstlv.h	(revision 3445)
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour la permettre la persistance PPF des vecteurs STL
+//                         R. Ansari - Avril 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PPFWRAPSTLV_H
+#define PPFWRAPSTLV_H
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include "ppersist.h"
+#include "pexceptions.h"
+#include <vector>
+#include <iostream>
+
+/*!
+   \class SOPHYA::PPFWrapperSTLVector
+   \ingroup BaseTools
+   Class for managing PPF persistence of standard (STL) vectors.
+   Only the overloaded operators I/O operators on POutPersist
+   and PInPersist streams are intended to be used in user programs.
+   When applied to vectors of user defined types and classes (\b T), the 
+   c++ I/O operators POutPersist& << and PInPersist& >> should be 
+   defined for the type \b T and the resulting handler must be registered
+   using the macro \b PPRegister(PPFWrapperSTLVector<T>)
+*/
+
+namespace SOPHYA {
+
+   
+template <class T>
+class PPFWrapperSTLVector : public  PPersist , public AnyDataObj {
+public:
+  PPFWrapperSTLVector()
+  {
+    dobj = new std::vector<T> ;
+    ownobj=true;    
+  }
+
+  //   PPFWrapperSTLVector(string const & filename);
+  PPFWrapperSTLVector(std::vector<T> & obj)
+  {
+    dobj = &obj;
+    ownobj = false;
+  }
+
+  PPFWrapperSTLVector(std::vector<T> * obj)
+  {
+    if (obj == NULL)  
+      throw ParmError("PPFWrapperSTLVector<T>::PPFWrapperSTLVector(* obj) obj=NULL (ppfwrapstlv.h)");
+    dobj = obj;
+    ownobj = false;
+  }
+  virtual ~PPFWrapperSTLVector()
+  {
+    if (ownobj && dobj) delete dobj;
+  }
+  virtual AnyDataObj* DataObj() { return this; }
+  virtual void        SetDataObj(AnyDataObj & o)
+  {
+    throw NotAvailableOperation("PPFWrapperSTLVector<T>::SetDataObj() Not permitted ! (ppfwrapstlv.h)");
+  }
+  inline operator std::vector<T>()  { return(*dobj); }
+
+protected :
+  virtual void       ReadSelf(PInPersist& is)
+  {
+    if (dobj == NULL) 
+      throw ParmError("PPFWrapperSTLVector<T>::ReadSelf() dobj=NULL (ppfwrapstlv.h)");
+    // On lit les 3 premiers uint_8
+    uint_8 itab[3];
+    is.Get(itab, 3);
+    // On efface le contenu du vecteur si necessaire - (on peut faire plus efficacement ...)
+    if ( dobj->size() > 0) dobj->erase(dobj->begin(), dobj->end());
+    T el;
+    for(uint_8 k=0; k<itab[1]; k++) { 
+      is >> el;
+      dobj->push_back(el);
+    }
+  }         
+  virtual void       WriteSelf(POutPersist& os) const
+  {
+    if (dobj == NULL) 
+      throw ParmError("PPFWrapperSTLVector<T>::WriteSelf() dobj=NULL (ppfwrapstlv.h)");
+    //  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 vecteur de donnees 
+    for(uint_8 k=0; k<itab[1]; k++) os << (*dobj)[k];
+  }
+
+  // Variables membres 
+  std::vector<T> * dobj;  // Le vecteur de la STL 
+  bool ownobj;  // true -> objet cree par le wrapper 
+};
+
+/*! Writes the STL vector object in the POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, std::vector<T> & obj)
+{ PPFWrapperSTLVector<T> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads in and initializes the STL vector object from the PInPersist stream \b is */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, std::vector<T> & obj)
+{ PPFWrapperSTLVector<T> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.cc	(revision 3445)
@@ -0,0 +1,213 @@
+#include "sopnamsp.h"
+#include "rawstream.h"
+#include "pexceptions.h"
+
+/*!
+   \class SOPHYA::RawInOutStream
+   \ingroup BaseTools
+   This class defines the interface for a raw input/output stream.
+   It has been designed primarily to be used by PPF streams 
+   (Sophya Persistence).
+*/
+
+/* --Methode-- */
+RawInOutStream::RawInOutStream()
+{
+}
+
+/* --Methode-- */
+RawInOutStream::~RawInOutStream()
+{
+}
+
+/* --Methode-- */
+bool  RawInOutStream::isSeekable() const
+{
+  return false;
+}
+
+/* --Methode-- */
+int_8 RawInOutStream::tellg()
+{
+  throw NotAvailableOperation("RawInOutStream::tellg() - Not implemented ");
+}
+
+/* --Methode-- */
+RawInOutStream& RawInOutStream::seekg(int_8, int)
+{ 
+  throw NotAvailableOperation("RawInOutStream::seekg() - Not implemented ");
+}
+
+/* --Methode-- */
+RawInOutStream& RawInOutStream::read(char* s, uint_8 n)
+{
+  throw NotAvailableOperation("RawInOutStream::read() - Not implemented ");
+}
+/* --Methode-- */
+int_8 RawInOutStream::tellp()
+{
+  throw NotAvailableOperation("RawInOutStream::tellp() - Not implemented ");
+}
+
+/* --Methode-- */
+RawInOutStream& RawInOutStream::seekp(int_8, int)
+{ 
+  throw NotAvailableOperation("RawInOutStream::seekp() - Not implemented ");
+}
+
+/* --Methode-- */
+RawInOutStream& RawInOutStream::write(const char* s, uint_8 n)
+{
+  throw NotAvailableOperation("RawInOutStream::write() - Not implemented ");
+}
+
+
+/*!
+   \class SOPHYA::RawInFileStream
+   \ingroup BaseTools
+   Implements the input interface (reading) of  RawInOutStream
+   on a disk file using the standard C library (fopen, fread, ...)
+*/
+
+/* --Methode-- */
+RawInFileStream::RawInFileStream(const char * path) 
+  : RawInOutStream()
+{
+  fip = fopen(path,"rb");
+  if (fip == NULL) { 
+    string errmsg = "RawInFileStream() - fopen(rb) ERROR - File= ";
+    errmsg += path;
+    throw IOExc(errmsg);
+  }
+  _filename = path;
+}
+
+/* --Methode-- */
+RawInFileStream::RawInFileStream(string const & path)
+  : RawInOutStream()
+{
+  fip = fopen(path.c_str(),"rb");
+  if (fip == NULL) { 
+    string errmsg = "RawInFileStream() - fopen(rb) ERROR - File= ";
+    errmsg += path;
+    throw IOExc(errmsg);
+  }
+  _filename = path;
+}
+
+/* --Methode-- */
+RawInFileStream::~RawInFileStream()
+{
+  fclose(fip);
+}
+
+
+/* --Methode-- */
+bool  RawInFileStream::isSeekable() const
+{
+  return true;
+}
+
+/* --Methode-- */
+int_8 RawInFileStream::tellg()
+{
+  return ftell(fip) ;
+}
+
+/* --Methode-- */
+RawInOutStream& RawInFileStream::seekg(int_8 off, int dir)
+{ 
+  int fsd = SEEK_SET;
+  if (dir == ios::beg)  fsd = SEEK_SET;
+  else if (dir == ios::end)  fsd = SEEK_END;
+  else fsd = SEEK_CUR;
+  fseek(fip, (long int)off, fsd);
+  return (*this);
+}
+
+/* --Methode-- */
+RawInOutStream& RawInFileStream::read(char* s, uint_8 n)
+{
+  size_t rc = fread((void *)s, 1, (size_t)n, fip);
+  if (rc !=  (size_t)n) {
+    string errmsg = "RawInFileStream::read() ERROR - File= ";
+    errmsg += _filename;
+    throw IOExc(errmsg);
+  }
+  return (*this);
+}
+
+/*!
+   \class SOPHYA::RawOutFileStream
+   \ingroup BaseTools
+   Implements the output interface (writing) of  RawInOutStream
+   on a disk file using the standard C library (fopen, fwrite, ...)
+*/
+
+/* --Methode-- */
+RawOutFileStream::RawOutFileStream(const char * path) 
+  : RawInOutStream()
+{
+  fip = fopen(path,"wb");
+  if (fip == NULL) { 
+    string errmsg = "RawOutFileStream() - fopen(wb) ERROR - File= ";
+    errmsg += path;
+    throw IOExc(errmsg);
+  }
+  _filename = path;
+}
+
+/* --Methode-- */
+RawOutFileStream::RawOutFileStream(string const & path)
+  : RawInOutStream()
+{
+  fip = fopen(path.c_str(),"wb");
+  if (fip == NULL) { 
+    string errmsg = "RawOutFileStream() - fopen(wb) ERROR - File= ";
+    errmsg += path;
+    throw IOExc(errmsg);
+  }
+   _filename = path;
+}
+
+/* --Methode-- */
+RawOutFileStream::~RawOutFileStream()
+{
+  fclose(fip);
+}
+
+
+/* --Methode-- */
+bool  RawOutFileStream::isSeekable() const
+{
+  return true;
+}
+
+/* --Methode-- */
+int_8 RawOutFileStream::tellp()
+{
+  return ftell(fip) ;
+}
+
+/* --Methode-- */
+RawInOutStream& RawOutFileStream::seekp(int_8 off, int dir)
+{ 
+  int fsd = SEEK_SET;
+  if (dir == ios::beg)  fsd = SEEK_SET;
+  else if (dir == ios::end)  fsd = SEEK_END;
+  else fsd = SEEK_CUR;
+  fseek(fip, (long int)off, fsd);
+  return (*this);
+}
+
+/* --Methode-- */
+RawInOutStream& RawOutFileStream::write(const char* s, uint_8 n)
+{
+  size_t rc = fwrite((void *)s, 1, (size_t)n, fip);
+  if (rc !=  (size_t)n) {
+    string errmsg = "RawOutFileStream::write() ERROR - File= ";
+    errmsg += _filename;
+    throw IOExc(errmsg);
+  }
+  return (*this);
+}
Index: /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/rawstream.h	(revision 3445)
@@ -0,0 +1,73 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef RAWSTREAM_H_SEEN
+#define RAWSTREAM_H_SEEN
+
+// Classe de flot brut - pour utilisation par les streams PPersist
+// R. Ansari      LAL IN2P3/CNRS  11/2003
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <iostream>
+#include <string>
+
+
+namespace SOPHYA {
+class RawInOutStream {
+public:
+                      RawInOutStream();
+  virtual             ~RawInOutStream();
+
+  virtual bool        isSeekable() const ;
+  // Interface pour lecture 
+  virtual int_8       tellg();
+  virtual RawInOutStream& seekg(int_8, int sd = ios::beg);
+  virtual RawInOutStream& read(char* s, uint_8 n);
+  // Interface pour ecriture 
+  virtual int_8       tellp();
+  virtual RawInOutStream& seekp(int_8, int sd = ios::beg);
+  virtual RawInOutStream& write(const char* s, uint_8 n);
+  inline  std::string     getFileName() const { return _filename; }
+protected:
+  std::string _filename;
+
+};
+
+// Input flow on a disk file 
+class RawInFileStream : public RawInOutStream {
+public:
+                      RawInFileStream(const char * path);
+                      RawInFileStream(string const & path);
+  virtual             ~RawInFileStream();
+
+  virtual bool        isSeekable() const ;
+  // Interface pour lecture 
+  virtual int_8       tellg();
+  virtual RawInOutStream& seekg(int_8, int sd = ios::beg);
+  virtual RawInOutStream& read(char* s, uint_8 n); 
+
+protected:
+  FILE * fip;
+};
+
+// Output flow on a disk file 
+class RawOutFileStream : public RawInOutStream {
+public:
+                      RawOutFileStream(const char * path);
+                      RawOutFileStream(string const & path);
+  virtual             ~RawOutFileStream();
+
+  virtual bool        isSeekable() const ;
+  // Interface pour ecriture 
+  virtual int_8       tellp();
+  virtual RawInOutStream& seekp(int_8 pos, int sd = ios::beg);
+  virtual RawInOutStream& write(const char* s, uint_8 n);
+
+protected:
+  FILE * fip;
+};
+
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/rcptr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/rcptr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/rcptr.h	(revision 3445)
@@ -0,0 +1,125 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef RCPTR_H
+#define RCPTR_H
+
+/*!
+  \class RCPtr
+  \ingroup BaseTools
+  This implements a very simple "smart pointer" with reference counting.
+  Many refinements are possible
+  Eric Aubourg  1999   CEA/DAPNIA/SPP
+
+  \verbatim
+  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 *.
+  \endverbatim
+*/
+
+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 class
+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_Nov2007/SophyaLib/BaseTools/segdatablock.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/segdatablock.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/segdatablock.h	(revision 3445)
@@ -0,0 +1,300 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees avec partage de references
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef SEGDATABLOCK_H
+#define SEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include <string.h> 
+#include <vector>
+#include <iostream>
+#include <iomanip>
+#include <typeinfo>
+
+#include "thsafeop.h"  //  for ThreadSafe operations (Ref.Count/Share) 
+
+/*!
+   \class SOPHYA::SegDBInterface
+   \ingroup BaseTools
+   Interface definition for segmented data container (template class).
+*/
+/*!
+   \class SOPHYA::SegDataBlock
+   \ingroup BaseTools
+   Template class impementing segmented data container in memory with 
+   management of reference sharing. 
+*/
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+//// ---------------- Class SegDBInterface ------------------ //
+//// ----------------- Class SegDataBlock ------------------- //
+////////////////////////////////////////////////////////////////
+
+template <class T>
+class SegDBInterface : public AnyDataObj {
+public:
+  virtual ~SegDBInterface() {}
+  //! Changes the data segment size and reallocates the memory segments
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0) = 0;
+  //! Alias for SetSize()
+  inline void  ReSize(size_t segsz, size_t nbseg=0) { SetSize(segsz, nbseg); }
+  //! Adds one segment to the data structure - returns the new number of segments.
+  virtual size_t Extend() = 0;
+  //! Return the segment size data structure
+  virtual  size_t SegmentSize() const = 0; 
+  //! Return the number of data segments
+  virtual size_t NbSegments() const = 0;
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return  SegmentSize()*NbSegments(); }
+  //! Return the pointer to data segment \b k
+  virtual T* GetSegment(size_t k) = 0;   
+  //! Return the const (read-only) pointer to data segment \b k      
+  virtual T const * GetCstSegment(size_t k) const = 0; 
+};
+
+
+// classe de container avec partage de reference
+template <class T>
+class SegDataBlock : public SegDBInterface<T> {
+
+public:
+
+  //! Default constructor - optional specification of segment size and number of segments
+  explicit SegDataBlock(size_t segsz=32, size_t nbseg=0)
+  {
+    mSRef = NULL;
+    SetSize(segsz, nbseg);
+  }
+  //! copy constructor - shares the data
+  SegDataBlock(const SegDataBlock<T>& a)
+  {
+    a.mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef = a.mSRef;
+    mSRef->nref++;
+    a.mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+  }
+  //! copy constructor with specification of flags for data sharing and element value copy
+  SegDataBlock(const SegDataBlock<T>& a, bool share, bool cpval=true)
+  {
+    if (share) {
+      a.mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+      mSRef = a.mSRef;
+      mSRef->nref++;
+      a.mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    }
+    else {
+      mSRef = NULL;
+      Clone(a, cpval);
+    }
+  }
+  //! copy constructor - shares the data if \b is a SegDataBlock, clones otherwise
+  SegDataBlock(const SegDBInterface<T>& a)
+  {
+    SegDataBlock<T> * sdb = dynamic_cast< SegDataBlock<T> *>(&a);
+    if (sdb != NULL) { 
+      sdb->mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+      mSRef = sdb->mSRef;
+      mSRef->nref++;
+      sdb->mSRefg->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    }
+    else Clone(a, true);
+  }
+  //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
+  virtual ~SegDataBlock()
+  {
+    //DEL    cout << " DEBUG-~SegDataBlock() " << hex << mSRef << dec << " NRef()= " << NRef() << endl;
+    Delete();
+  }
+
+
+  //! Adds one segment to the data structure - returns the number of allocated segments.
+  virtual size_t Extend()
+  {
+    T * p = new T[mSRef->segsize];
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->dseg.push_back(p);
+    size_t rs = mSRef->dseg.size();
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    return( rs );
+  }
+
+  //! Changes the data segment size and reallocates the memory segments
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0)
+  {
+    Delete();
+    mSRef = new SDREF;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->nref = 1;
+    mSRef->segsize = segsz;
+    mSRef->dsid = AnyDataObj::getUniqueId();
+    for(size_t k=0; k<nbseg; k++) Extend_P();
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+  }
+//! Shares the data between two SegDataBlock objects
+  void Share(const SegDataBlock<T>& a)
+  {
+    Delete();
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef = a.mSRef;
+    mSRef->nref++;
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+  }
+
+//! Makes a clone of the data structure and optionaly copie the data 
+  void Clone(const SegDBInterface<T> & a, bool cpval=true)
+  {
+    Delete();
+    mSRef = new SDREF;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->nref = 1;
+    mSRef->segsize = a.SegmentSize();
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    for(size_t k=0; k<a.NbSegments(); k++) {
+      Extend();
+      if (cpval) {
+	T * dst = GetSegment(k);
+	const T * src = a.GetCstSegment(k);
+	memcpy(dst, src, mSRef->segsize*sizeof(T));
+      }
+    }   
+  }
+
+
+  //! Return the segment size of the data structure
+  virtual size_t SegmentSize() const  { return mSRef->segsize; }
+  //! Return the number of data segments
+  virtual size_t NbSegments() const  { return mSRef->dseg.size(); }
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return mSRef->segsize*mSRef->dseg.size(); }
+
+  //! Return the pointer to data segment \b k      
+  virtual T* GetSegment(size_t k)              { return mSRef->dseg[k]; } 
+  //! Return the const (read-only) pointer to data segment \b k      
+  virtual T const * GetCstSegment(size_t k) const { return mSRef->dseg[k]; } 
+
+  //! Return the segment index for  element \b i
+  inline size_t SegIndex(size_t i) {  return i/mSRef->segsize; }
+  //! Return the offset (in data segment)  for  element \b i
+  inline size_t EltOffset(size_t i) {  return i%mSRef->segsize; }
+
+  //! Return the \b i th element of the segmented data structure   
+  inline T& operator()(size_t i)       { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of  the data structure
+  inline T& operator()(size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of the segmented data structure   
+  inline T& operator[](size_t i)       { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+  //! Return the \b i th element of  the data structure
+  inline T& operator[](size_t i) const { return *(mSRef->dseg[SegIndex(i)]+EltOffset(i));}
+
+
+  //! Return the number of references to the data structure
+  inline size_t NRef() const { return mSRef->nref; }
+
+  //! Equal operator. Set all element values to \b v 
+  SegDataBlock<T>& operator = (T const & v)
+  {
+    for(size_t k=0; k<NbSegments(); k++) {
+      T * p = mSRef->dseg[k];
+      for(size_t j=0; j<SegmentSize(); j++) p[j] = v;
+    }
+    return (*this);
+  }
+  //! Equal operator. Clones and copie values from \b a
+  inline SegDataBlock<T>& operator = (const SegDBInterface<T> & a)
+  {
+    Clone(a, true);
+    return (*this);
+  }
+  //! Equal operator. Clones and copie values from \b a
+  inline SegDataBlock<T>& operator = (const SegDataBlock<T> & a)
+  {
+    Clone(a, true);
+    return (*this);
+  }
+
+  //! ASCII formatted output (print)
+  void Print(ostream& os, int lev=0, const char * sep=NULL) const
+  {
+    os << "SegDataBlock< " << typeid(T).name() << "> mSRef= " << hex << mSRef
+       << " NRef=" << dec << NRef() << " DSId= " <<  DRefId() << endl;
+    os << " ... SegSize= " << SegmentSize() << " NbSeg= " << NbSegments() 
+       << "  Size= " << Size() << endl;
+    if (sep == NULL) sep = "  ";
+    if (lev > 0) {  
+      for(size_t k=0; k<NbSegments(); k++) {
+	T * p = mSRef->dseg[k];
+	os << " ..... DataSeg[ " << k << " ] : " << hex << p << dec << endl;
+	if (lev > 1) 
+	  for(size_t j=0; j<SegmentSize(); j++)  os << p[j] << sep;
+	os << endl;     
+      }
+    }
+  }
+  //! ASCII formatted output (print) on cout
+  inline void Print(int lev=0, const char * sep=NULL) const
+  {
+    Print(cout, lev, sep);
+  }
+
+  //! Returns the unique object identifier 
+  inline uint_8 DRefId() const { return ((mSRef)?mSRef->dsid:0); }
+
+protected:
+  //! NON-thread safe: Decrement the number of reference counts, and free the memory if NRef=0
+  void Delete() 
+  {
+    if (mSRef == NULL) return;
+    mSRef->gThsop.lock();
+    mSRef->nref--;
+    if (mSRef->nref > 0)  { 
+     mSRef->gThsop.unlock();
+     mSRef = NULL; 
+      return; 
+    }
+    //DEL cout << " DEBUG-SegDataBlock::Delete() NbSegments() = " << NbSegments() << endl;
+    for(size_t k=0; k<NbSegments(); k++) {
+      delete[] mSRef->dseg[k];
+      mSRef->dseg[k] = NULL;
+    }
+    mSRef->gThsop.unlock();
+    delete mSRef;
+    mSRef = NULL;
+  }
+  //! NON-thread safe, version of Extend() : Adds one segment to the data structure 
+  size_t Extend_P()
+  {
+    T * p = new T[mSRef->segsize];
+    mSRef->dseg.push_back(p);
+    return( mSRef->dseg.size());
+  }
+
+  /*! \cond 
+    SDREF structure for reference management - for internal use by SegDataBlock
+  */
+  typedef struct {
+    size_t nref;      // Number of references to the data structure
+    uint_8 dsid;      // Data structure Id - Used by FIO_SegDataBlock
+    std::vector<T *> dseg;
+    size_t segsize;
+    ThSafeOp gThsop;  // Mutex for thread safe operation 
+  } SDREF;
+  /*! \endcond */
+  SDREF *  mSRef;    //!< SDREF structure for reference sharing
+
+};
+
+
+//! Definition of operator \<\< for ascii formatted output of SegDataBlock
+template<class T> 
+inline ostream& operator << (ostream& os, const SegDataBlock<T>& a)
+  {  a.Print(os); return(os); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/BaseTools/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/smakefile	(revision 3445)
@@ -0,0 +1,91 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libBaseTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dvlist.o $(SOPHYAOBJP)fiondblock.o $(SOPHYAOBJP)mutyv.o $(SOPHYAOBJP)ndatablock.o $(SOPHYAOBJP)pexceptions.o $(SOPHYAOBJP)ppersist.o $(SOPHYAOBJP)ppfbinstream.o $(SOPHYAOBJP)ppftpointerio.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)srandgen.o
+	rm -f $(SOPHYALIBP)libBaseTools.a
+ 
+$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dvlist.o $(SOPHYAOBJP)fiondblock.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)mutyv.o $(SOPHYAOBJP)ndatablock.o $(SOPHYAOBJP)pexceptions.o $(SOPHYAOBJP)ppersist.o $(SOPHYAOBJP)ppfbinstream.o $(SOPHYAOBJP)ppftpointerio.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)srandgen.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)datatype.o: datatype.cc datatype.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatype.cc
+ 
+$(SOPHYAOBJP)dvlist.o: dvlist.cc $(SOPHYAINCP)machdefs.h \
+  dvlist.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h mutyv.h timestamp.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dvlist.cc
+ 
+$(SOPHYAOBJP)fiondblock.o: fiondblock.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  datatype.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiondblock.cc
+ 
+$(SOPHYAOBJP)mutyv.o: mutyv.cc sopnamsp.h mutyv.h \
+  $(SOPHYAINCP)machdefs.h timestamp.h objfio.h \
+  anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mutyv.cc
+ 
+$(SOPHYAOBJP)ndatablock.o: ndatablock.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  ndatablock.h anydataobj.h thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ndatablock.cc
+ 
+$(SOPHYAOBJP)pexceptions.o: pexceptions.cc sopnamsp.h pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pexceptions.cc
+ 
+$(SOPHYAOBJP)ppersist.o: ppersist.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h \
+  ppersist.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppersist.cc
+ 
+$(SOPHYAOBJP)ppfbinstream.o: ppfbinstream.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ppfbinstream.h \
+  rawstream.h pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppfbinstream.cc
+ 
+$(SOPHYAOBJP)ppftpointerio.o: ppftpointerio.cc \
+  $(SOPHYAINCP)machdefs.h ppftpointerio.h \
+  ppersist.h pexceptions.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppftpointerio.cc
+ 
+$(SOPHYAOBJP)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rawstream.cc
+ 
+$(SOPHYAOBJP)sophyainit.o: sophyainit.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h sophyainit.h \
+  pexceptions.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h fiondblock.h ndatablock.h anydataobj.h dvlist.h objfio.h \
+  mutyv.h timestamp.h stsrand.h fiosegdb.h segdatablock.h thsafeop.h \
+  ppftpointerio.h ppfwrapstlv.h sversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sophyainit.cc
+ 
+$(SOPHYAOBJP)stsrand.o: stsrand.cc stsrand.h \
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h \
+  ppersist.h pexceptions.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h ndatablock.h thsafeop.h fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  stsrand.cc
+ 
+$(SOPHYAOBJP)timestamp.o: timestamp.cc $(SOPHYAINCP)machdefs.h \
+  timestamp.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timestamp.cc
+ 
+$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h \
+  bithelp.h gnumd5.h
+	$(CCOMPILE) -o $@  gnumd5.c
+ 
+$(SOPHYAOBJP)srandgen.o: srandgen.c $(SOPHYAINCP)machdefs.h \
+  srandgen.h smathconst.h
+	$(CCOMPILE) -o $@  srandgen.c
+ 
Index: /tags/V_Nov2007/SophyaLib/BaseTools/smathconst.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/smathconst.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/smathconst.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/BaseTools/sophyainit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/sophyainit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/sophyainit.cc	(revision 3445)
@@ -0,0 +1,280 @@
+#include "sopnamsp.h"
+#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 "stsrand.h"
+
+#include "fiosegdb.h" 
+#include "ppfwrapstlv.h" 
+
+#include "sversion.h"
+
+#include <iostream>
+#include <map> 
+
+// ---  Classe d'initialisation de SOPHYA, (PPersistMgr en particulier)
+int SophyaInitiator::FgInit = 0;
+// Module version number - 2.0 , Jul 2006
+// Module version number - 2.02 , Fev07 Ajout NDataBlock::RenewObjId()
+// Module version number - 2.1 ,  Avr07 
+//  - Nettoyage machdefs_mkmf.h 
+//  - Ajout classe ThSafeOp ---> NDataBlock<T> Sw/SegDataBlock<T> ThreadSafe
+//     
+#define MOD_VERS   2.1
+
+// Pour garder la liste des modules et leurs numeros de version
+map<string, double>* ModListP = NULL;
+
+/*!
+   \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();
+  ModListP = new map<string, double>;
+  
+
+  // Initialisation des mecanismes PPF I/O 
+  PIOPersist::Initialize();
+  // Enregistrement des handlers PPF pour les NDataBlock<T> 
+  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> >);
+
+  // Enregistrement des handlers PPF pour les TimeStamp
+  PPRegister(ObjFileIO<TimeStamp>);
+  DObjRegister(ObjFileIO<TimeStamp>, TimeStamp);
+
+  // Enregistrement des handlers PPF pour les DVList
+  PPRegister(ObjFileIO<DVList>);
+  DObjRegister(ObjFileIO<DVList>, DVList);
+
+  // Enregistrement des handlers PPF pour les RandomGenerator
+  PPRegister(ObjFileIO<RandomGenerator>);
+  DObjRegister(ObjFileIO<RandomGenerator>, RandomGenerator);
+
+  // Enregistrement des handlers PPF pour les SegDataBlock<T> 
+  PPRegister(FIO_SegDataBlock<uint_2>);
+  DObjRegister(FIO_SegDataBlock<uint_2>, SegDataBlock<uint_2>);
+  PPRegister(FIO_SegDataBlock<int_2>);
+  DObjRegister(FIO_SegDataBlock<int_2>, SegDataBlock<int_2>);
+  PPRegister(FIO_SegDataBlock<int_4>);
+  DObjRegister(FIO_SegDataBlock<int_4>, SegDataBlock<int_4>);
+  PPRegister(FIO_SegDataBlock<int_8>);
+  DObjRegister(FIO_SegDataBlock<int_8>, SegDataBlock<int_8>);
+  PPRegister(FIO_SegDataBlock<uint_4>);
+  DObjRegister(FIO_SegDataBlock<uint_4>, SegDataBlock<uint_4>);
+  PPRegister(FIO_SegDataBlock<uint_8>);
+  DObjRegister(FIO_SegDataBlock<uint_8>, SegDataBlock<uint_8>);
+  PPRegister(FIO_SegDataBlock<r_4>);
+  DObjRegister(FIO_SegDataBlock<r_4>, SegDataBlock<r_4>);
+  PPRegister(FIO_SegDataBlock<r_8>);
+  DObjRegister(FIO_SegDataBlock<r_8>, SegDataBlock<r_8>);
+  PPRegister(FIO_SegDataBlock< complex<r_4> >);
+  DObjRegister(FIO_SegDataBlock< complex<r_4> >, SegDataBlock< complex<r_4> >);
+  PPRegister(FIO_SegDataBlock< complex<r_8> >);
+  DObjRegister(FIO_SegDataBlock< complex<r_8> >, SegDataBlock< complex<r_8> >);
+  PPRegister(FIO_SegDataBlock<string>);
+  DObjRegister(FIO_SegDataBlock<string>, SegDataBlock<string>);
+
+  // Enregistrement des handlers PPF pour les vecteurs de la STL
+  PPRegister(PPFWrapperSTLVector<uint_2>);
+  DObjRegister(PPFWrapperSTLVector<uint_2>, std::vector<uint_2>);
+  PPRegister(PPFWrapperSTLVector<int_2>);
+  DObjRegister(PPFWrapperSTLVector<int_2>, std::vector<int_2>);
+  PPRegister(PPFWrapperSTLVector<int_4>);
+  DObjRegister(PPFWrapperSTLVector<int_4>, std::vector<int_4>);
+  PPRegister(PPFWrapperSTLVector<int_8>);
+  DObjRegister(PPFWrapperSTLVector<int_8>, std::vector<int_8>);
+  PPRegister(PPFWrapperSTLVector<uint_4>);
+  DObjRegister(PPFWrapperSTLVector<uint_4>, std::vector<uint_4>);
+  PPRegister(PPFWrapperSTLVector<uint_8>);
+  DObjRegister(PPFWrapperSTLVector<uint_8>, std::vector<uint_8>);
+  PPRegister(PPFWrapperSTLVector<r_4>);
+  DObjRegister(PPFWrapperSTLVector<r_4>, std::vector<r_4>);
+  PPRegister(PPFWrapperSTLVector<r_8>);
+  DObjRegister(PPFWrapperSTLVector<r_8>, std::vector<r_8>);
+  PPRegister(PPFWrapperSTLVector< complex<r_4> >);
+  DObjRegister(PPFWrapperSTLVector< complex<r_4> >, std::vector< complex<r_4> >);
+  PPRegister(PPFWrapperSTLVector< complex<r_8> >);
+  DObjRegister(PPFWrapperSTLVector< complex<r_8> >, std::vector< complex<r_8> >);
+  PPRegister(PPFWrapperSTLVector< string >);
+  DObjRegister(PPFWrapperSTLVector< string >, std::vector<string>);
+
+  PPRegister(PPFWrapperSTLVector< TimeStamp >);
+  DObjRegister(PPFWrapperSTLVector< TimeStamp >, std::vector<TimeStamp>);
+
+
+#if (!defined(__GNUG__) && !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")) PrintVersion(false);
+
+  int pnice;
+  char* snice = getenv("SOPHYA_NICE");
+  if (!snice) pnice=8;
+  else pnice = atoi(snice);
+  nice(pnice);
+
+  SophyaInitiator::RegisterModule("BaseTools", MOD_VERS);  // Module name and version number registration  
+}
+
+SophyaInitiator::~SophyaInitiator()
+{
+  FgInit--;
+/*
+  if (FgInit == 0)
+    {
+    delete PPersistMgr::classList; PPersistMgr::classList = NULL;
+    delete PShPersist::objList;    PShPersist::objList = NULL;
+    }
+    */
+}
+
+/*! 
+  \brief Return the SOPHYA version number. 
+  \param svers contain the complete in addition the SOPHYA tag, the compiler name 
+  and the compilation date
+*/
+double SophyaInitiator::GetVersion(string& svers)
+{
+  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 __IBMCPP__
+  #ifdef SO_ARCH64
+  compiler = const_cast<char *>("IBM-xlC (-q64)") ;
+  #else
+  compiler = const_cast<char *>("IBM-xlC") ;
+  #endif
+  #endif
+  #ifdef __INTEL_COMPILER
+  compiler = const_cast<char *>("Intel-icc ") ;
+  #endif
+  #ifdef __SGICC__
+  #ifdef SO_ARCH64
+  compiler = const_cast<char *>("SGI-CC (-64) ") ;
+  #else
+  compiler = const_cast<char *>("SGI-CC ") ;
+  #endif
+  #endif
+
+  char buff[512];
+  sprintf(buff,"SOPHYA Version %4.1f Revision %d (%s) -- %s %s %s",
+          SOPHYA_VERSION, SOPHYA_REVISION, SOPHYA_TAG,
+          __DATE__, __TIME__, compiler);
+  svers = buff;
+  
+  return(SOPHYA_VERSION + (SOPHYA_REVISION/1000.));
+}
+
+//! Print the SOPHYA version string and optionaly the list of registered modules
+void SophyaInitiator::PrintVersion(bool fglist)
+{
+  string svers;
+  GetVersion(svers);
+  cout << svers << endl;
+  if (fglist) ListModules(cout);   
+}
+
+//! Should be called by sub-classes to register module name and version 
+int SophyaInitiator::RegisterModule(const char * name, double version)
+{
+  if (ModListP == NULL) 
+    throw NullPtrError("SophyaInitiator::RegisterModule() ModListP= NULL !");
+  map<string, double>& modlist = *ModListP;
+  modlist[string(name)] = version;
+  return modlist.size();
+}
+
+//! List of registered module names and version number
+int SophyaInitiator::ListModules(ostream& os)
+{
+  if (ModListP == NULL) 
+    throw NullPtrError("SophyaInitiator::ListModules() ModListP= NULL !");
+  os << "--- SophyaInitiator::ListModules() Name / VersionNumber --- " << endl;
+  map<string, double>& modlist = *ModListP;
+  int k = 1;
+  for(map<string, double>::iterator it = modlist.begin(); it != modlist.end(); it++, k++) 
+    os << k << " : " << (*it).first << " V= " << (*it).second << endl; 
+  os << " ----------------------------------------------------------- " << endl;
+  return modlist.size();
+}
+
+//! Return the SOPHYA version number: VERS + REV/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
+// La presence de l'objet statique psophyainit semble poserun probleme 
+// sur MacOSX 10.2 qui se plante a l'initialisation avec les shared-libs
+// Suppression de #if !defined(Darwin) en Juil 2006
+static SophyaInitiator psophyainit;
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/sophyainit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/sophyainit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/sophyainit.h	(revision 3445)
@@ -0,0 +1,37 @@
+// 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"
+#include <string>
+
+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();
+
+  static double         GetVersion(string& svers);
+  static void           PrintVersion(bool fglist=false);
+
+  static int            RegisterModule(const char* name, double version);
+  static int            ListModules(ostream& os);
+};
+
+#define SophyaInit() SophyaInitiator sophyainitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/sopnamsp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/sopnamsp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/sopnamsp.h	(revision 3445)
@@ -0,0 +1,23 @@
+#ifndef SOPNAMSP_SEEN
+#define SOPNAMSP_SEEN
+
+#ifdef __cplusplus
+
+/*  SOPHYA classes are in namespace SOPHYA:
+ sopnamsp.h :
+   1-/ DOIT etre mis dans les .cc de sophya
+   2-/ NE DOIT JAMAIS etre mis dans un .h de SOPHYA
+       disponible pour les utilisateur exterieurs
+ Dans un main programme:
+   1-/ Si on met sopnamsp.h les classes de SOPHYA
+       doivent etre instanciees: TArray<r_8>
+   2-/ Si on NE met PAS sopnamsp.h les classes de SOPHYA
+       doivent etre instanciees: SOPHYA::TArray<r_8>
+
+*/
+namespace SOPHYA {}
+using namespace SOPHYA;
+
+#endif
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/srandgen.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/srandgen.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/srandgen.c	(revision 3445)
@@ -0,0 +1,672 @@
+#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	srandgen.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 (obsolete).
+--
+*/
+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);
+}
+
+/*! \ingroup  BaseTools
+  \brief Poisson random number generator.
+  
+  Return an integer value (>=0) corresponding a Poisson distribution with mean \b mu.
+  \warning NOT the most efficient way of generating a large series of numbers
+  with the SAME mean
+*/
+int PoissRand(double mu)
+{
+  double pp,ppi,x;
+  int n;
+  ppi = pp = exp(-mu);
+  x = drand01();
+  n = 0;
+  while (x > ppi) {
+    n++;
+    pp = mu*pp/(double)n;
+    ppi += pp;
+  }
+  return n;
+}
+
+/*! \ingroup  BaseTools
+  \brief Poisson random number generator with approximation for large mean.
+  
+  Return an integer value (>=0) corresponding a Poisson distribution with mean \b mu.
+  If \b mu is greater or equal than \b mumax,
+  the large number gaussian approximation is applied.
+  \b mumax=10 is a good value.
+*/
+unsigned long PoissRandLimit(double mu,double mumax)
+// p(n) = (mu^n / n!) exp(-mu)  for n = 0, 1, 2, ...
+{
+  double pp,ppi,x;
+  unsigned long n;
+
+  if(mu>=mumax) {
+    pp = sqrt(mu);
+    while( (x=pp*NorRand()) < -mu );
+    return (unsigned long)(mu+x+0.5);
+  }
+
+  ppi = pp = exp(-mu);
+  x = drand01();
+  n = 0;
+  while (x > ppi) {
+    n++;
+    pp = mu*pp/(double)n;
+    ppi += pp;
+  }
+  return n;
+}
+
+/*=========================================================================*/
+/*
+++
+  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).
+--
+*/
+/*! \ingroup  BaseTools
+ \brief OBSOLETE (gaussian random number generator)
+*/
+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 "srandgen.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	srandgen.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_Nov2007/SophyaLib/BaseTools/srandgen.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/srandgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/srandgen.h	(revision 3445)
@@ -0,0 +1,87 @@
+/* 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>
+
+/* ------- SPECIFIQUE Mac Darwin OSX  <= 10.2 (gcc < 3.x) -------- */
+#if defined(Darwin) &&  defined(__GNUC__) && (__GNUC__ < 3)
+#include "osx_values.h"
+/* Declaration de drand48 et srand48 etc , mis ds SysSpec 
+                                          Reza 11/02/2003 */
+#ifdef __cplusplus
+extern "C" {
+#endif
+unsigned short int * seed48(unsigned short int seed16v[3]);
+void srand48(long seedval);
+/* Faute de mieux pour le moment : */
+#ifdef __cplusplus
+}
+#endif
+#define drand48() ((double)(random())/LONG_MAX)
+#endif
+/* ------- FIN SPECIFIQUE Mac OSX / Darwin V <= 10.2 --------- */
+
+#ifdef __cplusplus
+/* Declaration en fonctions inlines pour du C++ */
+inline float frand01() { return ( (float) drand48() ); }
+inline double drand01() { return ( drand48() ); }
+inline double ranf01() { return ( drand48() ); }
+
+inline float frandpm1() { return ( 2. * (float) drand48()  - 1.); }
+inline double drandpm1() { return ( 2. * drand48() - 1.); }
+inline double ranfpm1() { return ( 2. * drand48() - 1.); }
+#else
+/* les memes en define pour du C */
+#define frand01() ( (float) drand48() )
+#define drand01() ( drand48() )
+#define ranf01() drand01()
+
+#define frandpm1() ( 2. * frand01() - 1.)
+#define drandpm1() ( 2. * drand01() - 1.)
+#define ranfpm1() drandpm1()
+#endif
+
+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);
+
+int PoissRand(double mu);
+unsigned long PoissRandLimit(double mu,double mumax /* =10. */ );
+
+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_Nov2007/SophyaLib/BaseTools/stsrand.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/stsrand.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/stsrand.cc	(revision 3445)
@@ -0,0 +1,290 @@
+#include "stsrand.h"
+#include "thsafeop.h"
+//#include "srandgen.h"
+#include "fiondblock.h"
+#include <math.h> 
+#include <sys/time.h>
+
+namespace SOPHYA {
+
+/*!
+   \class RandomGenerator
+   \ingroup BaseTools
+   \brief Random number generator
+
+   This class is a thread-safe random number generator.
+   Its PPF handler can be used to save the complete state of the class and the underlying
+   random number generator used.
+
+   \sa SOPHYA::ObjFileIO<RandomGenerator>
+
+   \sa frand01 drand01 frandpm1 drandpm1 
+   \sa GauRnd PoissRand
+   \sa Ini_Ranf_Quick Ini_Ranf Get_Ranf Auto_Ini_Ranf
+
+
+*/
+
+// Objet statique global pour gestion de lock entre threads
+static ThSafeOp* ths_rand = NULL;
+
+RandomGenerator::RandomGenerator(size_t n, bool tsafe) 
+{
+  if (ths_rand == NULL)  ths_rand = new ThSafeOp; 
+  if (tsafe) {   // thread-safe
+    fg_nothrsafe = false;
+    if (n < 1) n = 1024;
+    rseq_.ReSize(n, false);
+    idx_ = n;
+  }
+  else {   // NOT thread-safe
+    fg_nothrsafe = true;
+    idx_ = 1;
+  }
+}
+
+RandomGenerator::RandomGenerator(RandomGenerator const & rg)
+{
+  if (ths_rand == NULL)  ths_rand = new ThSafeOp; 
+  if (!rg.fg_nothrsafe) { // thread-safe
+    fg_nothrsafe = false;
+    rseq_.ReSize(rg.rseq_.Size(), false);
+    idx_ = rseq_.Size();
+  }
+  else {   // NOT thread-safe
+    fg_nothrsafe = true;
+    idx_ = 1;
+  }
+}
+ 
+
+RandomGenerator::~RandomGenerator(void) 
+{
+  // rien a faire 
+}
+
+void RandomGenerator::AutoInit(int lp)
+// Initialisation automatique (pseudo) aleatoire du generateur.
+// L'initialiseur est donne par un codage du nombre de millisecondes
+// ecoulees depuis le 0 heure le 1er Janvier 1970 UTC (cf gettimeofday).
+// Seuls les 48 bits de poids faible sont retenus.
+// Un melange des bits est ensuite effectue pour que les 3 nombres
+// (unsigned short) d'initialisation ne soient pas trop semblables.
+//
+// Le nombre le plus grand que l'on peut mettre
+// dans un entier unsigned de N bits est: 2^N-1
+// 48 bits -> 2^48-1 = 281474976710655 musec = 3257.8j = 8.9y
+//         -> meme initialisation tous les 8.9 ans a 1 microsec pres !
+{
+  // On recupere le temps ecoule depuis l'origine code en sec+musec
+  struct timeval now;
+  gettimeofday(&now,0);
+
+  // Calcul du temps ecoule depuis l'origine en microsecondes
+  uint_8 v = (uint_8)now.tv_sec*(uint_8)1000000 + (uint_8)now.tv_usec;
+  if(lp>1) cout<<"..."<<now.tv_sec<<" sec + "<<now.tv_usec<<" musec = "<<v<<" musec"<<endl;
+
+  // Remplissage du tableau de bits
+  unsigned short b[48];
+  for(int ip=0;ip<48;ip++) {b[ip] = v&1; v = (v>>1);}
+  if(lp>2) {
+    cout<<"...b= ";
+    for(int ip=47;ip>=0;ip--) {if(ip==23) cout<<" "; cout<<b[ip];}
+    cout<<endl;
+  }
+
+  // Melange des bits qui varient vite (poids faible, microsec)
+  //   avec ceux variant lentement (poids fort, sec)
+  // On coupe le mot en trois: bits[0-15], bits[16-31] et bits[32-47]
+  // On echange 2 bits sur 3 du mot bits[0-15] dans les autres mots
+  //    bit0  <-> bit0  , bit1  <-> bit17 , bit2  <-> bit34
+  //    bit3  <-> bit3  , bit4  <-> bit20 , bit5  <-> bit37
+  //    bit13 <-> bit13 , bit14 <-> bit30 , bit15 <-> bit47
+  for(int ip=0;ip<16;ip++) {
+    if(ip%3==0) continue;
+    int ipd = (ip%3==1)? 16+ip : 32+ip;
+    unsigned short w = b[ip];
+    //cout<<"swap g["<<ip<<"]="<<b[ip]<<" <-> b["<<ipd<<"]="<<b[ipd]<<endl;
+    b[ip] = b[ipd];
+    b[ipd] = w;
+  }
+  if(lp>2) {
+    cout<<"...b= ";
+    for(int ip=47;ip>=0;ip--) {if(ip==23) cout<<" "; cout<<b[ip];}
+    cout<<endl;
+  }
+
+  // Construction du tableau d'initialisation
+  unsigned short seed_16v[3] = {0,0,0};
+  for(int is=0;is<3;is++) {
+    unsigned short w = 1;
+    for(int ip=0;ip<16;ip++) {
+      seed_16v[is] += w*b[is*16+ip];
+      w *= 2;
+    }
+  }
+  if(lp>0) cout<<"RandomGenerator::AutoInit: "<<seed_16v[0]<<" "<<seed_16v[1]<<" "<<seed_16v[2]<<endl;
+
+  // Initialise drand48()
+  Init(seed_16v,lp);
+}
+
+void RandomGenerator::Init(long seed_val, int lp)
+{
+  if (ths_rand == NULL)  ths_rand = new ThSafeOp; 
+  if(lp) cout << "RandomGenerator::Init(long seed=" << seed_val << ")" << endl;
+  ths_rand->lock();
+  srand48(seed_val);
+  ths_rand->unlock();
+  return;
+}
+
+void RandomGenerator::Init(unsigned short seed_16v[3], int lp)
+{
+  if (ths_rand == NULL)  ths_rand = new ThSafeOp; 
+  if(lp) cout << "RandomGenerator::Init(u_short seed_16v[3]=" << seed_16v[0]
+	      << "," << seed_16v[1] << "," << seed_16v[2] << ")" << endl;
+  ths_rand->lock();
+  Init_P(seed_16v);
+  ths_rand->unlock();
+}
+
+void RandomGenerator::GetSeed(unsigned short seed_16v[3], int lp)
+{
+  if (ths_rand == NULL)  ths_rand = new ThSafeOp; 
+  ths_rand->lock();
+  GetSeed_P(seed_16v);
+  ths_rand->unlock();
+  if(lp) cout << "RandomGenerator::GetSeed(u_short seed_16v[3]=" << seed_16v[0]
+	      << "," << seed_16v[1] << "," << seed_16v[2] << ")" << endl;
+  return;
+}
+
+void RandomGenerator::Init_P(unsigned short seed_16v[3])
+{
+  seed48(seed_16v);
+}
+
+void RandomGenerator::GetSeed_P(unsigned short seed_16v[3])
+{
+  unsigned short seed[3] = {0,0,0};
+  unsigned short *p;
+  p = seed48(seed);
+  memcpy(seed_16v,p,3*sizeof(unsigned short));
+  /* on re-initialise a ce qui etait avant */
+  seed48(seed_16v);
+  return;
+}
+
+r_8 RandomGenerator::Gaussian() 
+{
+  r_8 A=Next(); 
+  while (A==0.) A=Next(); 
+  return sqrt(-2.*log(A))*cos(2.*M_PI*Next());
+}
+
+
+uint_8 RandomGenerator::Poisson(double mu,double mumax)
+{
+  double pp,ppi,x;
+
+  if((mumax>0.)&&(mu>=mumax)) {
+    pp = sqrt(mu);
+    while( (x=pp*Gaussian()) < -mu );
+    return (uint_8)(mu+x+0.5);
+  }
+  else {
+    uint_8 n;
+    ppi = pp = exp(-mu);
+    x = Next();
+    n = 0;
+    while (x > ppi) {
+      n++;
+      pp = mu*pp/(double)n;
+      ppi += pp;
+    }
+    return n;
+  }
+  return 0;  // pas necessaire ?
+}
+
+void RandomGenerator::GenSeq(void)
+{
+  ths_rand->lock();
+  for(size_t k=0; k<rseq_.Size(); k++)  rseq_(k) = drand48();
+  ths_rand->unlock();
+  idx_ = 0;
+}
+
+//----------------------------------------------------------
+// Classe pour la gestion de persistance
+// ObjFileIO<RandomGenerator>
+//----------------------------------------------------------
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<RandomGenerator>::WriteSelf(POutPersist& s) const
+{
+  if (dobj == NULL)
+    throw NullPtrError("ObjFileIO<RandomGenerator>::WriteSelf() dobj=NULL");
+  ths_rand->lock();  // thread-safety
+  uint_4 itab[6];
+  //itab : [0]: version, [1,2,3] = srand48 state/seed  , [4,5] = reserved for future use
+  itab[0] = 1;
+  // On recupere et on ecrit ds le PPF l'etat du generateur aleatoire
+  unsigned short seed_16v[3];
+  dobj->GetSeed_P(seed_16v);
+  for(int i=0; i<3; i++)  itab[i+1] = seed_16v[i];
+  itab[4] = 0;
+  s.Put(itab, 6);
+  uint_8 sz = dobj->rseq_.Size();
+  s.Put(sz);  // Taille du tableau intermediaire
+  uint_8 ix = dobj->idx_;
+  s.Put(ix);  // valeur de l'index 
+
+  if (dobj->rseq_.Size() > 0)  s << dobj->rseq_;  // On ecrit le tableau (NDataBlock) si necessaire
+  ths_rand->unlock(); // thread-safety
+  return;
+}
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<RandomGenerator>::ReadSelf(PInPersist& s)
+{
+  uint_4 itab[6];
+  //itab : [0]: version, [1,2,3] = srand48 state/seed  , [4] = reserved for future use
+  s.Get(itab, 6);
+  uint_8 sz,ix;
+  s.Get(sz);  // Taille du tableau intermediaire
+  s.Get(ix);  // Taille du tableau intermediaire
+
+  if (dobj == NULL) dobj = new RandomGenerator(sz, (sz>0)?true:false);
+  dobj->idx_ = ix;
+  if (sz > 0) { 
+    s >> dobj->rseq_;  // On lit le tableau (NDataBlock) si necessaire
+    dobj->fg_nothrsafe = false;
+  }
+  else {  // Objet lu est NON thread-safe, taille_tableau rseq_ = 0
+    dobj->fg_nothrsafe = true;
+    if (dobj->rseq_.Size() > 0)  dobj->rseq_.Dealloc(); 
+  }
+  // On initialise l'etat du generateur aleatoire avec les valeurs lues
+  unsigned short seed_16v[3];
+  dobj->GetSeed_P(seed_16v);
+  for(int i=0; i<3; i++)  seed_16v[i] = itab[i+1];
+  dobj->Init(seed_16v, 0);
+  return;
+}
+
+// ---------------------------------------------------------
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<RandomGenerator>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<RandomGenerator>;
+#endif
+// ---------------------------------------------------------
+
+}  /* namespace SOPHYA */
+
Index: /tags/V_Nov2007/SophyaLib/BaseTools/stsrand.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/stsrand.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/stsrand.h	(revision 3445)
@@ -0,0 +1,101 @@
+#ifndef STSRAND_H_SEEN
+#define STSRAND_H_SEEN
+
+// Classe RandomGenerator 
+// Generateur aleatoire compatible multi-thread
+//
+// R. Ansari          (C) UPS+LAL IN2P3/CNRS  2007
+// C. Magneville      (C) DAPNIA/SPP  CEA     2007
+
+
+#include "machdefs.h"
+#include "objfio.h"   // Pour rendre la classe PPersist
+
+#include "ndatablock.h"
+
+namespace SOPHYA {
+
+class RandomGenerator : public AnyDataObj {
+
+ public:
+  RandomGenerator(size_t n = 1024, bool tsafe=true);
+  RandomGenerator(RandomGenerator const & rg);
+
+  virtual ~RandomGenerator();
+
+  /*! \brief Automatic initialization using the current time */
+  static  void AutoInit(int lp=0);
+  /*! \brief Initialization using the specified seed  */
+  static  void Init(long seed_val, int lp=0);
+  /*! \brief Initialization using the specified seed  */
+  static  void Init(unsigned short seed_16v[3], int lp=0);
+  /*! \brief Getting the current seed state */
+  static  void GetSeed(unsigned short seed_16v[3], int lp=0);
+
+  /*! \brief Return a random number \b r with a flat distribution  0<=r<1 */ 
+  inline r_8 Flat01() {return Next();}
+
+  /*! \brief Return a random number \b r with a flat distribution  -1<=r<1 */ 
+  inline r_8 Flatpm1() {return 2.*Next()-1.;}
+
+  /*! \brief Return a random number following a gaussian distribution (sigma=1, mean=0*/ 
+  virtual r_8 Gaussian(); 
+
+  /*! \brief Return a random number following a gaussian distribution "sigma", (mean=0)*/ 
+  virtual r_8 Gaussian(double sigma) 
+    { return sigma*Gaussian(); }
+ /*! \brief Return a random number following a gaussian distribution with mean=mu, and sigma */ 
+  virtual r_8 Gaussian(double sigma,double mu) 
+    { return sigma*Gaussian()+mu; }
+
+  /*! \brief alias for Gaussian() */ 
+  inline r_8 NorRand()
+    { return Gaussian(); }
+
+  /*! \brief Return a random number following a poisson distribution with mean mu */ 
+  virtual  uint_8 Poisson(double mu, double mumax);
+  
+  /*! \brief Return a random number following a poisson distribution with mean mu */ 
+  inline uint_8 Poisson(double mu)
+    { return Poisson(mu, -1.); }
+
+   /*! \brief Return a random number following a poisson distribution with mean mu */ 
+  inline uint_8  PoissRandLimit(double mu,double mumax=10.)
+    { return Poisson(mu, mumax); }
+ 
+  //  Pour la gestion de persistance PPF
+  friend class ObjFileIO<RandomGenerator> ;
+
+ protected:
+  // ---- protected data members
+  NDataBlock<r_8>  rseq_;  
+  size_t idx_;
+  bool fg_nothrsafe;  // if true --> NOT thread-safe
+  // ---- protected methods 
+  void GenSeq();
+  inline r_8 Next() 
+    {
+      if (rseq_.Size() == 0)  return drand48(); 
+      else { 
+	if(idx_==rseq_.Size()) GenSeq(); 
+	return(rseq_(idx_++));
+      }
+    }
+  // Non thread-safe version of Init() and GetSeed()
+  static  void Init_P(unsigned short seed_16v[3]);
+  static  void GetSeed_P(unsigned short seed_16v[3]);
+
+};  // Fin de la classe RandomGenerator
+
+// Classe pour la gestion de persistance PPF :  ObjFileIO<RandomGenerator>
+
+/*! Writes the random generator object state in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, RandomGenerator & obj)
+{ ObjFileIO<RandomGenerator> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the random generator object state from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, RandomGenerator & obj)
+{ ObjFileIO<RandomGenerator> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} /* namespace SOPHYA */
+
+#endif 
Index: /tags/V_Nov2007/SophyaLib/BaseTools/sversion.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/sversion.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/sversion.h	(revision 3445)
@@ -0,0 +1,8 @@
+#ifndef SVERSION_H
+#define SVERSION_H
+
+#define SOPHYA_VERSION   2.1
+#define SOPHYA_REVISION  00
+#define SOPHYA_TAG       "V_Nov2007"
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/swsegdb.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/swsegdb.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/swsegdb.h	(revision 3445)
@@ -0,0 +1,262 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees swapable
+//                         R. Ansari  Mars 2005
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef SWSEGDATABLOCK_H
+#define SWSEGDATABLOCK_H
+
+#include "machdefs.h"
+#include "segdatablock.h"
+#include "pexceptions.h"
+#include <vector>
+#include <typeinfo>
+
+/*!
+  \class SOPHYA::DataSwapperInterface
+  \ingroup BaseTools
+  Interface definition for  data swapper (pure virtual) classes to be used 
+  with SOPHYA::SwSegDataBlock classes.
+*/
+/*!
+  \class SOPHYA::SwSegDataBlock
+  \ingroup BaseTools
+  Segmented data structure with swap space management.
+*/
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+//// ------------- Class DataSwapperInterface --------------- //
+//// ---------------- Class SwSegDataBlock ------------------ //
+////////////////////////////////////////////////////////////////
+
+template <class T> 
+class DataSwapperInterface {
+public:
+  virtual ~DataSwapperInterface() { }
+  /*! Swap out the data array pointed by \b d with size \b sz
+    Return the swap position which might be used later to retrieve the data from swap
+    \param d : Pointer to the memory segment
+    \param sz : Number of elements (type T) 
+    \param idx : An integer which might be used to identify the data (optional)
+    \param oswp : Old swap position, if the data has already been swapped
+    \param osw : true -> data has already been swapped
+  */
+  virtual int_8 WriteToSwap(const T * d, size_t sz, int_8 idx, int_8 oswp=0, bool osw=false) = 0;
+  /*! Swap in the data array pointed by \b d with size \b sz
+    Retrieves the data from swap space and copies it to \b d
+    \param idx : optional data identifier
+    \param swp : swap position (obtained from a previous call to WriteToSwap()
+    \param d : pointer to T , where the data will be copied from swap space
+    \param sz : Number of data elements (type T) 
+   */
+  virtual void  ReadFromSwap(int_8 idx, int_8 swp, T* d, size_t sz) = 0;
+
+  /*! Duplicate the swapper object and return the new object pointer.
+      The returned pointer should be deleted when not needed any more.
+      This method is used by SwSegDataBlock<T> 
+  */
+  virtual DataSwapperInterface<T>* Clone() = 0;
+};
+
+template <class T>
+class SwSegDataBlock : public SegDBInterface<T> {
+public:
+  //! Constructor - creation from swap position tags (values)
+  SwSegDataBlock(DataSwapperInterface<T> & dsw, vector<int_8> const & swpos, size_t segsz)
+  {
+    mSRef = NULL;
+    SetSize(segsz, swpos.size());
+    SetSwapper(dsw);
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->swp = swpos;
+    for(size_t k=0; k<mSRef->fgwp.size(); k++)  mSRef->fgwp[k] = true; 
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    }
+  //! Constructor - optional specification of segment size and number of segments
+  SwSegDataBlock(DataSwapperInterface<T> & dsw, size_t segsz=32, size_t nbseg=0)
+  {
+    mSRef = NULL;
+    SetSize(segsz, nbseg);
+    SetSwapper(dsw);
+  }
+  //! copy constructor - shares the data
+  SwSegDataBlock(const SwSegDataBlock<T>& a)
+  {
+    a.mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef = a.mSRef;
+    mSRef->nref++;
+    size_t segsz = mSRef->segsize;
+    a.mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    buff = new T[segsz];
+    bidx = -1;        
+    fgcstbuff = true; 
+  }
+
+  //! Destructor. The memory is freed when the last object referencing the data segment is destroyed
+  virtual ~SwSegDataBlock() 
+  { 
+    Delete(); 
+  }
+  //! Adds one segment to the data structure - returns the pointer to the allocated segment.
+  virtual size_t Extend() 
+  {
+    size_t rs = 0;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->swp.push_back(0);
+    mSRef->fgwp.push_back(false);
+    rs = mSRef->swp.size();
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    return rs;
+  }
+  /*! \brief Changes the data segment size and reallocates the memory segments
+    \warning SetSwapper() must be called after call to SetSize() 
+  */
+  // segsz : Segment size ;  nbseg : Number of data segments
+  virtual void SetSize(size_t segsz, size_t nbseg=0)
+  {
+    Delete();
+    mSRef = new SWSDREF;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->nref = 1;
+    mSRef->segsize = segsz;
+    mSRef->dsid = AnyDataObj::getUniqueId();
+    for(size_t k=0; k<nbseg; k++) {
+      mSRef->swp.push_back(0);
+      mSRef->fgwp.push_back(false);
+    }
+    mSRef->swapper = NULL;
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    buff = new T[segsz];
+    bidx = -1;        
+    fgcstbuff = true; 
+  }
+
+  //! Define the data swapper object. Should only be called if SetSize() is called
+  void SetSwapper(DataSwapperInterface<T> & dsw)
+  {
+    if (mSRef == NULL) return;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    if (mSRef->swapper) delete mSRef->swapper;  
+    mSRef->swapper = dsw.Clone();
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+  }
+
+  //! Return the segment size data structure
+  virtual  size_t SegmentSize() const  { return mSRef->segsize; }
+  //! Return the number of data segments
+  virtual size_t NbSegments() const { return mSRef->swp.size(); } ;
+  //! Return the current size of the segmented data structure
+  inline size_t Size() const    { return  mSRef->swp.size()*mSRef->segsize; }
+  //! Return the pointer to data segment \b k
+  virtual T* GetSegment(size_t k) 
+  {
+    getSeg(k);
+    fgcstbuff = false;
+    return buff;
+  }
+  //! Return the const (read-only) pointer to data segment \b k         
+  virtual T const * GetCstSegment(size_t k) const 
+  {
+    if (getSeg(k))  fgcstbuff = true;
+    return buff;    
+  }
+
+  //! Equal operator. Shares the data with \b a
+  inline SwSegDataBlock<T>&  operator = (const SwSegDataBlock<T>& a)
+  {
+    Delete();
+    a.mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef = a.mSRef;
+    mSRef->nref++;
+    size_t segsz = mSRef->segsize;
+    a.mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    buff = new T[segsz];
+    bidx = -1;        
+    fgcstbuff = true; 
+    return *this;
+  }
+
+  //! Empties all memory buffers to swap stream 
+  void SwapOutBuffer() const
+  {
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    if ((bidx >= 0) && !fgcstbuff) {
+      int_8 nswp = mSRef->swapper->WriteToSwap(buff, mSRef->segsize, bidx, 
+					       mSRef->swp[bidx], mSRef->fgwp[bidx]);
+      mSRef->swp[bidx] = nswp;
+      mSRef->fgwp[bidx] = true;
+      bidx = -1;
+      fgcstbuff = true;  
+   }
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+  }
+  //! Return the position tag (swap position) table, after call to SwapOutBuffer()
+  std::vector< int_8 > & GetSwapPosTagTable() const 
+  { 
+    SwapOutBuffer();
+    return  mSRef->swp; 
+  } 
+
+protected: 
+  SwSegDataBlock() 
+  {
+    throw ForbiddenError("SwSegDataBlock() default constructor not allowed (swsegdb.h)");
+  }
+  void Delete()   
+  {
+    if (mSRef == NULL) return;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    mSRef->nref--;
+    if (mSRef->nref > 0)  { 
+      mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+      delete[] buff;
+      mSRef = NULL; 
+      return; 
+    }
+    if (mSRef->swapper) delete mSRef->swapper;  
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    delete mSRef;
+    delete[] buff;
+    mSRef = NULL;  
+  } 
+  bool getSeg(size_t k) const
+  {
+    if (k == bidx)  return false;
+    mSRef->gThsop.lock();   //  (ThreadSafe) - Start of atomic operation 
+    if ((bidx >= 0) && !fgcstbuff) {
+      int_8 nswp = mSRef->swapper->WriteToSwap(buff, mSRef->segsize, bidx, 
+					       mSRef->swp[bidx], mSRef->fgwp[bidx]);
+      mSRef->swp[bidx] = nswp;
+      mSRef->fgwp[bidx] = true;
+    }
+    if (mSRef->fgwp[k]) 
+      mSRef->swapper->ReadFromSwap(k, mSRef->swp[k], buff, mSRef->segsize);
+    //DEL-02022007    else { delete[] mSRef->buff;  mSRef->buff = new T[mSRef->segsize]; }  
+    mSRef->gThsop.unlock();   //  (ThreadSafe) - End of atomic operation
+    bidx = k;
+    return true;
+  }
+
+  //! \cond
+  typedef struct {
+    size_t nref;      // Number of references to the data structure  
+    uint_8 dsid;      // Data structure id
+    size_t segsize;   // data segment size
+    mutable std::vector< int_8 > swp;  // swap position tag for each segment
+    mutable std::vector< bool > fgwp;  // swap flag (true = already swapped)  for each segment
+    DataSwapperInterface<T> * swapper;   // Data swapper
+    ThSafeOp gThsop;         // Mutex for thread safe operation one / SWSDREF struct 
+  } SWSDREF;
+  //! \endcond
+  SWSDREF *  mSRef;    //!< SWSDREF structure for reference sharing
+  mutable T * buff;                // Data buffer   
+  mutable int_8 bidx;              // segment index (number) corresponding to buffer 
+  mutable bool fgcstbuff;          // true : this is a constant T * buff
+
+};
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/thsafeop.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/thsafeop.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/thsafeop.h	(revision 3445)
@@ -0,0 +1,56 @@
+#ifndef THSAFEOP_H_SEEN
+#define THSAFEOP_H_SEEN
+
+// Classe ThSafeOp : pour permettre l'execution d'operations atomiques en 
+// multithread, lors de gestion de comptage de reference en particulier.
+//  
+// R. Ansari      UPS+LAL IN2P3/CNRS  2007
+
+
+#include "machdefs.h"
+#include "pexceptions.h"
+
+#ifndef SO_NOTHSAFE
+#include <pthread.h>
+#endif
+
+namespace SOPHYA {
+
+
+/*! \brief 
+    Auxiliary class for insuring thread safe operations in SOPHYA, for reference 
+    counting operations 
+*/ 
+class ThSafeOp {
+public:
+#if defined(SO_NOTHSAFE)
+  explicit ThSafeOp() { }
+  ~ThSafeOp() { }
+  inline void	lock() { return; }
+  inline void	unlock() { return; }
+#else
+  explicit ThSafeOp() 
+    { 
+      int rc;
+      rc = pthread_mutex_init(&_mutx, NULL);
+      if (rc != 0) throw PException("ThSafeOp::ThSafeOp() / Error pthread_mutex_init");
+    }
+  ~ThSafeOp() 
+    {
+      int rc;
+      rc = pthread_mutex_destroy(&_mutx);
+      if (rc != 0) throw PException("ThSafeOp::~ThSafeOp() / Error pthread_mutex_destroy");
+    }
+  //! Locks the mutex object
+  inline void	lock()
+    { pthread_mutex_lock(&_mutx); } 
+  //! Unlocks the mutex object
+  inline void	unlock()
+    { pthread_mutex_unlock(&_mutx); }
+protected:
+  pthread_mutex_t _mutx;
+#endif
+};
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.cc	(revision 3445)
@@ -0,0 +1,358 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <math.h>
+#include "timestamp.h"
+#include "pexceptions.h"
+#include <iostream>
+
+namespace SOPHYA {
+
+/*!
+   \class TimeStamp
+   \ingroup BaseTools
+   A simple class for representing date and time. Simple operations 
+   on date/time are also provided. 
+   
+   \code
+   // Create a object with the current date and time and prints it to cout
+   TimeStamp ts; 
+   cout << ts << endl;
+   // Create an object with a specified date and time 
+   TimeStamp ts2("01/01/1905","00:00:00");
+   // Get the number of days since 0 Jan 1901
+   cout << ts2.ToDays() << endl;
+   \endcode
+*/
+
+#ifdef Linux 
+// La fonction trunc non declaree ds math.h sous Linux
+extern "C" { double trunc   (double x); }
+#endif
+//-------------------------------------------------------------------------
+//--------------------------  Classe TimeStamp   --------------------------
+//-------------------------------------------------------------------------
+
+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};
+
+  /*
+  //! Day of the week enum
+  enum WeekDay {day_Monday=0, day_Tuesday, day_Wednesday, day_Thursday, day_Friday, day_Saturday, day_Sunday};
+  */
+ 
+TimeStamp::TimeStamp()
+{
+  mSeconds = 0.;
+  mDays = 0;
+  SetNow();
+}
+
+TimeStamp::TimeStamp(TimeStamp const & ts)
+{
+  Set(ts);
+  mSeconds = ts.mSeconds;
+  mDays = ts.mDays;
+}
+
+TimeStamp::TimeStamp(int year, int month, int day, int hour, int min, double sec)
+{
+  SetDate(year, month, day);
+  SetHour(hour, min, sec);
+}
+
+
+TimeStamp::TimeStamp(double days)
+{
+  Set(days);
+}
+
+TimeStamp::TimeStamp(int_8 days, r_8 seconds)
+{
+  Set(days, seconds);
+}
+
+TimeStamp::TimeStamp(string const & date, string const & hour)
+{
+  SetDate(date);
+  SetHour(hour);
+}
+
+TimeStamp::TimeStamp(const char* date, const char* hour)
+{
+  SetDate(date);
+  SetHour(hour);
+}
+
+TimeStamp::TimeStamp(string& datim)
+{
+  Set(datim);
+}
+
+TimeStamp::TimeStamp(const char* datim)
+{
+  Set(datim);
+}
+
+void TimeStamp::Set(TimeStamp const & ts)
+{
+  mSeconds = ts.mSeconds;
+  mDays = ts.mDays;
+}
+
+void TimeStamp::Set(double days)
+{
+  if (days >= 0.) {
+    mDays = (int_8)trunc(days);
+    mSeconds = (days-trunc(days))*86400.;
+  }
+  else {
+    if ( (trunc(days)-days) > 0.) {
+      mDays = (int_8)trunc(days)-1;
+      mSeconds = (days-mDays)*86400.;
+    }
+    else {
+      mDays = (int_8)trunc(days);
+      mSeconds = 0.;
+    }
+  }
+}
+
+void TimeStamp::Set(int_8 days, r_8 seconds)
+{
+  if ( (seconds < 0.) || (seconds > 86400.) ) 
+    throw ParmError("TimeStamp::Set(int_8, r_8) seconds<0 or seconds>86400.");
+  mDays = days;
+  mSeconds = seconds;
+}
+
+void TimeStamp::Set(const char * datim)
+{
+  int year, month, day;
+  int hour, min;
+  double sec;
+  sscanf(datim,"%d-%d-%dT%d:%d:%lf", &year, &month, &day,
+	 &hour, &min, &sec);
+  SetDate(year, month, day);
+  SetHour(hour, min, sec);
+}
+
+
+void TimeStamp::SetNow()
+{
+  time_t t = time(NULL);
+  struct tm* TM = gmtime(&t);
+
+  int JJ,MM,AA;
+  int hh,mm;
+  double ss; 
+  
+  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;
+  SetDate(AA,MM,JJ);
+  SetHour(hh,mm,ss);
+}
+
+void TimeStamp::SetDate(int year, int month, int day)
+{
+  mDays = ConvertToDays(year, month, day);
+}
+
+void TimeStamp::SetDate(const char* date)
+{
+  int day,month,year;
+  sscanf(date,"%d/%d/%d", &day, &month, &year);
+  mDays = ConvertToDays(year, month, day);
+}
+
+void TimeStamp::SetHour(int hour, int min, double sec)
+{
+  mSeconds = hour*3600.+min*60+sec;
+}
+
+void TimeStamp::SetHour(const char* shour)
+{
+  int hour, min;
+  double sec;
+  sscanf(shour,"%d:%d:%lf",&hour, &min, &sec);
+  mSeconds = hour*3600.+min*60+sec;
+
+}
+
+void TimeStamp::GetDate(int& year, int& month, int& day) const
+{
+  int_8 jours = mDays;
+  // Recherche de l'annee
+  if (jours < 0) {
+    year = 1901;
+    while(jours < 0)  { 
+      year--;
+      jours += YearDays(year); 
+    }
+  }
+  else {
+    year = 1901;
+    while(jours > YearDays(year))  { 
+      jours -= YearDays(year); 
+      year++;
+    }
+  }
+  // Recherche du mois
+  month = 1;
+  while(jours > MonthDays(year, month) )  { 
+    jours -= MonthDays(year, month);
+    month++;
+  }
+  day = jours;
+}
+
+void TimeStamp::GetHour(int& hour, int& min, double& sec) const
+{
+  double seconds = mSeconds;
+  hour = (int)trunc(seconds/3600.);
+  seconds -= hour*3600;
+  min = (int)trunc(seconds/60.);
+  while (min >= 60) { hour++; min -= 60; }
+  sec = seconds-min*60;
+  while (sec >= 60.) { min++; sec -= 60.; }
+}
+
+double TimeStamp::ToDays() const
+{
+  return((double)mDays + mSeconds/86400.);
+}
+
+/*!
+\param fmt : String format for the date 
+  - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
+  - FmtDateOnly : dd/mm/yyyy
+  - FmtTimeOnly : hh:mm:ss.s
+  - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
+*/
+string TimeStamp::ToString(StrFmt fmt) const
+{
+  char buff[128];
+  int aa, mm, jj;
+  int hh, min;
+  double sec;
+  GetDate(aa, mm, jj);
+  GetHour(hh, min, sec);
+  if (fmt == FmtPackedDateTime) 
+    sprintf(buff,"%04d-%02d-%02dT%02d:%02d:%02.1f", aa,mm,jj, hh,min,sec);
+  else {
+    if (fmt == FmtDateOnly) 
+      sprintf(buff,"%02d/%02d/%04d ", jj,mm,aa);
+    else if (fmt == FmtTimeOnly) 
+      sprintf(buff,"%02d:%02d:%02.3f ", hh,min,sec);
+    else 
+      sprintf(buff,"%02d/%02d/%04d %02d:%02d:%02.1f UT", jj,mm,aa,hh,min,sec);
+  }
+  return buff;
+}
+
+/*!
+\param fmt : String format for the date 
+  - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
+  - FmtDateOnly : dd/mm/yyyy
+  - FmtTimeOnly : hh:mm:ss.s
+  - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
+*/
+void TimeStamp::Print(ostream& os, StrFmt fmt)  const
+{
+  os << " " << ToString(fmt) << " "; 
+}
+
+int TimeStamp::MonthDays(int annee, int mois) 
+{
+  if (mois<1 || mois>12) throw ParmError("TimeStamp::MonthDays month out of range");
+  
+  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;
+}
+
+int TimeStamp::YearDays(int annee)
+//	Retourne le nombre de jours dans l'année
+{
+  return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 366 : 365;
+}
+
+int_8 TimeStamp::ConvertToDays(int AA, int MM, int JJ)
+{
+  int_8 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 += TimeStamp::MonthDays(AA, i);
+  t += JJ;
+  // }
+  return t;
+}
+
+//----------------------------------------------------------
+// Classe pour la gestion de persistance
+// ObjFileIO<TimeStamp>
+//----------------------------------------------------------
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<TimeStamp>::WriteSelf(POutPersist& s) const
+{
+  if (dobj == NULL)
+    throw NullPtrError("ObjFileIO<TimeStamp>::WriteSelf() dobj=NULL");
+  int_4 ver;
+  ver = 1;
+  s.Put(ver);   // Lecture numero de version PPF
+  s.Put(dobj->DaysPart());
+  s.Put(dobj->SecondsPart());
+}
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<TimeStamp>::ReadSelf(PInPersist& s)
+{
+  int_4 ver;
+  s.Get(ver);   // Lecture numero de version PPF
+  r_8 seconds;
+  int_8 days;
+  s.Get(days);
+  s.Get(seconds);
+
+  if (dobj == NULL) dobj = new TimeStamp(days, seconds);
+  else dobj->Set(days, seconds);
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<TimeStamp>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<TimeStamp>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BaseTools/timestamp.h	(revision 3445)
@@ -0,0 +1,131 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef TIMESTAMP_H_SEEN
+#define TIMESTAMP_H_SEEN
+
+// Classe TimeStamp (Date+heure)
+//
+// R. Ansari      UPS+LAL IN2P3/CNRS  2005
+// Code recupere en partie ds dates.h dates.cc (classe Date) / E. Aubourg 1995-2000
+
+
+#include "machdefs.h"
+#include "objfio.h"
+#include <string> 
+#include <iostream> 
+
+namespace SOPHYA {
+  
+//! Class representing date and time
+class TimeStamp : public AnyDataObj {
+public:
+  /*  Pour utilisation ulterieure
+  //! GMT / local time enum 
+  enum {kGMTTime=0, kLocalTime=1};
+  */
+  //! Month name enum
+  enum Month {month_January=1, month_February, month_March, month_April, month_May, month_June, month_July,
+             month_August, month_September, month_October, month_November, month_December};  
+
+  enum StrFmt { FmtPackedDateTime , FmtDateOnly, FmtTimeOnly, FmtDateTime };
+
+  //! Default Constructor : current date and time (GMT)
+  TimeStamp();
+  TimeStamp(TimeStamp const & ts);
+  //! Constructor with specification of number of days since 0 Jan 1901 0h TU 
+  TimeStamp(double days);
+  //! Constructor from number of days (since 0/01/1901) and number of seconds 
+  TimeStamp(int_8 days, r_8 seconds);
+  //! Constructor with specification of day,month,year,hour,minutes,seconds 
+  TimeStamp(int year, int month, int day, int hour, int min, double sec);
+  //! Constructor with specification of date & time in the format YYYY/MM/DD hh:mm:ss  
+  TimeStamp(string const & date, string const & hour);
+  //! Constructor with specification of date & time in the format YYYY/MM/DD hh:mm:ss  
+  TimeStamp(const char* date, const char* hour);
+  //! Constructor with specification of date & time in the format YYYY-MM-DDThh:mm:ss 
+  TimeStamp(string& datim);
+  //! Constructor with specification of date & time in the format YYYY-MM-DDThh:mm:ss 
+  TimeStamp(const char* datim);
+
+  //! Set the value of the time stamp copying from "ts"
+  void Set(TimeStamp const & ts);
+  //! Sets the value of the time stamp from the number of days since 0 Jan 1901 0h TU 
+  void Set(double days);
+  //! Sets the value of the time stamp from the number of days and seconds
+  void Set(int_8 days, r_8 seconds);
+  //! Sets the value of the time stamp from a string in the format YYYY-MM-DDThh:mm:ss 
+  void Set(const char * datim);
+ //! Sets the value of the time stamp from a string in the format YYYY-MM-DDThh:mm:ss 
+  inline void Set(string const & datim)  { Set(datim.c_str()); }
+  //! initialize with current date and time (GMT)
+  void SetNow();
+
+  //! The equal (set) operator 
+  inline TimeStamp& operator= (TimeStamp const & ts) 
+    { Set(ts); return(*this); }
+
+  //! Sets the value of the date (days) 
+  void SetDate(int year, int month, int day);
+  //! Sets the value of the date (format: DD/MM/YYYY) 
+  void SetDate(const char* date); 
+  //! Sets the value of the date (format: DD/MM/YYYY) 
+  inline void SetDate(string const& date) { SetDate(date.c_str()); }
+
+  //! Sets the value of the time of day (hours) 
+  void SetHour(int hour, int min, double sec);
+  //! Sets the value of the time of day (format: hh:mm:ss[.ss]) 
+  void SetHour(const char* hour); 
+  //! Sets the value of the time of day (format: hh:mm:ss[.ss]) 
+  inline void SetHour(string const& hour) { SetHour(hour.c_str()); }
+
+  //! Return the date (Year, Month, Day)
+  void GetDate(int& year, int& month, int& day) const;
+  //! Return the time of the day
+  void GetHour(int& hour, int& min, double& sec) const;
+
+  //! Return the value of the TimeStamp as days.fraction_days since 0 Jan 1901
+  double ToDays() const;
+  //! Conversion operator to double - return ToDays() 
+  inline operator double() const { return ToDays(); }
+
+  //! Return the timestamp in string format 
+  string ToString(StrFmt fmt=FmtPackedDateTime) const;
+  
+  //! Return the integral number of days since 0 Jan 1901
+  inline int_8 DaysPart() { return mDays; }
+  //! Return the fractional number of days in seconds ( 0 < nsec < 86400. )
+  inline r_8 SecondsPart() { return mSeconds; }
+
+  //! Prints the date/time in string format on \b cout 
+  inline  void    Print(StrFmt fmt=FmtDateTime) const  
+     { Print(cout, fmt); }  
+  //! Prints the date/time in string format on stream \b os 
+  virtual void    Print(ostream& os, StrFmt fmt=FmtDateTime)  const;
+
+  //! Number of days in a given month  
+  static int   MonthDays(int year, int month);
+  //! Number of days in a given year
+  static int YearDays(int annee);
+  //! Number of  days since 0 janvier 1901 0h TU
+  static int_8 ConvertToDays(int year, int month, int day);
+  
+
+protected:
+  r_8 mSeconds;     // Number of seconds since 00:00:00 
+  int_8 mDays;      // Number of days since 0 Jan 1901
+};
+
+/*! operator << overloading - Prints date/time in string format on \b os*/
+inline ostream& operator << (ostream& s, TimeStamp const & ts)
+  {  ts.Print(s);  return(s);  }
+
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, TimeStamp & obj)
+{ ObjFileIO<TimeStamp> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, TimeStamp & obj)
+{ ObjFileIO<TimeStamp> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/AIX_xlC_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/AIX_xlC_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/AIX_xlC_make.inc	(revision 3445)
@@ -0,0 +1,78 @@
+
+# ----------------------------------------
+# --------- File AIX_xlC_make.inc --------
+#   Compilation avec xlC / AIX (IBM) 
+# ------- Dec 2005-Avr 2007   ------------
+
+#  Liste des librariries externes 
+#  Pour link fortran -lf ( pas besoin de -lxlf -lxlfutil )
+#  -lessl pour le BLAS IBM
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -lessl -lf
+
+#  Chemin et librairie pour PI 
+PIINC = 
+PILIBS = -lXm -lXt -lX11 
+
+#  Flag preprocesseur
+CPPFLAGS = -DAIX -I$(SOPHYAINCP) $(PIINC)
+#  Def compilateur C et flags
+CC = xlc
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+#    Pour compilation en mode 64 bits : -q64 
+CFLAGS = -O -g  CNFPHFLF 
+#  Def compilateur C++ et flags
+CXX =  xlC
+#  Flag IBM xlC (Dec 2005) 
+#  -qrtti=all : generate all RTTI infomation dynamic_cast + typeinfo
+#  -qeh=v6 : Exception handling compatible with v6 
+CXXFLAGS = -qrtti=all -qeh=v6 -O -g CNFPHFLF 
+# flags specifiques pour templates repository...
+# CXXTEMPFLG = -qtemplateregistry=$(SOPHYAOBJP)/templateregistry -qtemplaterecompile
+CXXTEMPFLG =
+#  Compilo fortran
+FC = xlf CNFPHFLF 
+FFLAGS =  
+# Pour fabriquer les lib .a   (-X 64 pour les librairies en mode 64 bits) 
+AR = ar
+ARFLAGS = -rcs
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = so
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXTEMPFLG) -brtl -qmkshrobj 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lpthread -lm -lc -ldl 
+LIBFORT = 
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+#  Il n'a pas ete possible de faire marcher les executables avec 
+#  des shared-libs, linke avec d'autres librairies (lapack, cfitsio ...)
+## SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+## SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+### --- Pb sur AIX quand plusieurs shared libs sont utilisees -> remplacement par -lAsophyaextPI
+## SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lAsophyaextPI  $(SOPBASELIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+## SOPHYAALLSLBLIST = $(SOPHYAEXTSLBLIST)
+### ---------------------
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lsophya -L$(SOPHYALIBP) -lFitsIOServer -lIFFTW -lLinAlg -lXAstroPack $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lsophya -L$(SOPHYALIBP) -lPIext -lPIGcont -lPI -lFitsIOServer -lIFFTW -lLinAlg -lXAstroPack $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation d'executables
+CXXLINK = $(CXX) $(CXXFLAGS) -brtl 
+CLINK = $(CC) $(CFLAGS)
+FCLINK = $(FC) $(FFLAGS)
+
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -qmkshrobj 
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/Darwin_g++_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/Darwin_g++_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/Darwin_g++_make.inc	(revision 3445)
@@ -0,0 +1,60 @@
+# --------- File Darwin_g++_make.inc -------- 
+
+#  Liste des librariries externes 
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -framework Accelerate
+
+#  Chemin et librairie pour PI 
+PIINC = -I/usr/X11R6/include/ -I/sw/include
+PILIBS = -L/sw/lib -lXm -L/usr/X11R6/lib  -lXt -lX11 
+
+
+#  Flag preprocesseur
+CPPFLAGS = -DDarwin -I$(SOPHYAINCP)  $(PIINC)
+#  Def compilateur C et flags
+CC = cc
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+CFLAGS = -fno-common -g -O -fPIC CNFPHFLF 
+#  With optimization flags 
+#  CFLAGS = -fno-common -g -fastf -mtune=G5 -fPIC
+#  Def compilateur C++ et flags
+CXX =  c++
+CXXFLAGS = -fno-common -g -O -fPIC  CNFPHFLF 
+# CXXFLAGS = -fno-common -g -fastf -mtune=G5 -fPIC 
+# flags specifiques pour templates repository...
+CXXTEMPFLG =
+#  Compilo fortran
+FC = g77
+FFLAGS =  
+# Pour fabriquer les lib .a
+AR = libtool 
+ARFLAGS = -static -o 
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = dylib
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXTEMPFLG) -dynamiclib 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lpthread -lm -lc -ldl 
+LIBFORT = 
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation d'executables
+CXXLINK = $(CXX) $(CXXFLAGS) -bind_at_load
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -bundle 
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/IRIX64_CC_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/IRIX64_CC_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/IRIX64_CC_make.inc	(revision 3445)
@@ -0,0 +1,61 @@
+# --------- File IRIX64_CC_make.inc -------- 
+
+#  Liste des librariries externes  (complib.sgimath : lapack+blas de SGI)
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -lcomplib.sgimath
+
+#  Chemin et librairie pour PI 
+PIINC = 
+PILIBS = -lXm -lXt -lX11 
+
+
+#  Flag preprocesseur 
+CPPFLAGS = -I$(SOPHYAINCP)  $(PIINC)
+#  Def compilateur C et flags
+CC = cc 
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+#  Mode 64 bits : flag -64 pour CFLAGS et CXXFLAGS
+CFLAGS = -g3 -O CNFPHFLF
+#  Def compilateur C++ et flags
+CXX =  CC 
+CXXFLAGS = -prelink -LANG:std -g3 -O CNFPHFLF 
+# flags specifiques pour templates repository...
+CXXTEMPFLG = 
+#  Compilo fortran / commande et flags a verifier
+FC = f90 
+FFLAGS = CNFPHFLF 
+# Pour fabriquer les lib .a
+AR = /usr/bin/ar
+ARFLAGS = -rcs
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = so
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXTEMPFLG) -shared 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lpthread -lm 
+LIBFORT = 
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation d executables
+CXXLINK = $(CXX) $(CXXFLAGS)
+CLINK = $(CC) $(CFLAGS)
+FCLINK = $(FC) $(FFLAGS)
+
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -shared
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_g++_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_g++_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_g++_make.inc	(revision 3445)
@@ -0,0 +1,61 @@
+# --------- File Linux_g_make.inc -------- 
+
+#  Liste des librariries externes 
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -lg2c
+
+#  Chemin et librairie pour PI 
+PIINC = -I/usr/X11R6/include/
+PILIBS = -L/usr/X11R6/lib/ -lXm -lXt -lX11 
+
+
+#  Flag preprocesseur
+CPPFLAGS = -DLinux -I$(SOPHYAINCP) $(PIINC)
+#  Def compilateur C et flags
+CC = gcc
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+CFLAGS = -Wall -Wpointer-arith -Wmissing-prototypes -O -g -fPIC  CNFPHFLF
+#  Def compilateur C++ et flags
+CXX =  g++
+#  Flag de warning -Wsynth NON inclus par defaut (04/2007)
+CXXFLAGS = -Wall -Wpointer-arith -O -g -fPIC  CNFPHFLF 
+# flags specifiques pour templates repository...
+CXXTEMPFLG =
+#  Compilo fortran
+FC = g77
+FFLAGS =  
+# Pour fabriquer les lib .a
+AR = ar
+ARFLAGS = -rcs
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = so
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXTEMPFLG) -shared 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lstdc++ -lpthread -lm -lc -ldl 
+LIBFORT = -lg2c
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation dexecutables
+CXXLINK = $(CXX) $(CXXFLAGS)
+CLINK = $(CC) $(CFLAGS)
+FCLINK = $(FC) $(FFLAGS)
+
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -shared
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_icc_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_icc_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/Linux_icc_make.inc	(revision 3445)
@@ -0,0 +1,61 @@
+# --------- File Linux_g_make.inc -------- 
+
+#  Liste des librariries externes 
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -lg2c
+
+#  Chemin et librairie pour PI 
+PIINC = -I/usr/X11R6/include/
+PILIBS = -L/usr/X11R6/lib/ -lXm -lXt -lX11 
+
+
+#  Flag preprocesseur
+CPPFLAGS = -I$(SOPHYAINCP) $(PIINC)
+#  Def compilateur C et flags
+CC = icc
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+CFLAGS = -fpic -O -g  CNFPHFLF 
+#  Def compilateur C++ et flags
+CXX =  icpc
+CXXFLAGS = -fpic -O -frtti -g  CNFPHFLF 
+CXXREP =
+#  Compilo fortran
+FC = ifort
+FFLAGS =  
+# Pour fabriquer les lib .a
+AR = ar
+ARFLAGS = -rcs
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+CXXCOMPILELIB = $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CXXREP) -c 
+CXXCOMPILEPROG = $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CXXREP) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = so
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXREP) -shared 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lpthread -lm -lc -ldl 
+LIBFORT = -lg2c
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation dexecutables
+CXXLINK = $(CXX) $(CXXFLAGS)
+CLINK = $(CC) $(CFLAGS)
+FCLINK = $(FC) $(FFLAGS)
+
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -shared
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/Makefile	(revision 3445)
@@ -0,0 +1,117 @@
+include sophyamake.inc
+
+defaut: libs
+
+all: libs extlibs PI
+libs: cxxlibs
+extlibs : cxxextlibs
+
+cxxlibs::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/BaseTools.conf ] ; then cd  ../BaseTools ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SysTools.conf ] ; then cd  ../SysTools ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SUtils.conf ] ; then cd  ../SUtils ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/TArray.conf ] ; then cd  ../TArray ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/NTools.conf ] ; then cd  ../NTools ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/HiStats.conf ] ; then cd  ../HiStats ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SkyMap.conf ] ; then cd  ../SkyMap ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/Samba.conf ] ; then cd  ../Samba ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SkyT.conf ] ; then cd  ../SkyT ; $(MAKE) ; fi
+
+cxxextlibs::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/FitsIOServer.conf ] ; then cd  ../FitsIOServer ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/IFFTW.conf ] ; then cd  ../IFFTW ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/LinAlg.conf ] ; then cd  ../LinAlg ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/XAstroPack.conf ] ; then cd  ../XAstroPack ; $(MAKE) ; fi
+ 
+PI::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PI.conf ] ; then cd ../PI ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PIGcont.conf ] ; then cd ../PIGcont ; $(MAKE) ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PIext.conf ] ; then cd ../PIext ; $(MAKE) ; fi
+
+#  Shared library creation part of the Makefile
+
+#  main dependence list
+slball : slb slbext slbpi 
+slb : $(SOPHYASLBP)libsophya.$(SLEXT)
+slbext : $(SOPHYASLBP)libextsophya.$(SLEXT)    
+slbpi : $(SOPHYASLBP)libPI.$(SLEXT)
+#  All object modules in a single shared library
+slballinone : $(SOPHYASLBP)libAsophyaextPI.$(SLEXT) 
+
+# List of .o files for SOPHYA  module
+ALLOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+# List of .o files modules with reference to external libraries
+ALLEXTOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+
+# List of .o files for PI modules 
+ALLPIOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+# Building Sophya shared library
+$(SOPHYASLBP)libsophya.$(SLEXT) : $(ALLOBJSF)
+	echo `cat $(ALLOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@  `cat $(ALLOBJSF) ` $(SOPBASELIBS)
+ 
+# Building ExtSophya shared library
+$(SOPHYASLBP)libextsophya.$(SLEXT) : $(ALLEXTOBJSF)
+	echo `cat $(ALLEXTOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@  `cat $(ALLEXTOBJSF) ` \
+	$(SOPHYASLBLIST) $(SOPEXTLIBS)
+
+# Building PI shared library
+$(SOPHYASLBP)libPI.$(SLEXT) : $(ALLPIOBJSF)
+	echo `cat $(ALLPIOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@ `cat $(ALLPIOBJSF) ` \
+	$(SOPHYASLBLIST) $(PILIBS)
+
+# Building a single shared library with all modules Sophya+ExtSophya+PI
+$(SOPHYASLBP)libAsophyaextPI.$(SLEXT) : $(ALLOBJSF) $(ALLEXTOBJSF) $(ALLPIOBJSF)
+	echo `cat $(ALLOBJSF)` ; \
+	echo `cat $(ALLEXTOBJSF)` ; \
+	echo `cat $(ALLPIOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@ \
+	`cat $(ALLOBJSF) ` \
+	`cat $(ALLEXTOBJSF) ` \
+	`cat $(ALLPIOBJSF) ` \
+	$(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+
+#  Cleaning targets
+clean:
+	if [ -d $(SOPHYALIBP) ] ; then cd $(SOPHYALIBP)/. ; rm -f *.a  ; fi
+	if [ -d $(SOPHYASLBP) ] ; then cd $(SOPHYASLBP)/. ; rm -f *.so ; fi
+	if [ -d $(SOPHYAEXEP) ] ; then cd $(SOPHYAEXEP)/. ; rm -f * ; fi
+	if [ -d $(SOPHYAOBJP) ] ; then cd $(SOPHYAOBJP)/. ; rm -rf *.o cxxrep templateregistry ; fi
+
+cleanobj:
+	if [ -d $(SOPHYAOBJP) ] ; then rm -rf $(SOPHYAOBJP) ; fi
+
+#  Various main program builds
+prgall : tests prgutil prgmap progpi
+piapp : progpi
+spiapp : progpi
+
+basetests:
+	cd ../Tests/ ; make arrt carrt tnt tobjio
+
+tests:
+	cd ../Tests/ ; make
+
+prgutil:
+	cd ../PrgUtil/ ; make
+
+progpi:
+	cd ../ProgPI/ ; make
+
+prgmap:
+	cd ../PrgMap/ ; make
+
+pmixer:
+	cd ../PMixer/ ; make
+
+
+
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/OSF1_cxx_make.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/OSF1_cxx_make.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/OSF1_cxx_make.inc	(revision 3445)
@@ -0,0 +1,60 @@
+# --------- File OSF1_cxx_make.inc -------- 
+
+#  Liste des librariries externes 
+SOPEXTLIBS = $(SOPEXTLIBP) $(SOPEXTLIBLIST) -lfor
+
+#  Chemin et librairie pour PI 
+PIINC = 
+PILIBS = -lXm -lXt -lX11 
+
+
+#  Flag preprocesseur
+CPPFLAGS = -DOSF1 -I$(SOPHYAINCP)  $(PIINC)
+#  Def compilateur C et flags
+CC = cc
+# Replace [CNFPHFLF] by specific compilation flags below (done by configure)
+CFLAGS = -O -pthread -g1  CNFPHFLF 
+#  Def compilateur C++ et flags
+CXX =  cxx
+CXXFLAGS = -O -pthread -g1 -no_implicit_include  CNFPHFLF 
+# flags specifiques pour templates repository...
+CXXTEMPFLG = -ptr $(SOPHYAOBJP)/cxxrep/
+#  Compilo fortran
+FC = f77 CNFPHFLF 
+FFLAGS =  
+# Pour fabriquer les lib .a
+AR = /usr/bin/ar
+ARFLAGS = -rcs
+
+
+#  Ordres de compilation
+CCOMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -c 
+CXXCOMPILE = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c 
+FCCOMPILE = $(FC) $(FFLAGS) -c 
+
+#  Extension de nom pour les librairies partagees
+SLEXT = so
+#  Fabrication de librairies partagees 
+CMDSHLCXX = $(CXX) $(CXXFLAGS) $(CXXTEMPFLG) -shared 
+
+
+#  Liste de librairie de base, necessaire pour libsophya
+SOPBASELIBS = -lpthread -lm 
+LIBFORT = -lfor -lFutil -lots -lUfor
+
+# --- Chemin pour l ensemble les librairies SOPHYA , +ExtLibs, +PI
+SOPHYALIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST)  $(SOPBASELIBS)
+SOPHYAEXTLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLLIBLIST = -L$(SOPHYALIBP) $(SOPMODLIBLIST) $(SOPPILIBLIST) $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+SOPHYASLBLIST = -L$(SOPHYASLBP) -lsophya  $(SOPBASELIBS)
+SOPHYAEXTSLBLIST = -L$(SOPHYASLBP) -lextsophya -lsophya $(SOPEXTLIBS) $(SOPBASELIBS)
+SOPHYAALLSLBLIST = -L$(SOPHYASLBP) -lPI -lextsophya -lsophya $(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+#  Commande de link pour creation d executables
+CXXLINK = $(CXX) $(CXXFLAGS)
+CLINK = $(CC) $(CFLAGS)
+FCLINK = $(FC) $(FFLAGS)
+
+#  Commande de link pour creation de module pouvant etre charge dynamiquement
+CXXDLL = $(CXX) $(CXXFLAGS) -shared
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/README
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/README	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/README	(revision 3445)
@@ -0,0 +1,189 @@
+======================== BuildMgr Module ======================
+== Code Management scripts / top level makefile for SOPHYA ====
+===============================================================
+              (C) LAL-IN2P3/CNRS   1998-2007 
+              (C) DAPNIA/CEA       1998-2007
+===============================================================
+
+### README file for SOPHYA Build makefiles and scripts (BuildMgr) ####
+See http://www.sophya.org and the SOPHYA overview manual for more information
+
+
+====================================
+A/ Software build and installation :
+====================================
+
+1/ Configuration: 
+csh> cd BuildMgr/
+csh> ./configure -h
+# configure with c-fitsio, installed in /usr/local/include and /usr/local/lib, 
+# with g++ as cxx compiler. The target installation directory is $HOME/SObjs/ 
+# To get c-fitsio : http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html
+
+
+# Create the target installation directory (if not already existing)
+csh> mkdir ~/SObjs
+# Define the SOPHYABASE environment variable
+csh> setenv $SOPHYABASE ~/SObjs/
+# run the configure script 
+csh> ./configure -sbase $SOPHYABASE -scxx g++ -extp /usr/local 
+     -noext fftw -noext lapack -noext astro
+
+2/ compile and build the libraries
+csh> make libs extlibs slb slbext 
+# Or if you want to compile also PI (need Motif or Lesstif)
+csh> make all slball 
+
+3/ Compile some test and utility programs
+csh> make basetests prgutil 
+# To compile piapp
+csh> make piapp 
+
+4/ You can clean the .o files, if you are not going to recompile after 
+changing or update source files
+csh> make cleanobj
+
+5/ List of Makefile targets
+  > libs extlibs PI = all 
+  > slb slbext slbpi = slball    (OR = slballinone)
+  > clean  cleanobj
+  > tests prgutil prgmap progpi = prgall 
+  > basetests piapp (ou progpi)  pmixer 
+
+6/ Currently tested on the following platform/compilers
+-------------------------------------------------------------------------
+Linux 2.4 , 2.6              g++ 3.x 4.0     (GNU g++ compiler)             
+MacOSX/Darwin 10.3/10.4      g++ 3.3,4.0     (Apple/GNU compiler)
+Linux 2.4                    icc 9.0         (Intel compiler)                  
+HP/Compaq/DEC OSF 5.x        cxx 6.x         (native Tru64/OSF compiler)
+SGI IRIX64                   CC  7.30        (IRIX-64 native compiler)
+IBM AIX (5.3)                xlC 8.0         (AIX native compiler)
+-------------------------------------------------------------------------
+
+============================
+B/ Code management scripts :
+============================
+
+1/ configure : c-shell script configuration 
+   ./configure -sbase /tmp/sbase/ -scxx cxx -extp /usr/local/extlibs
+
+2/ mkmflib : c-shell script for creation of library module Makefile / smakefile
+   ./mkmflib -sbase /tmp/sbase SUtils
+
+3/ mkmfprog : c-shell script for creation of programs module Makefile / smakefile
+   ./mkmfprog -sbase /tmp/sbase SUtils
+
+4/ domkmf : c-shell script : calls mkmflib for all modules 
+   ./domkmf -sbase /tmp/sbase
+
+5/ chk_cvs.csh : Compares/updates modules using CVS
+  Usage: chk_cvs.csh [-a] [-all] [-nos] [-u] [r]
+         chk_cvs.csh  -h  for help
+
+6/ Makefile/smakefile : Top level makefile for library and program modules 
+
+7/ Configuration files used to generate sophyamake.inc
+   - Linux_g++_make.inc: Linux with g++ compiler 
+   - OSF1_cxx_make.inc:  HP/Compaq/Digital Tru64 with native cxx compiler
+   - Darwin_g++_make.inc: Apple/MacOSX with the native GNU compiler
+   - IRIX64_CC_make.inc: SGI IRIX-64 system and native CC compiler 
+   - AIX_xlC_make.inc : IBM AIX system and compiler xlC 
+   - Linux_icc_make.inc : Linux with Intel compiler
+
+
+==========================================
+C/ List of modules SOPHYA and PI modules :
+==========================================
+
+* BuildMgr/      Scripts for code management and makefiles
+* BaseTools/     General architecture support classes
+* TArray/        Template numerical arrays, vectors and matrices
+* HiStats/       Histogram-ming and data set handling classes
+* NTools/        Some standard numerical analysis tools 
+* SUtils/        Utility classes and functions
+* SysTools/      Interface to various services provided by the operating system
+* SkyMap/        Local and full sky maps
+* SkyT/          Spectral emission and detector frequency response modelling   
+* Samba/         Miscellaneous classes (TOD analysis, Spherical Harmonics, ...)
+
+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
+
+
+================================================
+D/ How to use Sophya libraries and/or programs :
+================================================
+
+1./ Set the Sophya environment variable :
+  that is the repository where the libraries and the programs stand,
+  for example:
+  > setenv SOPHYABASE /home/.../SophyaWork
+
+  ..Remark:
+  The choice of the name is up to you, but if you want
+  to use versions on different operating systems (or compilators)
+  the "SOPHYABASE" repository must be different, for example:
+  > setenv SOPHYABASE /home/.../SophyaWork_Linux_gcc2.95
+  > setenv SOPHYABASE /home/.../SophyaWork_Linux_gcc4
+  > setenv SOPHYABASE /home/.../SophyaWork_OSF1_cxx
+  > setenv SOPHYABASE /home/.../SophyaWork_OSF1_gcc
+  > ...
+
+  So you will find:
+  ..shared libraries   in:  $SOPHYABASE/slb
+  ..archived libraries in:  $SOPHYABASE/lib
+       (you will probably prefer to use the shared versions of the libraries)
+  ..programs           in:  $SOPHYABASE/exe
+  ..include files      in:  $SOPHYABASE/include
+       (you will only need it if you write code using sophya libraries)
+  ..object files       in:  $SOPHYABASE/obj
+       (you probably should not have to use it)
+
+2./ Using Sophya shared libraries:
+  As you would do for any software,
+  add the repository name of Sophya shared libraries to LD_LIBRARY_PATH
+  > setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${SOPHYABASE}/slb
+
+3./ Using Sophya programs:
+  As you would do for any software,
+  add the repository name of Sophya programs to PATH
+  > setenv PATH ${PATH}:${SOPHYABASE}/exe
+  then recomputed the internal hash table for executables
+  > rehash
+
+4./ Using external libraries which are wrapped in Sophya external modules:
+  Sophya is presently using the archived version of the external libraries
+  so nothing special have to be done.
+
+5./ Making your own programs:
+  If you are writing code using Sophya you may like to
+     "include $(SOPHYABASE)/include/sophyamake.inc"
+  in your own Makefile.
+  That will provide you with default variables for the libraries repositories
+  and names as well as standard compilation and link options for
+  various current OS and compilators.
+     (please see: > more $SOPHYABASE/include/sophyamake.inc )
+  That is JUST AN HELP that Sophya provides, you may prefer
+  to deal YOURSELF with libraires path/names and compiler/linker options.
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/change_smake2make.csh
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/change_smake2make.csh	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/change_smake2make.csh	(revision 3445)
@@ -0,0 +1,38 @@
+#!/bin/csh
+# Pour changer "smakefile" en "Makefile"
+# - Pas d'argument: tous les repertoire CVS sous la racine
+# - $1 : nom du perpertoire a traiter
+# ATTENTION: a lancer depuis la racine Sophya:
+# > ./BuildMgr/change_smake2make.csh
+# > ./BuildMgr/change_smake2make.csh XephemAstroLib
+set CURDIR = `pwd`
+
+#--- Recherche des repertoires sous CVS
+if( $#argv > 0 ) then
+  set dcvs = $1
+else
+  set dcvs =
+  foreach f ( `ls -1` )
+    if( -e $f/CVS ) set dcvs = ( $dcvs $f )
+  end
+endif
+
+#--- Action CVS dans chacun des repertoires concernes
+foreach d ( $dcvs )
+  if (-e $CURDIR/$d)  then
+    cd $CURDIR/$d
+    if( ! -e Makefile ) continue
+    if( ! -e smakefile ) continue
+    grep -q 'include ../BuildMgr/sophyamake.inc' Makefile
+    if( $status != 0 ) continue
+    grep -q 'include $(SOPHYABASE)/include/sophyamake.inc' smakefile
+    if( $status != 0 ) continue
+    sed 's?include $(SOPHYABASE)/include/sophyamake.inc?include ../BuildMgr/sophyamake.inc?' smakefile >! Makefile
+    echo ">>> $d : Makefile generated from smakefile"
+    diff smakefile Makefile
+  endif
+end
+
+
+exit 0
+
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/chk_cvs.csh
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/chk_cvs.csh	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/chk_cvs.csh	(revision 3445)
@@ -0,0 +1,65 @@
+#!/bin/csh
+
+#--- Decodage arguments
+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 CURDIR = `pwd`
+if( $?U ) echo "attention...... UPDATE demande"
+
+#--- Recherche des repertoires sous CVS
+set fall = (`ls -1`)
+set dcvs = ( )
+foreach f ( $fall )
+  if( -e $f/CVS ) set dcvs = ( $dcvs $f )
+end
+
+#--- Action CVS dans chacun des repertoires concernes
+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_Nov2007/SophyaLib/BuildMgr/configure
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/configure	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/configure	(revision 3445)
@@ -0,0 +1,606 @@
+#!/bin/csh
+#  SOPHYA configuration managment script 
+#  C. Magneville / R. Ansari   -      Mai 2005
+#     Updated : 2006, Avr/Mai , Oct 2007
+# Exemple: ./configure -sbase /laltmp/ansari/sbase/ -scxx cxx -extp /exp/planck/ExtLibs/Include/ \
+#              -extp /exp/planck/ExtLibs/OSF1-cxx/
+
+#----------------------------------------------------------------------
+#### liste des modules
+set SOPMODOK = ( 1 1 1 1 1 1 1 1 1 )
+set SOPMOD = ( BaseTools SysTools SUtils TArray NTools HiStats SkyMap Samba SkyT )
+set ALLSOPLIBS = ( '-lBaseTools' '-lSysTools' '-lSUtils' '-lTArray' '-lNTools' '-lHiStats' '-lSkyMap' '-lSamba' '-lSkyT' )
+
+set SOPPIOK = ( 1 1 1 )
+set SOPPI = ( PI PIext PIGcont )
+set ALLPILIBS = ( '-lPI' '-lPIext' '-lPIGcont' )
+
+set SOPEXT     = ( FitsIOServer  IFFTW  LinAlg  XAstroPack )
+set EXTCURNAME = ( fits          fftw   lapack  astro      )
+set SOPEXTOK   = ( 1             1      1       1          )
+set EXTINCNAME = ( FitsIO/fitsio.h FFTW/fftw3.h  PASDEINC XAstro/astro.h )
+set EXTLIBNAME = ( libcfitsio.a libfftw3.a liblapack.a libxastro.a )
+set ALLEXTLIBS = ( '-lcfitsio' '-lfftw3' '-llapack -lblas' '-lxastro' )
+
+#FFTW2: set EXTINCNAME = ( FitsIO/fitsio.h FFTW/fftw.h  PASDEINC XAstro/astro.h )
+#FFTW2: set EXTLIBNAME = ( libcfitsio.a libfftw.a liblapack.a libxastro.a )
+#FFTW2: set ALLEXTLIBS = ( '-lcfitsio' '-lfftw -lrfftw' '-llapack -lblas' '-lxastro' )
+
+set defextinc = ( /usr/include /usr/local/include )
+set defextlib = ( /usr/lib /usr/local/lib )
+
+
+#----------------------------------------------------------------------
+#### Decodage arguments
+set cmdline = "$0 $*" 
+set extpath
+set extpathinc
+set extpathlib
+unset incln
+unset mincname
+set compopt 
+unset arch64
+unset sasz64
+unset nofpic
+unset nothsafe
+unset boundcheck
+unset sodebug
+unset usefftw2
+unset uselapack2
+unset alsofftwfloat
+unset slballinone
+while ( $#argv > 0 )
+
+if( "$1" == "-h" ) then
+  echo 'configure [-sbase SOPHYABASE] [-scxx SOPHYACXX] [-incln] '
+  echo "  [-minc mymake.inc]  [-compopt 'cc/cxxOptions'] "
+  echo '  [-arch64] [-sasz64] [-nofpic] [-nothsafe] [-boundcheck] [-sodebug]'
+  echo '  [-extp dir1 -extp dir2 ...] [-extip dir1 -extip dir2 ... ] [-extlp dir1 -extlp dir2 ... ]'
+  echo '  [-noextlib] [-noext fits] [-noext fftw] [-noext lapack] [-noext astro]'
+  echo '  [-noPI] [-slballinone]'
+  echo '  [-alsofftwfloat] [-usefftw2] [-uselapack2] '
+  echo '  (See SOPHYA manual/web pages for a detailed description of configure options)'
+  exit -1
+endif
+if( "$1" == "-sbase" ) then
+  setenv SOPHYABASE $2
+  shift
+endif
+if( "$1" == "-scxx" ) then
+  setenv SOPHYACXX $2
+  shift
+endif
+if( "$1" == "-incln" ) then
+  set incln
+endif
+if( "$1" == "-minc" ) then
+  set mincname = ( $2 )
+  shift
+endif
+if( "$1" == "-compopt" ) then
+  set compopt = ( $2 )
+  shift
+endif
+if( "$1" == "-extp" ) then
+  set extpath = ( $extpath $2 )
+  shift
+endif
+if( "$1" == "-extip" ) then
+  set extpathinc = ( $extpathinc $2 )
+  shift
+endif
+if( "$1" == "-extlp" ) then
+  set extpathlib = ( $extpathlib $2 )
+  shift
+endif
+if( "$1" == "-noextlib" ) then
+  set i = 0
+  while ( $i < $#SOPEXTOK )
+    @ i += 1
+    set SOPEXTOK[$i] = 0
+  end  
+endif
+if( "$1" == "-noext" ) then
+  set i = 0
+  while ( $i < $#EXTCURNAME )
+    @ i += 1
+    if( "$2" == "$EXTCURNAME[$i]" ) set SOPEXTOK[$i] = 0
+  end
+  shift
+endif
+if( "$1" == "-PI" ) then
+  set SOPPIOK = ( 0 0 0 )
+endif
+if( "$1" == "-alsofftwfloat" ) then
+# On veut la version float de FFTW, en plus de double
+  set alsofftwfloat
+  set i = 0
+  while ( $i < $#EXTCURNAME )
+    @ i += 1
+    if( "fftw" == "$EXTCURNAME[$i]" ) then
+       set ALLEXTLIBS[$i] = '-lfftw3 -lfftw3f'
+    endif
+  end
+endif
+if( "$1" == "-usefftw2" ) then
+# version FFTW 2 au lieu de V3
+  set usefftw2
+  set i = 0
+  while ( $i < $#EXTCURNAME )
+    @ i += 1
+    if( "fftw" == "$EXTCURNAME[$i]" ) then
+       set EXTINCNAME[$i] = 'FFTW/fftw.h'
+       set EXTLIBNAME[$i] = 'libfftw.a'
+       set ALLEXTLIBS[$i] = '-lfftw -lrfftw'
+    endif
+  end
+endif
+if( "$1" == "-uselapack2" ) then
+# version LAPACK 2 au lieu de V3
+  set uselapack2
+endif
+if( "$1" == "-slballinone" ) then
+# Pour utiliser une seule librairie libsophyaPIext.so au lieu 
+#   des 3 libsophya.so libextsophya.so libPI.so
+  set slballinone
+endif
+#  Decodage options pour flags de machdefs.h 
+#  Liste de flags : SO_ARCH64 SO_NOFPIC SO_SASIZET64 SO_BOUNDCHECKING SOPHYA_DEBUG
+if( "$1" == "-arch64" ) then
+  set arch64
+endif
+if( "$1" == "-sasz64" ) then
+  set sasz64
+endif
+if( "$1" == "-nofpic" ) then
+  set nofpic
+endif
+if( "$1" == "-nothsafe" ) then
+  set nothsafe
+endif
+if( "$1" == "-boundcheck" ) then
+  set boundcheck
+endif
+if( "$1" == "-sodebug" ) then
+  set sodebug
+endif
+
+
+shift
+end
+
+## ------ Detection linux 64 bits ---
+unset linux64
+if ( `uname`  == "Linux" ) then 
+  if ( `uname -m` == "x86_64" ) then 
+    echo ' ... Linux x86_64 (64 bits) ---> -arch64 ' 
+    set linux64
+    set arch64
+  endif
+endif
+
+
+#----------------------------------------------------------------------
+#### Verification generale
+if( ! $?SOPHYABASE ) then
+  echo ERROR: define SOPHYABASE or use script arguments
+  exit -2
+endif
+if( ! $?SOPHYACXX ) then
+  echo ERROR: define SOPHYACXX or use script arguments
+  echo "   SOPHYACXX define the name of the C++ compiler (ex: g++ cxx ...)"
+  exit -2
+endif
+if( ! $?TMPDIR ) setenv TMPDIR /tmp
+touch $TMPDIR/tmp_test
+if( $status != 0 ) then
+  echo ERROR: no write acces in temporary directory: $TMPDIR
+  echo '----> define TMPDIR environment variable: "setenv TMPDIR ..."'
+  exit -2
+endif
+rm -f $TMPDIR/tmp_test
+if( ! $?mincname ) then
+  set mincname = `uname`_${SOPHYACXX}_make.inc
+endif
+if( ! -e $mincname ) then
+  echo ERROR: file $mincname NOT found
+  exit -2
+endif
+if( ! -e ../BaseTools/machdefs_mkmf.h ) then
+  echo ERROR: file machdefs_mkmf.h NOT found in BaseTools
+  exit -2
+endif
+echo SOPEXTOK: $SOPEXTOK
+
+#----------------------------------------------------------------------
+#### creation des variables chemins sophya core
+echo " "
+echo ">>>>>> 1/ Creating directory tree under $SOPHYABASE  "
+set sinc = $SOPHYABASE/include
+set slib = $SOPHYABASE/lib
+set sslb = $SOPHYABASE/slb
+set sobj = $SOPHYABASE/obj
+set sexe = $SOPHYABASE/exe
+set sconf = $sinc/SophyaConfInfo
+foreach d ( $sinc $slib $sslb $sobj $sexe $sconf )
+  if( ! -d $d ) then
+    mkdir $d
+    if( $status ) then
+      echo ERROR: creation of $d failed
+      exit -3
+    endif
+    echo Directory $d created
+  endif
+  touch $d/tmp_test
+  if( $status ) then
+    echo ERROR: no write acces to $d
+    exit -4
+  endif
+  rm -f $d/tmp_test
+end
+
+
+#----------------------------------------------------------------------
+#### Fichier confinfo - log e configure
+set conflog = $sconf/conf.log
+rm -f $conflog ; touch $conflog 
+echo ' --- Log of SOPHYA configure script - Date= ' `date` >> $conflog
+echo "$cmdline"  >> $conflog
+set inclistf = $sconf/include.list
+rm -f $inclistf ; touch $inclistf
+
+
+#----------------------------------------------------------------------
+#### liens ou copie des *.h
+echo " "
+if( $?incln ) then
+  echo ">>>>>> 2/ Creating symbolic link for include files in $sinc "
+else
+  echo ">>>>>> 2/ Copying include files to $sinc "
+endif
+
+cd ../  > /dev/null
+set srcd = `pwd`
+set cpln = "cp -p "
+if( $?incln ) set cpln = "ln -s -f  "
+foreach d ( $SOPMOD $SOPEXT $SOPPI )
+  if ( -d $srcd/$d ) then
+    if ( $?incln ) then 
+      echo Creating link to include files for module $d
+    else 
+      echo Copying include files for module $d
+    endif
+
+    cd $srcd/$d;
+    set file = ( *.h )
+    cd $sinc;  if( $status == 0 ) rm -f $file
+    # on vire le .h de $file si .h dans excludeinc du module
+    cd $srcd/$d
+    if( -e excludeinc ) then
+      if( `cat excludeinc | wc -l` > 0 ) then
+        set file
+        foreach f ( *.h )
+          grep -q "$f:r\.h" excludeinc
+          if( $status != 0 ) set file = ( $file $f )
+        end
+      endif
+    endif
+    # on copie ou link dans $sinc
+    if( `echo $file | wc -w` > 0 ) then
+      foreach f ( $file )
+        $cpln $srcd/$d/$f  $sinc/$f
+      end
+    endif
+    echo $file >> $inclistf
+  endif
+end
+rm -f $sinc/machdefs_ac.h $sinc/machdefs_mkmf.h 
+cd $srcd/BuildMgr/.
+
+
+#----------------------------------------------------------------------
+#### lien  des .h des librairies externes
+echo " "
+echo ">>>>>> 3/  Include files for external libraries "
+set i = 0
+while ( $i < $#SOPEXT )
+  @ i += 1
+  if( "$EXTINCNAME[$i]" == "PASDEINC" ) continue
+  if( $SOPEXTOK[$i] <= 0 ) continue
+  set nom = $EXTINCNAME[$i]:t
+  set rac = $EXTINCNAME[$i]:h
+  if( -d ../$SOPEXT[$i] ) then
+    echo "Searching include file for $SOPEXT[$i] ..."
+    foreach d ( $extpathinc $extpath $defextinc )
+      set duminc = `find $d -name $nom -print -follow | head -1 `
+      set dumrep = $duminc:h
+      if ( "$dumrep" != "" ) then
+        rm -f $sinc/$rac
+        ln -f -s $dumrep $sinc/$rac
+        echo Includes for $SOPEXT[$i] found in $dumrep
+        break
+      endif
+    end
+    if ( "$dumrep" == "" ) then
+      echo WARNING: Includes for $SOPEXT[$i] NOT found
+      echo "    Compilation of module  $SOPEXT[$i] disabled"
+      set SOPEXTOK[$i] = 0
+    endif
+  endif
+end
+
+
+#----------------------------------------------------------------------
+#### liens des librairies externes
+echo " "
+echo ">>>>>> 4.1/  External libraries "
+set fpath = $TMPDIR/fpath
+rm -f $fpath; touch $fpath
+set extliblib
+set i = 0
+while ( $i < $#SOPEXT )
+  @ i += 1
+  if( "$EXTLIBNAME[$i]" == "PASDELIB" ) continue
+  if( $SOPEXTOK[$i] <= 0 ) continue
+  set nom = $EXTLIBNAME[$i]
+  if( -d ../$SOPEXT[$i] ) then
+    echo "Searching libraries path for $SOPEXT[$i] ..."
+    foreach d ( $extpathlib $extpath $defextlib )
+      set dumlib = `find $d -name $nom -print -follow | head -1 `
+      if ( "$dumlib" != "" ) then
+        echo "-L$dumlib:h" >> $fpath
+        set extliblib = ( $extliblib $ALLEXTLIBS[$i] )
+        break
+      endif
+    end
+    if ( "$dumlib" == "" ) then
+      echo WARNING: Libraries for $SOPEXT[$i] NOT found
+      echo "    Check the generated make.inc file"
+    endif
+  endif
+end
+set extlibpath = `cat $fpath | sort -u`
+echo extlibpath= $extlibpath
+echo extliblib= $extliblib
+rm -f $fpath
+
+
+#----------------------------------------------------------------------
+#### Identification des librairies archives Sophya
+echo " "
+echo ">>>>>> 4.2/  Sophya libraries archives "
+set sopmodlib
+set i = 0
+while ( $i < $#SOPMOD )
+  @ i += 1
+  if( $SOPMODOK[$i] <= 0 ) continue
+  if( -d ../$SOPMOD[$i] ) then
+    set sopmodlib = ( $sopmodlib $ALLSOPLIBS[$i] )
+  else
+    echo "WARNING: module "$SOPMOD[$i]" not found"
+  endif
+end
+echo sopmodlib= $sopmodlib
+
+echo " "
+echo ">>>>>> 4.3/  PI-Sophya libraries archives "
+set soppilib
+set i = 0
+while ( $i < $#SOPPI )
+  @ i += 1
+  if( $SOPPIOK[$i] <= 0 ) continue
+  if( -d ../$SOPPI[$i] ) then
+    set soppilib = ( $soppilib $ALLPILIBS[$i] )
+  else
+    echo "WARNING: module "$SOPPI[$i]" not found"
+  endif
+end
+echo soppilib= $soppilib
+
+#----------------------------------------------------------------------
+#### Generation de sophyamake.inc
+#  On le cree dans le repertoire temporaire d'abord 
+set mfile = $sinc/sophyamake.inc
+rm -f $mfile
+echo " "
+echo ">>>>>> 5/  Creating $mfile from $mincname "
+echo "# -----------------------------------------------" > $mfile
+echo "#  File make.inc - generated by SOPHYA configure" >> $mfile
+echo "#  Date" `date` >> $mfile 
+echo "#  Seed file : $mincname " >> $mfile 
+echo "# -----------------------------------------------" >> $mfile
+echo " " >> $mfile 
+echo "# SOPHYA Base installation directory " >> $mfile 
+echo "SOPHYABASE = $SOPHYABASE" >> $mfile
+echo " " >> $mfile 
+echo 'SOPHYAINCP = $(SOPHYABASE)/include/' >> $mfile
+echo 'SOPHYAOBJP = $(SOPHYABASE)/obj/' >> $mfile
+echo 'SOPHYALIBP = $(SOPHYABASE)/lib/' >> $mfile
+echo 'SOPHYASLBP = $(SOPHYABASE)/slb/' >> $mfile
+echo 'SOPHYAEXEP = $(SOPHYABASE)/exe/' >> $mfile
+
+echo " " >> $mfile 
+echo "# module libraries  " >> $mfile
+echo "SOPMODLIBLIST = $sopmodlib" >> $mfile
+
+echo " " >> $mfile 
+echo "# External libraries PATH  " >> $mfile
+echo "SOPEXTLIBP = $extlibpath"  >> $mfile
+echo "SOPEXTLIBLIST = $extliblib" >> $mfile
+
+echo " " >> $mfile 
+echo "# PI libraries  " >> $mfile
+echo "SOPPILIBLIST = $soppilib" >> $mfile
+
+echo " " >> $mfile 
+cat $mincname >> $mfile
+
+# --- Gestion des flags modifiants les options de compilation et liste de librairies (par sed)
+set sname = `uname`
+set sprgfile = $TMPDIR/compop.scom  
+echo '{' > $sprgfile 
+set scmd = "/FLAGS/s/CNFPHFLF/ $compopt/g"
+if ( $?arch64 ) then
+  set a64cf = ' '
+  if ( ( "$sname" == "IRIX64" ) && ("$SOPHYACXX" == "CC" ) ) set a64cf = '-64'
+  if ( "$sname" == "AIX" ) then 
+    if ( ("$SOPHYACXX" == "xlC" ) || ("$SOPHYACXX" == "xlc" ) )  set a64cf = '-q64'
+    echo "/ARFLAGS/s/-rcs/-rcs -X 64/" >>  $sprgfile 
+  endif
+  set scmd = "/FLAGS/s/CNFPHFLF/$a64cf $compopt/g"
+endif
+echo $scmd >> $sprgfile
+if ( $?nofpic ) echo "s/-fPIC/ /g" >>  $sprgfile
+if( $?slballinone ) then 
+  echo "/SOPHYAALLSLBLIST/s/-lPI -lextsophya -lsophya/-lAsophyaextPI/" >>  $sprgfile 
+  echo "/SOPHYAEXTSLBLIST/s/-lextsophya -lsophya/-lAsophyaextPI/" >>  $sprgfile 
+endif
+if ( $?linux64 ) then
+  echo "s?-L/usr/X11R6/lib?-L/usr/X11R6/lib64?g" >>  $sprgfile 
+endif
+echo '}' >> $sprgfile 
+set mftmp = $TMPDIR/sopmake.inc
+cp $mfile $mftmp
+sed -f $sprgfile $mftmp >   $mfile
+rm -f $sprgfile $mftmp
+# --- FIN de gestion des flags modifiants les options de compilation (par sed)
+
+rm -f $mfile:t
+ln -s $mfile $mfile:t
+
+
+#----------------------------------------------------------------------
+#### Copie de machdefs.h
+set mdefname = $TMPDIR/machdefs.h
+echo " "
+echo ">>>>>> 6.a/  Creating  machdefs.h from BaseTools/machdefs_mkmf.h"
+rm -f $mdefname; touch $mdefname
+echo "/*** machdefs.h generated by SOPHYA configure ***/" >> $mdefname
+echo "#ifndef MACHDEFS_SEEN" >> $mdefname
+echo "#define MACHDEFS_SEEN" >> $mdefname
+echo "/*------ Code generation switch ---- */" >> $mdefname
+echo "/*   System selector (uname) */" >> $mdefname
+# Fait avant - set sname = `uname`
+echo "#ifndef $sname" >> $mdefname
+echo "#define $sname 1 "  >> $mdefname
+echo "#endif" >> $mdefname
+
+## Definition de flags de compilation en fonction des options de configure 
+if ( $?arch64 )  echo "#define SO_ARCH64  1" >> $mdefname
+if ( $?sasz64 )  echo "#define SO_SASIZET64  1" >> $mdefname
+if ( $?nofpic )  echo "#define SO_NOFPIC  1" >> $mdefname
+if ( $?nothsafe )  echo "#define SO_NOTHSAFE  1" >> $mdefname
+if ( $?boundcheck )  echo "#define SO_BOUNDCHECKING  1" >> $mdefname
+if ( $?sodebug )  echo "#define SOPHYA_DEBUG  1" >> $mdefname
+
+if ( "$sname" == "IRIX64" ) then
+  if ( "$SOPHYACXX" == "CC" ) then
+#  __SGICC__ : flag indiquant que c'est le compilo CC de SGI 
+    echo "#define __SGICC__ 1" >> $mdefname
+  endif
+endif
+
+
+echo " " >> $mdefname 
+grep -v -e '#ifndef *MACHDEFS_SEEN' -e '#define *MACHDEFS_SEEN' ../BaseTools/machdefs_mkmf.h >> $mdefname
+#  On ne copie que si machdefs.h est different 
+if (-e $sinc/machdefs.h ) then 
+  diff $mdefname $sinc/machdefs.h >& /dev/null
+  if ($status != 0) then 
+    cp -f -p $mdefname $sinc/machdefs.h 
+    echo " file $sinc/machdefs.h changed -> replaced"    
+  else 
+    echo " file $sinc/machdefs.h has not changed -> kept"
+  endif
+else
+  cp -f -p $mdefname $sinc/machdefs.h  
+  echo " file $sinc/machdefs.h created"    
+endif
+rm -f $mdefname
+
+
+#### Creation de sspvflags.h
+echo " "
+echo ">>>>>> 6.b/  Creating  $sinc/sspvflags.h "
+rm -f $sinc/sspvflags.h; touch $sinc/sspvflags.h
+
+echo "#ifndef SSPVFLAGS_SEEN" >> $sinc/sspvflags.h
+echo "#define SSPVFLAGS_SEEN" >> $sinc/sspvflags.h
+echo " " >> $sinc/sspvflags.h 
+echo "/*------ External libraries no-use flag ---- */" >> $sinc/sspvflags.h
+set i = 0
+while ( $i < $#SOPEXTOK )
+  @ i += 1
+  if( $SOPEXTOK[$i] > 0 ) continue
+  echo "#define SOPHYA_NO_$SOPEXT[$i]" >> $sinc/sspvflags.h
+end
+
+echo " " >> $sinc/sspvflags.h 
+echo "/*------ SOPOHYA/ExtLibsvVersion selection flags ---- */" >> $sinc/sspvflags.h
+echo " " >> $sinc/sspvflags.h 
+if( $?alsofftwfloat ) then
+  echo "/*-- Compile ALSO float version of FFTWServer methods -- */" >> $sinc/sspvflags.h
+  echo "#define ALSO_FFTW_FLOAT_EXTSOP" >> $sinc/sspvflags.h
+endif
+if( $?usefftw2 ) then
+  echo "/*-- Use FFTW V2 instead of V3 -- */" >> $sinc/sspvflags.h
+  echo "#define FFTW_V2_EXTSOP" >> $sinc/sspvflags.h
+endif
+if( $?uselapack2 ) then
+  echo "/*-- Use LAPACK V2 instead of V3 -- */" >> $sinc/sspvflags.h
+  echo "#define LAPACK_V2_EXTSOP" >> $sinc/sspvflags.h
+endif
+echo " " >> $sinc/sspvflags.h 
+if( $?slballinone ) then
+  echo "/*------ Use of single shared lib for SOPHYA+extlibs+PI ---- */" >> $sinc/sspvflags.h
+  echo "#define SO_SLBALLINONE " >> $sinc/sspvflags.h
+endif
+echo " " >> $sinc/sspvflags.h 
+echo "#endif " >> $sinc/sspvflags.h 
+
+
+#----------------------------------------------------------------------
+#### Creation des fichiers contenant les listes d'objets et d'includes
+echo " "
+echo ">>>>>> 7/  Creating object list files for shared library creation "
+set objlistname = $sconf/libsophya.objlist
+echo " 7.a/ Creating $objlistname "
+rm -f $objlistname ; touch $objlistname
+foreach d ( $SOPMOD )
+  rm -f $sconf/$d.conf
+  if ( ! -d ../$d ) continue 
+  cat ../$d/objlist.list >> $objlistname
+  touch $sconf/$d.conf
+end
+
+set objlistname = $sconf/libextsophya.objlist
+echo " 7.b/ Creating $objlistname "
+rm -f $objlistname ; touch $objlistname
+set i = 0
+while ( $i < $#SOPEXT )
+  @ i += 1
+  set d = $SOPEXT[$i]
+  rm -f $sconf/$d.conf
+  if( $SOPEXTOK[$i] <= 0 ) continue
+  if ( ! -d ../$d ) continue
+  cat ../$d/objlist.list >> $objlistname
+  touch $sconf/$d.conf
+end  
+
+set objlistname = $sconf/libPI.objlist
+echo " 7.c/ Creating $objlistname "
+rm -f $objlistname ; touch $objlistname
+set i = 0
+while ( $i < $#SOPPI )
+  @ i += 1
+  set d = $SOPPI[$i]
+  rm -f $sconf/$d.conf
+  if( $SOPPIOK[$i] <= 0 ) continue
+  if ( ! -d ../$d ) continue
+  cat ../$d/objlist.list >> $objlistname
+  touch $sconf/$d.conf
+end
+
+
+#----------------------------------------------------------------------
+exit 0
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/domakeprogs
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/domakeprogs	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/domakeprogs	(revision 3445)
@@ -0,0 +1,7 @@
+#!/bin/csh
+foreach f ( ProgPI PrgUtil PrgMap Tests PMixer )
+cd ../$f 
+pwd
+echo "make in $f " 
+time make
+end
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/domkmf
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/domkmf	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/domkmf	(revision 3445)
@@ -0,0 +1,32 @@
+#!/bin/csh
+#  Script pour enchainer la fabrication des makefiles SOPHYA
+#  Mettre les options de mkmflib comme argument
+
+# ---- Pour debugger
+# set DO = 'echo'
+set DO = ''
+
+echo " ==== Creation smakefile pour les modules SOPHYA ====" 
+foreach f ( BaseTools SysTools SUtils TArray NTools HiStats SkyMap Samba SkyT )
+  set cmd = "./mkmflib $* $f" 
+  $DO $cmd 
+end
+
+echo " ==== Creation smakefile pour les modules EXTLIBS_SOPHYA ===="
+foreach f ( FitsIOServer IFFTW LinAlg XAstroPack )
+  set cmd = "./mkmflib $* $f" 
+  $DO $cmd 
+end
+
+echo " ==== Creation smakefile pour les modules PI ====" 
+foreach f ( PI PIGcont PIext )
+  set cmd = "./mkmflib $* $f" 
+  $DO $cmd 
+end
+
+echo " ==== Creation smakefile pour les modules de Programmes ====" 
+#foreach f ( ProgPI PrgUtil PrgMap Tests PMixer )
+foreach f ( ProgPI PrgUtil PrgMap PMixer )
+  set cmd = "./mkmfprog $* $f" 
+  $DO $cmd 
+end
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/mkdepend.csh
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/mkdepend.csh	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/mkdepend.csh	(revision 3445)
@@ -0,0 +1,35 @@
+#!/bin/csh
+# Pour ecrire les dependances a l'ecran
+
+if( $#argv < 1) then 
+  echo ' Usage: mkdepend.csh [-sbase SOPHYABASE] nom_fichier.{cc,c,f}'
+  exit -1
+endif
+
+set file = $argv[$#argv]
+while ( $#argv > 0 )
+  if( "$1" == "-sbase" ) then
+    setenv SOPHYABASE $2
+    shift
+  endif
+  shift
+end
+
+if( ! $?SOPHYABASE ) then
+  echo 'ERROR:  define SOPHYABASE or use script arguments'
+  exit -2
+endif
+
+set inc = `echo $SOPHYABASE/include | sed "s?//?/?g"`
+set nomsys = `uname`
+set ext = $file:e
+
+if( "$ext" == "cc" || "$ext" == "cxx" || "$ext" == "C" || "$ext" == "c" ) then
+  gcc -MM -D$nomsys -I$inc $file  \
+       | sed -e 's/.*\.o/\$(SOPHYAOBJP)&/'  \
+       | sed -e 's?'$inc/'?$(SOPHYAINCP)?g'
+else
+  echo "extension $ext not treated"
+endif
+
+exit 0
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/mkmflib
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/mkmflib	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/mkmflib	(revision 3445)
@@ -0,0 +1,126 @@
+#!/bin/csh 
+#  Script de generation des Makefile/smakefile pour modules
+#  librairies SOPHYA  
+#  C. Magneville / R. Ansari - Mai 2005
+#------
+#  Option controlant la generation des smakefile OU Makefile
+#  smakefile utilise pour le developpement - contient une reference 
+#  a $(SOPHYABASE)/include/sophyamake.inc
+#  les Makefile reference ../BuildMgr/sophyamake.inc
+#------
+
+if ( ! $?TMPDIR ) set TMPDIR = /tmp
+set makname = "Makefile"
+unset targetdir 
+
+if ( $#argv < 1) then 
+  echo ' Usage: mkmflib [-dev] [-sbase SOPHYABASE] ModuleName '
+  exit -1
+endif
+
+while ( $#argv > 0 )
+  if( "$1" == "-h" ) then
+    echo ' Usage: mkmflib [-dev] [-sbase SOPHYABASE] ModuleName '
+    exit -1
+  else if ( "$1" == "-dev" ) then 
+   set makname = "smakefile"
+  else if( "$1" == "-sbase" ) then
+    setenv SOPHYABASE $2
+    shift
+  else 
+    set targetdir = $1
+  endif
+  shift
+end
+
+if( ! $?SOPHYABASE ) then
+  echo 'ERROR: (mkmflib) define SOPHYABASE or use script arguments'
+  exit -2
+endif
+
+if( ! $?targetdir ) then
+  echo 'ERROR: (mkmflib) No target module (directory) specified'
+  exit -3
+endif
+
+cd ../$targetdir
+
+#--- fichier des fichiers a exclure
+if ( ! -f exclude ) touch exclude
+sort exclude >! $TMPDIR/exclude.sort
+set exclfile = 'exclude'
+
+echo "mkmflib: Creating $targetdir/objlist.list , $targetdir/$makname" 
+
+#--- fichier de la liste des .o
+set liblist = objlist.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 smakefile
+set libf='$(SOPHYALIBP)lib'$targetdir'.a'
+rm -f $makname; touch $makname
+
+if ($makname == "smakefile") then 
+  echo 'include $(SOPHYABASE)/include/sophyamake.inc' >> $makname 
+else 
+  echo 'include ../BuildMgr/sophyamake.inc' >> $makname 
+endif
+
+echo ' ' >> $makname
+echo 'all:' $libf  >> $makname 
+echo ' ' >> $makname
+
+echo 'clean:' >> $makname
+set toto='rm -f'
+foreach f ( *.cc *.c ) 
+  set toto= ( $toto '$(SOPHYAOBJP)'$f:r.o )
+end
+echo '	' $toto >> $makname
+echo '	rm -f '$libf >> $makname
+echo ' ' >> $makname
+
+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/^/$(SOPHYAOBJP)/'` >> $makname
+echo '	$(AR) $(ARFLAGS) $@ $? ' >> $makname
+set slbobjlist = libsophya.so
+if( -e shlibs.name ) set slbobjlist = `grep ^lib shlibs.name | head -1`
+set slbobjlist = $slbobjlist:r.objlist
+echo '	touch $(SOPHYAINCP)/SophyaConfInfo/'$slbobjlist >> $makname
+rm -f $TMPDIR/exclude.sort
+
+echo " " >> $makname
+
+
+#--- Creation des dependances
+set inc = `echo $SOPHYABASE/include | sed "s?//?/?g" | sed 's?/$??'`
+set nomsys = `uname`
+
+foreach f ( *.cc )
+  grep -q '^'$f'$' $exclfile && continue
+  gcc -MM -D$nomsys -I$inc $f  \
+       | sed -e 's/.*\.o/\$(SOPHYAOBJP)&/'  \
+       | sed -e 's?'$inc/'?$(SOPHYAINCP)?g'  >> $makname
+  echo '	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end
+
+foreach f ( *.c )
+  grep -q '^'$f'$' $exclfile && continue
+  gcc -MM -D$nomsys -I$inc $f  \
+       | sed -e 's/.*\.o/\$(SOPHYAOBJP)&/'  \
+       | sed -e 's?'$inc/'?$(SOPHYAINCP)?g' >> $makname
+  echo '	$(CCOMPILE) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end 
+
+foreach f ( *.f )
+  grep -q '^'$f'$' $exclfile && continue
+  echo '$(SOPHYAOBJP)'$f:r'.o: '$f >> $makname
+  echo '	$(FCOMPILE) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end 
+
+exit 0
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/mkmfprog
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/mkmfprog	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/mkmfprog	(revision 3445)
@@ -0,0 +1,143 @@
+#!/bin/csh
+#  Script de generation des Makefile/smakefile pour modules
+#  programmes SOPHYA  
+#  C. Magneville / R. Ansari - Mai 2005
+#--- Cf commentaires dans mkmflib
+
+if ( ! $?TMPDIR ) set TMPDIR = /tmp
+set makname = "Makefile"
+unset targetdir 
+
+if ( $#argv < 1) then 
+  echo ' Usage: mkmfprog [-dev] [-sbase SOPHYABASE] ModuleName '
+  exit -1
+endif
+
+while ( $#argv > 0 )
+  if( "$1" == "-h" ) then
+    echo ' Usage: mkmfprog [-dev] [-sbase SOPHYABASE] ModuleName '
+    exit -1
+  else if ( "$1" == "-dev" ) then 
+   set makname = "smakefile"
+  else if( "$1" == "-sbase" ) then
+    setenv SOPHYABASE $2
+    shift
+  else 
+    set targetdir = $1
+  endif
+  shift
+end
+
+if( ! $?SOPHYABASE ) then
+  echo 'ERROR: (mkmfprog) define SOPHYABASE or use script arguments'
+  exit -2
+endif
+
+if( ! $?targetdir ) then
+  echo 'ERROR: (mkmfprog) No target module (directory) specified'
+  exit -3
+endif
+
+cd ../$targetdir
+
+if ( ! -f programs ) touch programs
+if ( ! -f usedslibs ) touch usedslibs
+
+echo "mkmfprog: Creating $targetdir/$makname" 
+
+#--- La liste des programmes a compiler et de tous les .o
+set prog = ( `cat programs | awk '{print $1}'` )
+set obj = 
+foreach f ( $prog )
+  set obj = ( `grep ^$f programs | awk -F"$f " '{print $2}'` $obj )
+end
+
+#--- Creation de smakefile
+rm -f $makname; touch $makname
+
+if ($makname == "smakefile") then 
+  echo 'include $(SOPHYABASE)/include/sophyamake.inc' >> $makname 
+else 
+  echo 'include ../BuildMgr/sophyamake.inc' >> $makname 
+endif
+echo ' ' >> $makname
+
+set dum = 'PROGS = '
+foreach f ( $prog )
+  set dum = ( $dum  '$(SOPHYAEXEP)'$f )
+end
+echo $dum >> $makname
+echo ' ' >> $makname
+
+echo 'all: $(PROGS)' >> $makname
+echo ' ' >> $makname
+
+set dum = 
+foreach f ( $obj )
+  set dum = ( $dum '$(SOPHYAOBJP)'$f )
+end
+echo 'clean:' >> $makname
+echo '	rm -f $(PROGS)' >> $makname
+echo '	rm -f '$dum >> $makname
+echo ' ' >> $makname
+
+#--- Les programmes
+unset sopok extok piok
+grep -q ^sophya usedslibs
+if( $status == 0 ) set sopok
+grep -q ^extsophya usedslibs
+if( $status == 0 ) set extok
+grep -q ^PI usedslibs
+if( $status == 0 ) set piok
+set lib = '$(SOPHYAALLSLBLIST)'
+if( $?sopok ) set lib = '$(SOPHYASLBLIST)'
+if( $?extok ) set lib = '$(SOPHYAEXTSLBLIST)'
+if( $?piok )  set lib = '$(SOPHYAALLSLBLIST)'
+
+foreach f ( $prog )
+  echo $f': $(SOPHYAEXEP)'$f >> $makname
+  echo '	echo $@ " done"' >> $makname
+  set oo = ( `grep ^$f programs | awk -F"$f " '{print $2}'` )
+  set dum 
+  foreach fo ( $oo )
+    set dum = " $dum "'$(SOPHYAOBJP)'$fo
+  end
+  echo 
+  echo '$(SOPHYAEXEP)'$f':' $dum  >> $makname
+  echo '	$(CXXLINK) $(CXXTEMPFLG) -o $@' $dum $lib >> $makname
+  echo ' ' >> $makname
+end
+
+#--- Les dependances
+set inc = `echo $SOPHYABASE/include | sed "s?//?/?g" | sed 's?/$??'`
+set nomsys = `uname`
+
+foreach f ( *.cc )
+  grep -q "$f:r\.o" programs
+  if( $status != 0 ) continue
+  gcc -MM -D$nomsys -I$inc $f  \
+       | sed -e 's/.*\.o/\$(SOPHYAOBJP)&/'  \
+       | sed -e 's?'$inc/'?$(SOPHYAINCP)?g'  >> $makname
+  echo '	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end
+
+foreach f ( *.c )
+  grep -q "$f:r\.o" programs
+  if( $status != 0 ) continue
+  gcc -MM -D$nomsys -I$inc $f  \
+       | sed -e 's/.*\.o/\$(SOPHYAOBJP)&/'  \
+       | sed -e 's?'$inc/'?$(SOPHYAINCP)?g' >> $makname
+  echo '	$(CCOMPILE) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end 
+
+foreach f ( *.f )
+  grep -q "$f:r\.o" programs
+  if( $status != 0 ) continue
+  echo '$(SOPHYAOBJP)'$f:r'.o: '$f >> $makname
+  echo '	$(FCOMPILE) -o $@ ' $f >> $makname
+  echo ' ' >> $makname
+end 
+
+exit 0
Index: /tags/V_Nov2007/SophyaLib/BuildMgr/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/BuildMgr/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/BuildMgr/smakefile	(revision 3445)
@@ -0,0 +1,115 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+defaut: libs
+
+all: libs extlibs PI
+libs: cxxlibs
+extlibs : cxxextlibs
+
+cxxlibs::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/BaseTools.conf ] ; then cd  ../BaseTools ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SysTools.conf ] ; then cd  ../SysTools ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SUtils.conf ] ; then cd  ../SUtils ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/TArray.conf ] ; then cd  ../TArray ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/NTools.conf ] ; then cd  ../NTools ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/HiStats.conf ] ; then cd  ../HiStats ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SkyMap.conf ] ; then cd  ../SkyMap ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/Samba.conf ] ; then cd  ../Samba ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/SkyT.conf ] ; then cd  ../SkyT ; $(MAKE) -f smakefile ; fi
+
+cxxextlibs::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/FitsIOServer.conf ] ; then cd  ../FitsIOServer ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/IFFTW.conf ] ; then cd  ../IFFTW ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/LinAlg.conf ] ; then cd  ../LinAlg ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/XAstroPack.conf ] ; then cd  ../XAstroPack ; $(MAKE) -f smakefile ; fi
+ 
+PI::
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PI.conf ] ; then cd ../PI ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PIGcont.conf ] ; then cd ../PIGcont ; $(MAKE) -f smakefile ; fi
+	if [ -f $(SOPHYAINCP)/SophyaConfInfo/PIext.conf ] ; then cd ../PIext ; $(MAKE) -f smakefile ; fi
+
+#  Shared library creation part of the Makefile
+
+#  main dependence list
+slball : slb slbext slbpi 
+slb : $(SOPHYASLBP)libsophya.$(SLEXT)
+slbext : $(SOPHYASLBP)libextsophya.$(SLEXT)    
+slbpi : $(SOPHYASLBP)libPI.$(SLEXT)
+#  All object modules in a single shared library
+slballinone : $(SOPHYASLBP)libAsophyaextPI.$(SLEXT) 
+
+# List of .o files for SOPHYA  module
+ALLOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+# List of .o files modules with reference to external libraries
+ALLEXTOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libextsophya.objlist
+
+# List of .o files for PI modules 
+ALLPIOBJSF = $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+# Building Sophya shared library
+$(SOPHYASLBP)libsophya.$(SLEXT) : $(ALLOBJSF)
+	echo `cat $(ALLOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@  `cat $(ALLOBJSF) ` $(SOPBASELIBS)
+ 
+# Building ExtSophya shared library
+$(SOPHYASLBP)libextsophya.$(SLEXT) : $(ALLEXTOBJSF)
+	echo `cat $(ALLEXTOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@  `cat $(ALLEXTOBJSF) ` \
+	$(SOPHYASLBLIST) $(SOPEXTLIBS)
+
+# Building PI shared library
+$(SOPHYASLBP)libPI.$(SLEXT) : $(ALLPIOBJSF)
+	echo `cat $(ALLPIOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@ `cat $(ALLPIOBJSF) ` \
+	$(SOPHYAEXTSLBLIST) $(PILIBS)
+
+# Building a single shared library with all modules Sophya+ExtSophya+PI
+$(SOPHYASLBP)libAsophyaextPI.$(SLEXT) : $(ALLOBJSF) $(ALLEXTOBJSF) $(ALLPIOBJSF)
+	echo `cat $(ALLOBJSF)` ; \
+	echo `cat $(ALLEXTOBJSF)` ; \
+	echo `cat $(ALLPIOBJSF)` ; \
+	cd  $(SOPHYAOBJP); \
+	$(CMDSHLCXX) -o $@ \
+	`cat $(ALLOBJSF) ` \
+	`cat $(ALLEXTOBJSF) ` \
+	`cat $(ALLPIOBJSF) ` \
+	$(PILIBS) $(SOPEXTLIBS) $(SOPBASELIBS)
+
+
+#  Cleaning targets
+clean:
+	if [ -d $(SOPHYALIBP) ] ; then cd $(SOPHYALIBP)/. ; rm -f *.a  ; fi
+	if [ -d $(SOPHYASLBP) ] ; then cd $(SOPHYASLBP)/. ; rm -f *.so ; fi
+	if [ -d $(SOPHYAEXEP) ] ; then cd $(SOPHYAEXEP)/. ; rm -f * ; fi
+	if [ -d $(SOPHYAOBJP) ] ; then cd $(SOPHYAOBJP)/. ; rm -rf *.o cxxrep templateregistry ; fi
+
+cleanobj:
+	if [ -d $(SOPHYAOBJP) ] ; then rm -rf $(SOPHYAOBJP) ; fi
+
+#  Various main program builds
+prgall : tests prgutil prgmap progpi
+piapp : progpi
+spiapp : progpi
+
+basetests:
+	cd ../Tests/ ; make -f smakefile arrt carrt tnt tobjio
+
+tests:
+	cd ../Tests/ ; make -f smakefile 
+
+prgutil:
+	cd ../PrgUtil/ ; make -f smakefile 
+
+progpi:
+	cd ../ProgPI/ ; make -f smakefile 
+
+prgmap:
+	cd ../PrgMap/ ; make -f smakefile 
+
+pmixer:
+	cd ../PMixer/ ; make -f smakefile 
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/Makefile	(revision 3445)
@@ -0,0 +1,403 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libHiStats.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basedtable.o $(SOPHYAOBJP)datatable.o $(SOPHYAOBJP)fio_dtable.o $(SOPHYAOBJP)hisprof.o $(SOPHYAOBJP)hist2err.o $(SOPHYAOBJP)histerr.o $(SOPHYAOBJP)histinit.o $(SOPHYAOBJP)histos.o $(SOPHYAOBJP)histos2.o $(SOPHYAOBJP)ntupintf.o $(SOPHYAOBJP)ntuple.o $(SOPHYAOBJP)proxtuple.o $(SOPHYAOBJP)swppfdtable.o $(SOPHYAOBJP)xntuple.o
+	rm -f $(SOPHYALIBP)libHiStats.a
+ 
+$(SOPHYALIBP)libHiStats.a : $(SOPHYAOBJP)basedtable.o $(SOPHYAOBJP)datatable.o $(SOPHYAOBJP)fio_dtable.o $(SOPHYAOBJP)hisprof.o $(SOPHYAOBJP)hist2err.o $(SOPHYAOBJP)histerr.o $(SOPHYAOBJP)histinit.o $(SOPHYAOBJP)histos2.o $(SOPHYAOBJP)histos.o $(SOPHYAOBJP)ntupintf.o $(SOPHYAOBJP)ntuple.o $(SOPHYAOBJP)proxtuple.o $(SOPHYAOBJP)swppfdtable.o $(SOPHYAOBJP)xntuple.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)basedtable.o: basedtable.cc basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basedtable.cc
+ 
+$(SOPHYAOBJP)datatable.o: datatable.cc datatable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiosegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatable.cc
+ 
+$(SOPHYAOBJP)fio_dtable.o: fio_dtable.cc datatable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiosegdb.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fio_dtable.cc
+ 
+$(SOPHYAOBJP)hisprof.o: hisprof.cc $(SOPHYAINCP)machdefs.h \
+  hisprof.h $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)perrors.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  hisprof.cc
+ 
+$(SOPHYAOBJP)hist2err.o: hist2err.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h hist2err.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)tmatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  hist2err.cc
+ 
+$(SOPHYAOBJP)histerr.o: histerr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h histerr.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histerr.cc
+ 
+$(SOPHYAOBJP)histinit.o: histinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h histos2.h \
+  $(SOPHYAINCP)utils.h hisprof.h histerr.h \
+  hist2err.h $(SOPHYAINCP)tmatrix.h ntuple.h \
+  ntupintf.h $(SOPHYAINCP)dvlist.h xntuple.h \
+  datatable.h basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histinit.cc
+ 
+$(SOPHYAOBJP)histos.o: histos.cc $(SOPHYAINCP)machdefs.h \
+  histos.h $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histos.cc
+ 
+$(SOPHYAOBJP)histos2.o: histos2.cc $(SOPHYAINCP)machdefs.h \
+  histos2.h $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)utils.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histos2.cc
+ 
+$(SOPHYAOBJP)ntupintf.o: ntupintf.cc $(SOPHYAINCP)sopnamsp.h \
+  ntupintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntupintf.cc
+ 
+$(SOPHYAOBJP)ntuple.o: ntuple.cc $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h ntuple.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntuple.cc
+ 
+$(SOPHYAOBJP)proxtuple.o: proxtuple.cc $(SOPHYAINCP)sopnamsp.h \
+  proxtuple.h ntuple.h $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  proxtuple.cc
+ 
+$(SOPHYAOBJP)swppfdtable.o: swppfdtable.cc swppfdtable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  swppfdtable.cc
+ 
+$(SOPHYAOBJP)xntuple.o: xntuple.cc $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)perrors.h xntuple.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xntuple.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/HiStats/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/HiStats/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/Makefile.mgr	(revision 3445)
@@ -0,0 +1,243 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libHiStats.a
+clean:
+	rm -f $(OBJ)basedtable.o $(OBJ)datatable.o $(OBJ)fio_dtable.o $(OBJ)hisprof.o $(OBJ)histerr.o $(OBJ)histinit.o $(OBJ)histos.o $(OBJ)histos2.o $(OBJ)ntupintf.o $(OBJ)ntuple.o $(OBJ)proxtuple.o $(OBJ)swppfdtable.o $(OBJ)xntuple.o
+	rm -f $(LIB)libHiStats.a
+$(LIB)libHiStats.a : $(OBJ)basedtable.o $(OBJ)datatable.o $(OBJ)fio_dtable.o $(OBJ)hisprof.o $(OBJ)histerr.o $(OBJ)histinit.o $(OBJ)histos.o $(OBJ)histos2.o $(OBJ)ntupintf.o $(OBJ)ntuple.o $(OBJ)proxtuple.o $(OBJ)swppfdtable.o $(OBJ)xntuple.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)basedtable.o: basedtable.cc basedtable.h \
+  $(INC)machdefs.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)segdatablock.h \
+  $(INC)sopnamsp.h
+$(OBJ)datatable.o: datatable.cc datatable.h basedtable.h \
+  $(INC)machdefs.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)segdatablock.h \
+  $(INC)sopnamsp.h \
+  $(INC)strutil.h \
+  $(INC)fiosegdb.h \
+  $(INC)ppftpointerio.h
+$(OBJ)fio_dtable.o: fio_dtable.cc datatable.h basedtable.h \
+  $(INC)machdefs.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)segdatablock.h swppfdtable.h \
+  $(INC)swsegdb.h \
+  $(INC)ppfswapper.h \
+  $(INC)ppftpointerio.h \
+  $(INC)sopnamsp.h \
+  $(INC)fiosegdb.h
+$(OBJ)hisprof.o: hisprof.cc $(INC)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h histos.h
+$(OBJ)histerr.o: histerr.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h histinit.h \
+  $(INC)ntoolsinit.h \
+  $(INC)tarrinit.h \
+  $(INC)sophyainit.h histerr.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h 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)mutyv.h \
+  $(INC)dvlist.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h
+$(OBJ)histinit.o: histinit.cc $(INC)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 histerr.h \
+  ntuple.h ntupintf.h xntuple.h datatable.h basedtable.h \
+  $(INC)segdatablock.h swppfdtable.h \
+  $(INC)swsegdb.h \
+  $(INC)ppfswapper.h \
+  $(INC)ppftpointerio.h
+$(OBJ)histos.o: histos.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h histos.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h \
+  ntupintf.h $(INC)machdefs.h \
+  $(INC)pexceptions.h
+$(OBJ)ntuple.o: ntuple.cc $(INC)sopnamsp.h \
+  $(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 \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)mutyv.h
+$(OBJ)proxtuple.o: proxtuple.cc $(INC)sopnamsp.h \
+  proxtuple.h ntuple.h $(INC)objfio.h \
+  $(INC)machdefs.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)mutyv.h
+$(OBJ)swppfdtable.o: swppfdtable.cc swppfdtable.h basedtable.h \
+  $(INC)machdefs.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)segdatablock.h \
+  $(INC)swsegdb.h \
+  $(INC)ppfswapper.h \
+  $(INC)ppftpointerio.h \
+  $(INC)sopnamsp.h
+$(OBJ)xntuple.o: xntuple.cc $(INC)sopnamsp.h \
+  $(INC)ppersist.h \
+  $(INC)machdefs.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)perrors.h xntuple.h ntupintf.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)mutyv.h
Index: /tags/V_Nov2007/SophyaLib/HiStats/basedtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/basedtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/basedtable.cc	(revision 3445)
@@ -0,0 +1,1043 @@
+#include "basedtable.h"
+#include <ctype.h>
+#include "pexceptions.h"
+#include "thsafeop.h"
+
+namespace SOPHYA {
+
+/*!
+   \class DataTableRow
+   \ingroup HiStats
+   This class is intented to be used with datatable classes
+   (inheriting from BaseDataTable) for representing a row (line)
+   of the table. 
+*/
+DataTableRow::DataTableRow( vector<string> const& colnames )
+{
+  if (colnames.size() < 1) 
+    throw ParmError("DataTableRow::DataTableRow(vector<string>& cn) cn.size()==0 ");
+  size_ = colnames.size();
+  mtv_ = new MuTyV[ size_ ];
+  for(sa_size_t k=0; k<size_; k++) 
+    nm2idx_[colnames[k]] = k;
+}
+
+DataTableRow::DataTableRow(DataTableRow const & a )
+{
+  size_ = a.size_;
+  mtv_ = new MuTyV[ size_ ];
+  nm2idx_ = a.nm2idx_;
+}
+
+MuTyV DataTableRow::get(string const& colname) const
+{
+  map<string, sa_size_t>::const_iterator it = nm2idx_.find(colname);
+  if (it == nm2idx_.end()) { 
+    string msg = "DataTableRow::get( " ;
+    msg += colname;    msg += " ) Not found column name";
+    throw NotFoundExc(msg);
+  }
+  return mtv_[(*it).second];
+}
+
+MuTyV& DataTableRow::get(string const& colname) 
+{
+  map<string, sa_size_t>::const_iterator it = nm2idx_.find(colname);
+  if (it == nm2idx_.end()) { 
+    string msg = "DataTableRow::get( " ;
+    msg += colname;    msg += " ) const - Not found column name";
+    throw NotFoundExc(msg);
+  }
+  return mtv_[(*it).second];
+}
+
+ostream&   DataTableRow::Print(ostream& os) const
+{
+  for(sa_size_t k=0; k<size_; k++) 
+    os << (string)mtv_[k] << " ";
+  return os;
+}
+
+/*!
+   \class BaseDataTable
+   \ingroup HiStats
+   Base class for data tables. Each line represent a record
+   and the column contains a given data type.
+   \warning 
+   Thread safe fill operation can be activated using the method SetThreadSafe()
+   Default mode is NON thread-safe fill.   
+*/
+
+/*!
+  if fgl == true , return LongForm string
+  \verbatim
+  ----------------------------------------------  
+  FieldType         ShortForm     LongForm
+  ----------------------------------------------  
+  IntegerField          I         Integer
+  LongField             L         Long Integer
+  FloatField            F         Float
+  DoubleField           D         Double
+  ComplexField         Zx4        Complex
+  DoubleComplexField   Zx8        DoubleComplex
+  StringField           S         String
+  DateTimeField         T         DateTime
+  ----------------------------------------------  
+  \endverbatim
+*/
+string BaseDataTable::ColTypeToString(FieldType ft, bool fgl)
+{
+  string rs;
+  switch (ft) {
+  case IntegerField :
+    if (fgl) rs = "Integer";
+    else rs = "I";
+    break;
+  case LongField :
+    if (fgl) rs = "Long Integer";
+    else rs = "L";
+    break;
+  case FloatField :
+    if (fgl) rs = "Float";
+    else rs = "F";
+    break;
+  case DoubleField :
+    if (fgl) rs = "Double";
+    else rs = "D";
+    break;
+  case ComplexField :
+    if (fgl) rs = "Complex";
+    else rs = "Zx4";    
+    break;
+  case DoubleComplexField :
+    if (fgl) rs = "DoubleComplex";
+    else rs = "Zx8";
+    break;    
+  case StringField :
+    if (fgl) rs = "String";
+    else rs = "S";
+    break;
+  case DateTimeField :
+    if (fgl) rs = "DateTime";
+    else rs = "T";
+    break;
+  default:
+    rs = "??";
+    break;
+  }
+  return rs;
+}
+
+BaseDataTable::FieldType BaseDataTable::StringToColType(string const & sctyp)
+{
+  if ( (sctyp == "Integer") || (sctyp == "I") )  return IntegerField;
+  else if ( (sctyp == "Long Integer") || (sctyp == "L") )  return LongField;
+  else if ( (sctyp == "Float") || (sctyp == "F") )  return FloatField;
+  else if ( (sctyp == "Double") || (sctyp == "D") )  return DoubleField;
+  else if ( (sctyp == "Complex") || (sctyp == "Zx4") )  return ComplexField;
+  else if ( (sctyp == "DoubleComplex") || (sctyp == "Zx8") || (sctyp == "Z") )  
+    return DoubleComplexField;
+  else if ( (sctyp == "String") || (sctyp == "S") )  return StringField;
+  else if ( (sctyp == "DateTime") || (sctyp == "T") )  return DateTimeField;
+  else return DoubleField;
+}
+
+/* Constructeur */
+BaseDataTable::BaseDataTable(sa_size_t segsz)
+{
+  mNEnt = 0;
+  mSegSz = (segsz > 0) ? segsz : 16;
+  mNSeg = 0;
+  mVarD = NULL;
+  mVarMTV = NULL;
+  mInfo = NULL;
+  mThS = NULL;
+}
+
+BaseDataTable::~BaseDataTable()
+{
+  if (mVarD) delete[] mVarD;
+  if (mVarMTV) delete[] mVarMTV;
+  if (mInfo) delete mInfo;
+  if (mThS) delete mThS;
+}
+
+/*!
+  \brief Activate or deactivate thread-safe \b AddRow() operations
+
+  If fg==true, create an ThSafeOp object in order to insure atomic AddRow()
+  and GetRow()/GetColumn() operations. if fg==false, the ThSafeOp object (mThS) 
+  of the target DataTable is destroyed.
+
+  When activated, the following operations are thread-safe : 
+
+  - AddRow(const r_8* data)
+  - AddRow(const MuTyV* data)
+  - AddRow(DataTableRow const& data)
+  - GetRow(sa_size_t n, DataTableRow& row)
+  - GetRow(sa_size_t n, MuTyV* mtvp)
+  - GetColumnD(sa_size_t k)
+
+  \warning The default AddRow() operation mode for DataTables is NOT thread-safe. 
+  Please note also that the thread-safety state is NOt saved to PPF (or FITS) streams.
+*/
+void BaseDataTable::SetThreadSafe(bool fg) 
+{
+  if (fg) {
+    if (mThS) return;
+    else mThS = new ThSafeOp();
+  }
+  else {
+    if (mThS) delete mThS;
+    mThS = NULL;
+  }
+}
+
+
+/*! \cond
+  \class DT_TSOP_SYNC 
+  \ingroup HiStats 
+  Classe utilitaire pour faciliter la gestion de lock pour 
+  operations thread-safe BaseDataTable
+*/
+class DT_TSOP_SYNC {
+ public:
+  explicit DT_TSOP_SYNC(ThSafeOp* ths) 
+  { 
+    ths_ = ths; 
+    if (ths_) ths_->lock(); 
+  }
+  ~DT_TSOP_SYNC() 
+  {
+    if (ths_) ths_->unlock(); 
+  }
+  inline ThSafeOp* NOp() { return ths_; }
+ protected:
+  ThSafeOp* ths_;
+};
+/*! \endcond */
+
+sa_size_t BaseDataTable::CopyStructure(BaseDataTable const & a)
+{
+  if (NVar() > 0) 
+    throw ParmError("BaseDataTable::CopyStructure() Table already has columns");
+  if (a.NVar() == 0) {
+    cout << "BaseDataTable::CopyStructure(a)/Warning Table a is not initialized" << endl;
+    return 0;
+  }
+  for (size_t kk=0; kk<a.mNames.size(); kk++) 
+    AddColumn(a.mNames[kk].type, a.mNames[kk].nom);
+  return NVar();
+}
+
+//! return true is same structure
+bool BaseDataTable::CompareStructure(BaseDataTable const & a)
+{
+  if (NVar() != a.NVar())  return false;
+  for (size_t kk=0; kk<mNames.size(); kk++) 
+    if ( (mNames[kk].type != a.mNames[kk].type) || 
+	 (mNames[kk].nom != a.mNames[kk].nom) ) return false;
+  return true;
+}
+
+//! Check the validity of column name \b cnom - throw exception.
+bool BaseDataTable::CheckColName(string const & cnom)
+{
+  size_t l,k;
+  l = cnom.length();
+  if (l < 1)  
+    throw ParmError("BaseDataTable::CheckColName() zero length column name");
+  if (!isalpha(cnom[0]))  
+    throw ParmError("BaseDataTable::CheckColName() first character not alphabetical");
+  for(k=1; k<l; k++) 
+    if ((!isalnum(cnom[k])) && (cnom[k] != '_'))  
+      throw ParmError("BaseDataTable::CheckColName() Non alphanumeric char in name");
+  for(k=0; k<mNames.size(); k++)
+    if (cnom == mNames[k].nom) 
+      throw ParmError("BaseDataTable::CheckColName() already existing name");
+  return true;
+}
+
+/*! 
+  \brief Check  the validity of column name \b cnom and correct it if necessary
+  return true if \b cnom has been changed
+*/
+bool BaseDataTable::CheckCorrectColName(string& cnom)
+{
+  size_t l,k;
+  l = cnom.length();
+  string ssn;
+  MuTyV mvv = (NCols()+1);
+  mvv.Convert(ssn);
+  bool fgrc = false;
+  if (l < 1) { cnom = "C"+ssn;   fgrc = true; }
+  if (!isalpha(cnom[0]))  { cnom = "C"+cnom;  fgrc = true; }
+  for(k=1; k<l; k++) 
+    if ((!isalnum(cnom[k])) && (cnom[k] != '_'))  { 
+      cnom[k] = '_';  fgrc = true;
+    }
+  bool fgdouble = true;
+  while (fgdouble) {
+    fgdouble = false;
+    for(k=0; k<mNames.size(); k++)
+      if (cnom == mNames[k].nom) {
+	fgdouble = true;  break;
+      }
+    if (fgdouble) { cnom = cnom+ssn; fgrc = true; } 
+  }
+  return fgrc;
+}
+
+// Retourne une structure
+/*!
+ The returned BaseDataTable object can be used for subsequent call to 
+ AddRow() or GetRow() methods.
+ Generate an exception if called for a table with no columns
+*/
+DataTableRow BaseDataTable::EmptyRow()
+{
+  if (NCols() == 0) 
+    throw ParmError("BaseDataTable::EmptyRow() Table has no column !");
+  vector<string> nms;
+  for(sa_size_t k=0; k<NVar(); k++)  nms.push_back(mNames[k].nom);
+  DataTableRow row(nms);
+  return row;
+}
+
+// 
+// A quel index correspond mon nom ? 
+// 
+sa_size_t BaseDataTable::IndexNom(char const* nom) const 
+{
+  for(sa_size_t k=0; k<NVar(); k++) 
+    if ( mNames[k].nom == nom )      return k;
+  return -1;
+  // Reza:Avril 2005 : PINtuple se base sur le renvoi de -1 et pas d'une exception
+  //  throw NotFoundExc("BaseDataTable::IndexNom() : column name not found ");
+}
+
+string BaseDataTable::NomIndex(sa_size_t k) const 
+{
+  if ((k < 0) || (k >= NVar())) 
+    throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k");
+  return mNames[k].nom ; 
+}
+
+//! Adds a row (or line) to the table with r_8* inout data
+/*! 
+  The data to be added is provided as an array (vector) of double (r_8).
+  The necessary data conversion is performed, depending on each 
+  column's data typeconverted to the data type. 
+  Return the new number of table rows (lines / entries)
+  \param data : Data for each cell of the row to be appended 
+  (data[k] k=0..NbColumns()) 
+*/
+sa_size_t BaseDataTable::AddRow(const r_8* data)
+{
+  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation 
+
+  if (NVar() == 0) 
+    throw ParmError("BaseDataTable::AddRow(const r_8*) Table has no column !");
+  if (NEntry() == SegmentSize()*NbSegments())  Extend();
+  sa_size_t n = NEntry();
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  for(sa_size_t k=0; k<mIColsP.size(); k++) 
+    mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
+  for(sa_size_t k=0; k<mLColsP.size(); k++) 
+    mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
+  for(sa_size_t k=0; k<mFColsP.size(); k++) 
+    mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
+  for(sa_size_t k=0; k<mDColsP.size(); k++) 
+    mDColsP[k]->GetSegment(bid)[off] = data[mDColIdx[k]];
+  for(sa_size_t k=0; k<mYColsP.size(); k++) 
+    mYColsP[k]->GetSegment(bid)[off] = complex<r_4>(data[mYColIdx[k]],0.);
+  for(sa_size_t k=0; k<mZColsP.size(); k++) 
+    mZColsP[k]->GetSegment(bid)[off] = complex<r_8>(data[mZColIdx[k]],0.);
+  for(sa_size_t k=0; k<mSColsP.size(); k++) 
+    mSColsP[k]->GetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]);
+
+  mNEnt++;
+  return mNEnt;
+}
+
+//! Adds a row (or line) to the table with input data as an array of MuTyV
+/*! 
+  The data to be added is provided as an array (vector) of MuTyV.
+  The MuTyV class conversion operators are used to match against each 
+  cell data type.
+  Return the new number of table rows (lines / entries)
+  \param data : Data (MuTyV*) for each cell of the row to be appended 
+  (data[k] k=0..NbColumns()) 
+*/
+sa_size_t BaseDataTable::AddRow(const MuTyV* data)
+{
+  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation 
+
+  if (NVar() == 0) 
+    throw ParmError("BaseDataTable::AddRow(const MuTyV*) Table has no column !");
+  if (NEntry() == SegmentSize()*NbSegments())  Extend();
+  sa_size_t n = NEntry();
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  for(sa_size_t k=0; k<mIColsP.size(); k++) 
+    mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
+  for(sa_size_t k=0; k<mLColsP.size(); k++) 
+    mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
+  for(sa_size_t k=0; k<mSColsP.size(); k++) 
+    mSColsP[k]->GetSegment(bid)[off] = (string)data[mSColIdx[k]];
+  for(sa_size_t k=0; k<mFColsP.size(); k++) 
+    mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
+  for(sa_size_t k=0; k<mDColsP.size(); k++) 
+    mDColsP[k]->GetSegment(bid)[off] = (r_8)data[mDColIdx[k]];
+  for(sa_size_t k=0; k<mYColsP.size(); k++) 
+    mYColsP[k]->GetSegment(bid)[off] = 
+      complex<r_4>(data[mYColIdx[k]].GetRealPart(), data[mYColIdx[k]].GetImagPart());
+  for(sa_size_t k=0; k<mZColsP.size(); k++) 
+    mZColsP[k]->GetSegment(bid)[off] = 
+      complex<r_8>(data[mZColIdx[k]].GetRealPart(), data[mZColIdx[k]].GetImagPart());
+
+  mNEnt++;
+  return mNEnt;
+}
+//! Adds a row (or line) to the table with input data as DataTableRow object
+/*! 
+  The internal MuTyV array of the object contains the data and the 
+  MuTyV class conversion operators are used to match against each 
+  cell data type.
+  Only the size of the input data object is checked.
+  Return the new number of table rows (lines / entries)
+  \param data : Data  for each cell of the row to be appended 
+  (data[k] k=0..NbColumns()) 
+*/
+sa_size_t BaseDataTable::AddRow(DataTableRow const& data)
+{
+  if ( data.Size() != NCols() )
+    throw SzMismatchError(" BaseDataTable::AddRow() - data.Size() != NCols() ");
+  return AddRow(data.MTVPtr());
+}
+
+/*! 
+  Extends the table (in the row direction). This method is called automatically when needed.
+*/
+sa_size_t BaseDataTable::Extend()
+{
+  for(sa_size_t k=0; k<mIColsP.size(); k++) 
+    mIColsP[k]->Extend();
+  for(sa_size_t k=0; k<mLColsP.size(); k++) 
+    mLColsP[k]->Extend();
+  for(sa_size_t k=0; k<mFColsP.size(); k++) 
+    mFColsP[k]->Extend();
+  for(sa_size_t k=0; k<mDColsP.size(); k++)     
+    mDColsP[k]->Extend();
+  for(sa_size_t k=0; k<mYColsP.size(); k++) 
+    mYColsP[k]->Extend();
+  for(sa_size_t k=0; k<mZColsP.size(); k++) 
+    mZColsP[k]->Extend();
+  for(sa_size_t k=0; k<mSColsP.size(); k++) 
+    mSColsP[k]->Extend();
+  mNSeg++;
+  return mNSeg;
+}
+
+/*!
+  Fills the input \b row object with the content of row \b n.
+  Return a reference to the input \b row object. 
+  Generate an exception if the input \b row object has the wrong size.
+*/
+DataTableRow& BaseDataTable::GetRow(sa_size_t n, DataTableRow& row) const
+{
+  if ( row.Size() != NCols() )
+    throw SzMismatchError(" BaseDataTable::GetRow(n, row) - row.Size() != NCols() ");
+  GetRow(n, row.MTVPtr());
+  return row;
+}
+
+/*!
+  For thread-safe operation, specify a valid \b mtvp  pointer (!= NULL)  
+*/
+MuTyV* BaseDataTable::GetRow(sa_size_t n, MuTyV* mtvp) const 
+{
+  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation 
+
+  if ((n < 0) || (n >= NEntry())) 
+    throw RangeCheckError("BaseDataTable::GetRow() out of range line index n");
+  if (mtvp == NULL) {
+    if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
+    mtvp = mVarMTV;
+  }
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  for(sa_size_t k=0; k<mIColsP.size(); k++) 
+    mtvp[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mLColsP.size(); k++) 
+    mtvp[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mFColsP.size(); k++) 
+    mtvp[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mDColsP.size(); k++) {
+    if (GetColumType(mDColIdx[k]) == DateTimeField) 
+      mtvp[mDColIdx[k]] = TimeStamp(mDColsP[k]->GetCstSegment(bid)[off]);
+    else mtvp[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
+  }
+  for(sa_size_t k=0; k<mYColsP.size(); k++) 
+    mtvp[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mZColsP.size(); k++) 
+    mtvp[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mSColsP.size(); k++) 
+    mtvp[mSColIdx[k]] = mSColsP[k]->GetCstSegment(bid)[off];
+
+  return mtvp;
+}
+
+#define BADVAL -1.e39
+
+TVector<r_8> BaseDataTable::GetColumnD(sa_size_t k) const
+{
+  DT_TSOP_SYNC dttss(mThS); dttss.NOp();  // Thread-safe operation 
+
+  if ((k < 0) || (k >= NVar())) 
+    throw RangeCheckError("BaseDataTable::GetColumnD() out of range column index k");
+  sa_size_t sk = mNames[k].ser;
+  sa_size_t i = 0; 
+  TVector<r_8> rv(NEntry());
+
+  for (sa_size_t is=0; is<NbSegments(); is++) {
+    switch (mNames[k].type) {
+    case IntegerField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mIColsP[sk]->GetCstSegment(is)[j];
+      break;
+    case LongField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mLColsP[sk]->GetCstSegment(is)[j];
+      break;
+    case FloatField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mFColsP[sk]->GetCstSegment(is)[j];
+      break;
+    case DoubleField :
+    case DateTimeField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mDColsP[sk]->GetCstSegment(is)[j];
+      break;
+    case ComplexField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mYColsP[sk]->GetCstSegment(is)[j].real();
+      break;
+    case DoubleComplexField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv(i) = mZColsP[sk]->GetCstSegment(is)[j].real();
+      break;
+    case StringField :
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)
+	rv = atof(mSColsP[sk]->GetCstSegment(is)[j].c_str());
+      break;
+    default:
+      for(sa_size_t j=0; (j<SegmentSize())&&(i<NEntry()); j++,i++)  
+	rv(i) = BADVAL;
+      break;
+    }
+  }
+  return rv ; 
+}
+
+void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
+{
+  if (cp && (NEntry() > 0) )
+    throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
+  if (a.NVar() == 0)  throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
+  if (NVar() == 0) CopyStructure(a);
+  else if (!CompareStructure(a)) 
+    throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
+  if (a.NEntry() == 0) {
+    cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
+    return;
+  }
+  for(sa_size_t kk=0; kk<a.NEntry(); kk++) 
+    AddRow(a.GetLine(kk));
+}
+
+
+//! Returns the associated DVList object
+DVList&  BaseDataTable::Info() const
+{
+  if (mInfo == NULL)  mInfo = new DVList;
+  return(*mInfo);
+}
+
+/*!
+  Formatted (text) output of the table, for lines lstart <= l_index < lend , with step lstep
+  \param os : output stream (formatted output)
+  \param lstart : start row (line) index
+  \param lend : end row (line) index 
+  \param lstep : row index increment
+*/
+ostream& BaseDataTable::Print(ostream& os, sa_size_t lstart, sa_size_t lend, sa_size_t lstep) const
+{
+  os << "##### BaseDataTable::Print() - Table(NRow=" << NEntry() << " , NCol=" 
+     << NVar() << ") ##### " << endl;
+  os << "#! " ;
+  for (size_t i=0; i<NVar(); i++) {
+    string nom = mNames[i].nom;
+    nom += ':'; nom += ColTypeToString(mNames[i].type);
+    os << setw(12) << nom << " ";
+  }
+  os << endl;
+  os << "##########################################################################" << endl;
+  for (sa_size_t l=lstart; l<lend; l+=lstep)
+    os << TableRowToString(l, true) << endl;
+  return os;
+}
+
+/*! In addition to printing the number of entries and column names, 
+  this method prints also minimum/maximum value for each column. 
+  This information might be computed when the Show() method is called.
+  This may take some time for tables with large number of entries (>~ 10^6)
+*/
+void   BaseDataTable::Show(ostream& os) const 
+{
+  os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry() 
+     << " ( SegSize= " << SegmentSize() << "  NbSegments= " 
+     << NbSegments() << " )" << endl;
+  os << "--------------------------------------------------------------------" << endl;
+  os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("  
+     << setw(4) << "Type" << ") | " 
+     << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
+  os << "--------------------------------------------------------------------" << endl;
+  r_8 min, max ;
+  for(sa_size_t i = 0 ; i < NVar() ; i++) {
+    GetMinMax(i, min, max) ;
+    string nom;
+    if (mNames[i].nom.length() > 20) 
+      nom = mNames[i].nom.substr(20);
+    else nom = mNames[i].nom;
+    os << setw(3) << i << ":" << setw(20) << nom << " (" 
+       << setw(4) << ColTypeToString(mNames[i].type) << ") | " 
+       << setw(15) << min << " | " << setw(15) << max << endl;
+  }
+  os << "--------------------------------------------------------------------" << endl;
+  return;
+}
+
+//! Fills table from an ascii (text) file
+/*
+  Return number of non empt lines (added to table)
+  \param is : input ascii (text) stream
+  \param clm : Lines starting with clm are ignored (comments)
+  \param sep : separator between different fields (columns)
+*/
+sa_size_t  BaseDataTable::FillFromASCIIFile(istream& is, char clm, const char* sep)
+{
+  string str;
+  if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
+  sa_size_t iv, nl;
+  nl = 0;
+  while (!is.eof()) {
+    str = "";
+    getline(is, str);
+    if (is.good() || is.eof()) {
+      size_t l = str.length();
+      if ((l == 0) || (str[0]==clm)) continue;
+      for(iv=0; iv<NVar(); iv++) mVarMTV[iv] = 0.;
+      iv = 0;
+      size_t q = 0;
+      size_t p = 0;
+      while ( (q < l) && (iv < NVar()) ) {
+	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)  { 
+	    mVarMTV[iv] = str.substr(p+1,q-p-1);
+	    q++;
+	  }
+	  else mVarMTV[iv] = str.substr(p+1,l-p-1);
+	  iv++;
+	}
+	else {
+	  q = str.find_first_of(sep,p);
+	  if (q > l) q = l;
+	  mVarMTV[iv] = str.substr(p,q-p);
+	  iv++;
+	}
+	if (mNames[iv-1].type == DateTimeField) {
+	  string tts = (string)mVarMTV[iv-1];
+	  mVarMTV[iv-1] = TimeStamp(tts);
+	}
+      }
+      AddRow(mVarMTV);
+      nl++;
+    }
+  }  // Fin boucle lignes fichier
+  cout << "BaseDataTable::FillFromASCIIFile()/Info: " << nl << " lines decoded from stream " << endl; 
+  return(nl);
+}
+
+
+
+// 
+// ------------------------------------
+// ------- Interface NTuple -----------
+// ------------------------------------
+// 
+sa_size_t BaseDataTable::NbLines() const
+{
+  return(NEntry());
+}
+
+sa_size_t BaseDataTable::NbColumns() const
+{
+  return(NVar());
+}
+
+r_8* BaseDataTable::GetLineD(sa_size_t n) const 
+{
+  if ((n < 0) || (n >= NEntry())) 
+    throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
+  if (mVarD == NULL) mVarD = new r_8[NVar()];
+
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  for(sa_size_t k=0; k<mIColsP.size(); k++) 
+    mVarD[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mLColsP.size(); k++) 
+    mVarD[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mFColsP.size(); k++) 
+    mVarD[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mDColsP.size(); k++) 
+    mVarD[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
+  for(sa_size_t k=0; k<mYColsP.size(); k++) 
+    mVarD[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off].real();
+  for(sa_size_t k=0; k<mZColsP.size(); k++) 
+    mVarD[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off].real();
+  for(sa_size_t k=0; k<mSColsP.size(); k++) 
+    mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
+
+  return mVarD;
+}
+
+
+r_8  BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const 
+{
+  if ((n < 0) || (n >= NEntry())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
+  if ((k < 0) || (k >= NVar())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
+  double rv = BADVAL;
+  sa_size_t sk = mNames[k].ser;
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+
+  switch (mNames[k].type) {
+  case IntegerField :
+    rv = mIColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case LongField :
+    rv = mLColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case FloatField :
+    rv = mFColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case DoubleField :
+  case DateTimeField :
+    rv = mDColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case ComplexField :
+    rv = mYColsP[sk]->GetCstSegment(bid)[off].real();
+    break;
+  case DoubleComplexField :
+    rv = mZColsP[sk]->GetCstSegment(bid)[off].real();
+    break;
+  case StringField :
+    rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str());
+    break;
+  default:
+    rv = BADVAL;
+    break;
+  }
+  return rv ; 
+}
+
+
+r_8  BaseDataTable::GetCell(sa_size_t n, string const& nom) const 
+{
+  return GetCell(n, IndexNom(nom));
+}
+
+string   BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
+{
+  if ((n < 0) || (n >= NEntry())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
+  if ((k < 0) || (k >= NVar())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
+  MuTyV rv;;
+  sa_size_t sk = mNames[k].ser;
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  switch (mNames[k].type) {
+  case IntegerField :
+    rv = mIColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case LongField :
+    rv = mLColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case FloatField :
+    rv = mFColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case DoubleField :
+    rv = mDColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case ComplexField :
+    rv = mYColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case DoubleComplexField :
+    rv = mZColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case StringField :
+    rv = mSColsP[sk]->GetCstSegment(bid)[off];
+    break;
+  case DateTimeField :
+    rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
+    break;
+  default:
+    rv = " ";
+    break;
+  }
+  return (string)rv ; 
+}
+
+void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max)  const
+{
+  min = 9E39 ; max = -9E39 ; 
+  if ((k < 0) || (k >= NVar())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
+  if (mMinMaxNEnt.size() < NVar()) {
+    mMin.clear();
+    mMax.clear();
+    mMinMaxNEnt.clear();
+    for(size_t kk=0; kk<NVar(); kk++) {
+      mMin.push_back(0.);
+      mMax.push_back(0.);
+      mMinMaxNEnt.push_back(0);
+    }
+  }
+  if (mMinMaxNEnt[k] == mNEnt) {
+    min = mMin[k];
+    max = mMax[k];
+    return;
+  }
+  sa_size_t sk = mNames[k].ser;
+
+  sa_size_t cnt = 0;
+  switch (mNames[k].type) {
+  case IntegerField :
+    for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
+      const int_4* sp = mIColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n] > max) max = sp[n];
+	if (sp[n] < min) min = sp[n];
+	cnt++;
+      }
+    }
+    
+    break;
+  case LongField :
+    for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
+      const int_8* sp = mLColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n] > max) max = sp[n];
+	if (sp[n] < min) min = sp[n];
+	cnt++;
+      }
+    }
+    break;
+  case FloatField :
+    for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
+      const r_4* sp = mFColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n] > max) max = sp[n];
+	if (sp[n] < min) min = sp[n];
+	cnt++;
+      }
+    }
+    break;
+  case DoubleField :
+  case DateTimeField :
+    for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
+      const r_8* sp = mDColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n] > max) max = sp[n];
+	if (sp[n] < min) min = sp[n];
+	cnt++;
+      }
+    }
+    break;
+  case ComplexField :
+    for(size_t is=0; is<mYColsP[sk]->NbSegments(); is++) {
+      const complex<r_4> * sp = mYColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mYColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n].real() > max) max = sp[n].real();
+	if (sp[n].real() < min) min = sp[n].real();
+	cnt++;
+      }
+    }
+    break;
+  case DoubleComplexField :
+    for(size_t is=0; is<mZColsP[sk]->NbSegments(); is++) {
+      const complex<r_8> * sp = mZColsP[sk]->GetCstSegment(is);
+      for(size_t n=0; n<mZColsP[sk]->SegmentSize(); n++) {
+	if (cnt >= NEntry())  break;
+	if (sp[n].real() > max) max = sp[n].real();
+	if (sp[n].real() < min) min = sp[n].real();
+	cnt++;
+      }
+    }
+    break;
+  case StringField :
+    return;
+    break;
+  default:
+    return;
+    break;
+  }  
+
+  mMinMaxNEnt[k] = cnt; 
+  mMin[k] = min;
+  mMax[k] = max;
+  return ; 
+}
+
+
+void BaseDataTable::GetMinMax(string const & nom, double& min, double& max)   const
+{
+  GetMinMax(IndexNom(nom), min, max) ; 
+}
+
+
+sa_size_t BaseDataTable::ColumnIndex(string const& nom) const 
+{
+  return IndexNom(nom) ; 
+}
+
+
+string BaseDataTable::ColumnName(sa_size_t k) const 
+{
+  return NomIndex(k) ; 
+}
+
+
+string BaseDataTable::VarList_C(const char* nomx) const 
+{
+  string rets="";
+  sa_size_t i;
+  for(i=0; i<NVar(); i++) {
+    if ( (i%5 == 0) && (i > 0) )  rets += ";";  
+    if (i%5 == 0)   rets += "\ndouble "; 
+    else rets += ",";
+    rets += mNames[i].nom;
+  }
+  rets += "; \n";
+  if (nomx) { 
+    char buff[256];
+    for(i=0; i<NVar(); i++) {
+      rets += mNames[i].nom;
+      rets += '=';
+      
+      sprintf(buff,"%s[%ld]; ",  nomx, (long)i);
+      rets += buff;
+      if ( (i%3 == 0) && (i > 0) )  rets += "\n"; 
+    }
+  }
+  return(rets);
+}
+
+
+string BaseDataTable::LineHeaderToString() const 
+{
+  string rets,s;
+  
+  for(int i=0; i<NVar(); i++) {
+    s = mNames[i].nom;
+    size_t l = s.length();
+    for(size_t ii=l; ii<12; ii++) s += ' ';
+    if (i > 0) rets += ' ';   
+    rets += s;
+  }
+  return(rets);  
+}
+
+/*!
+  Return a table row (line) as a string
+  \sa TableRowToString()
+*/
+string BaseDataTable::LineToString(sa_size_t n) const
+{
+  return TableRowToString(n, false);
+}
+
+/*!
+  \param n : table row index ( 0 ... NEntry()-1) 
+  \param qstr : if true , enclose strings in quotes ''
+  \param sep : separates fields using \b sep
+  \param fw : minimum field width
+ */
+string BaseDataTable::TableRowToString(sa_size_t n, bool qstr, 
+				       const char* sep, int fw) const 
+{
+  if ((n < 0) || (n >= NEntry())) 
+    throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
+  string rs;
+  MuTyV rv;;
+  sa_size_t bid = n/mSegSz;
+  sa_size_t off = n%mSegSz;
+  for(sa_size_t k=0; k<NVar(); k++) {
+    sa_size_t sk = mNames[k].ser;
+    switch (mNames[k].type) {
+    case IntegerField :
+      rv = mIColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case LongField :
+      rv = mLColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case FloatField :
+      rv = mFColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case DoubleField :
+      rv = mDColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case ComplexField :
+      rv = mYColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case DoubleComplexField :
+      rv = mZColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case StringField :
+      rv = mSColsP[sk]->GetCstSegment(bid)[off];
+      break;
+    case DateTimeField :
+      rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
+      break;
+    default:
+      rv = " ";
+      break;
+    }
+    string s;
+    if ( (mNames[k].type == StringField) && (qstr) ) {
+      s = '\'';  s += (string)rv; s += '\''; 
+    }
+    else  s= (string)rv;
+    size_t l = s.length();
+    for(size_t ii=l; ii<fw; ii++) s += ' ';
+    if (k > 0) rs += sep;
+    rs += s;
+  }
+  return rs;
+}
+
+} // FIN namespace SOPHYA 
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/basedtable.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/basedtable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/basedtable.h	(revision 3445)
@@ -0,0 +1,336 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Class BaseDataTable 
+//   R. Ansari -  Avril 2005
+//   (C)  LAL-IN2P3/CNRS    CEA-DAPNIA  
+
+#ifndef BASEDTABLE_H_SEEN
+#define BASEDTABLE_H_SEEN
+
+#include "machdefs.h"
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+
+#include <complex>
+
+#include "ntupintf.h"
+#include "dvlist.h"
+#include "segdatablock.h"
+#include "tvector.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+//! Class for representing and manipulating DataTable rows.  
+class DataTableRow {
+public:
+//! Constructor - For use by BaseDataTable class
+  DataTableRow( vector<string> const & colnames );
+//! Copy constructor
+  DataTableRow( DataTableRow const & a );
+//! Returns the value for column \b k. No bound checking performed 
+  inline MuTyV      operator[]  (sa_size_t k)  const { return mtv_[k]; }
+//! Returns a reference to the value of column \b k. No bound checking performed 
+  inline MuTyV&     operator[]  (sa_size_t k)  { return mtv_[k]; }
+//! Returns the value for column \b colname. 
+  inline MuTyV      operator[]  (string const colname)  const { return get(colname); }
+//! Returns a reference to the value of column \b k. 
+  inline MuTyV&     operator[]  (string const colname)   { return get(colname); }
+//! Returns the value for column \b colname. 
+  MuTyV      get(string const& colname) const;
+//! Returns a reference to the value of column \b k. 
+  MuTyV&     get(string const& colname);
+//! Acces to the MuTyV pointer
+  inline sa_size_t  Size() const { return size_; }
+//! Acces to the MuTyV pointer
+  inline MuTyV const *     MTVPtr() const { return mtv_; }
+//! Acces to the MuTyV pointer
+  inline MuTyV*     MTVPtr() { return mtv_; }
+//! prints the object content on the output stream 
+  ostream&   Print(ostream& os) const;
+protected:
+  MuTyV * mtv_;
+  sa_size_t size_;
+  map<string , sa_size_t> nm2idx_;
+};
+
+/*! Prints the DataTableRow object content on the output stream ( */
+inline ostream& operator << (ostream& s, DataTableRow const & row)
+  {  row.Print(s);  return(s);  }
+
+//  Forward class declaration for Thread-safe operations
+class ThSafeOp;
+
+//! Interface definition for classes handling data in a table.
+class BaseDataTable : public AnyDataObj , public NTupleInterface {
+public:
+  // ===> DO NOT CHANGE EXISTING enum type VALUES !!! 
+  enum FieldType {IntegerField=1, LongField=2, 
+		  FloatField=3, DoubleField=4,
+		  ComplexField=5, DoubleComplexField=6,
+		  StringField=7, DateTimeField=8};
+  // <=====================================================> 
+
+  //! Return the column type as a string (long or short depending on fgl=true/false)
+  static string     ColTypeToString(FieldType ft, bool fgl=false);
+  //! Return the column type corresponding to \b sctyp
+  static FieldType  StringToColType(string const & sctyp);
+
+  // constructeur , destructeur 
+  BaseDataTable(sa_size_t segsz=512);
+  virtual           ~BaseDataTable();
+
+  // Activate/deactivate thread-safe AddRow()/GetRow() operation
+  virtual void      SetThreadSafe(bool fg=true);
+  //! Return true if AddRow()/GetRow()  operations are thread-safe
+  inline bool       IsThreadSafe() const { return ((mThS)?true:false); }
+  
+  //! Adds a column holding integer, named \b cnom
+  inline sa_size_t  AddIntegerColumn(const char * cnom) 
+  { return AddColumn(IntegerField, cnom); }
+  //! Adds a column holding integer, named \b cnom
+  inline sa_size_t  AddIntegerColumn(string const & cnom) 
+  { return AddColumn(IntegerField, cnom); }
+  //! Adds a column holding long integer, named \b cnom
+  inline sa_size_t  AddLongColumn(const char * cnom) 
+  { return AddColumn(LongField, cnom); }
+  //! Adds a column holding long integer, named \b cnom
+  inline sa_size_t  AddLongColumn(string const & cnom) 
+  { return AddColumn(LongField, cnom); }
+  //! Adds a column holding floating values (r_4), named \b cnom
+  inline sa_size_t  AddFloatColumn(const char * cnom) 
+  { return AddColumn(FloatField, cnom); }
+  //! Adds a column holding floating values (r_4), named \b cnom
+  inline sa_size_t  AddFloatColumn(string const & cnom) 
+  { return AddColumn(FloatField, cnom); }
+  //! Adds a column holding double values (r_8), named \b cnom
+  inline sa_size_t  AddDoubleColumn(const char * cnom) 
+  { return AddColumn(DoubleField, cnom); }
+  //! Adds a column holding double values (r_8), named \b cnom
+  inline sa_size_t  AddDoubleColumn(string const & cnom) 
+  { return AddColumn(DoubleField, cnom); }
+  //! Adds a column holding single precision complex values (complex<r_4>), named \b cnom
+  inline sa_size_t  AddComplexColumn(const char * cnom) 
+  { return AddColumn(ComplexField, cnom); }
+  //! Adds a column holding single precision complex values (complex<r_4>), named \b cnom
+  inline sa_size_t  AddComplexColumn(string const & cnom) 
+  { return AddColumn(ComplexField, cnom); }
+  //! Adds a column holding double precision complex values (complex<r_8>), named \b cnom
+  inline sa_size_t  AddDoubleComplexColumn(const char * cnom) 
+  { return AddColumn(DoubleComplexField, cnom); }
+  //! Adds a column holding double precision complex values (complex<r_8>), named \b cnom
+  inline sa_size_t  AddDoubleComplexColumn(string const & cnom) 
+  { return AddColumn(DoubleComplexField, cnom); }
+  //! Adds a column holding character strings, named \b cnom
+  inline sa_size_t  AddStringColumn(const char * cnom) 
+  { return AddColumn(StringField, cnom); }
+  //! Adds a column holding character strings, named \b cnom
+  inline sa_size_t  AddStringColumn(string const & cnom) 
+  { return AddColumn(StringField, cnom); }
+  //! Adds a column holding Date/Time value, named \b cnom 
+  inline sa_size_t  AddDateTimeColumn(const char * cnom) 
+  { return AddColumn(DateTimeField, cnom); }
+  //! Adds a column holding Date/Time value, named \b cnom 
+  inline sa_size_t  AddDateTimeColumn(string const & cnom) 
+  { return AddColumn(DateTimeField, cnom); }
+  
+  inline sa_size_t  AddColumn(FieldType ft, const char * cnom)
+  { string nom = cnom;  return AddColumn(ft, nom); }
+  
+  //! Pure virtual method for adding a new column to the Data Table
+  virtual sa_size_t AddColumn(FieldType ft, string const & cnom) = 0;
+  //! Duplicate the data table structure from the source Table
+  virtual sa_size_t CopyStructure(BaseDataTable const & a);
+  //! Checks if the two table have the same column structure
+  virtual bool      CompareStructure(BaseDataTable const & a);
+
+  // Verifie la validite du nom de colonne:envoie une exception
+  // si nom en double ou non valide
+  virtual bool      CheckColName(string const & cnom);
+  // Verifie et corrige si besoin un nom de colonne
+  virtual bool      CheckCorrectColName(string & cnom);
+
+  // Acces to various counts and parameters
+  //! Return the number of lines (rows) in the table)
+  inline sa_size_t  NRows() const { return mNEnt ; }
+  //! Return the number of lines (rows) in the table)
+  inline sa_size_t  NEntry() const { return mNEnt ; }
+  //! Return the number of columns in the tables (number of cells in a row)  
+  inline sa_size_t  NCols() const   { return mNames.size() ; } 
+  //! Return the number of columns in the tables (number of cells in a row)  
+  inline sa_size_t  NVar() const   { return mNames.size() ; } 
+  //! Return the number of columns in the tables (number of cells in a row)  
+  inline sa_size_t  NVars() const   { return mNames.size() ; } 
+  //! Return the segment size (SegDBInterface objects corresponding to columns)  
+  inline sa_size_t  SegmentSize() const   { return mSegSz ; } 
+  //! Return the number of segments (SegDBInterface objects corresponding to columns)  
+  inline sa_size_t  NbSegments() const   { return mNSeg ; } 
+
+  //! Return a compatible DataTableRow object (with table column names)
+  virtual DataTableRow  EmptyRow();
+
+  // Filling data structures (adding lines/rows)
+  virtual sa_size_t AddRow(const r_8* data);
+  // Filling data structures (adding lines/rows)
+  virtual sa_size_t AddRow(const MuTyV * data);
+  // Filling data structures (adding lines/rows)
+  virtual sa_size_t AddRow(DataTableRow const & data);
+
+  //! Alias for AddRow()
+  inline sa_size_t  AddLine(const r_8* data)
+  { return AddRow(data); }
+  //! Alias for AddRow()
+  inline sa_size_t  AddLine(const MuTyV * data)
+  { return AddRow(data); }
+  //! Alias for AddLine()
+  inline sa_size_t  AddLine(DataTableRow const & data)
+  { return AddRow(data); }
+
+  //! Alias for AddRow() - Kept for backward compatibility with NTuple class interface.
+  inline sa_size_t  Fill(const r_8* data)
+  { return AddRow(data); }
+
+  // Pour etendre la table -      
+  virtual sa_size_t Extend();
+
+  //! Return the information stored in row \b n of the table in \b row object
+  virtual DataTableRow&   GetRow(sa_size_t n, DataTableRow& row) const ;
+  //! Return the information stored in line (row) \b n of the table 
+  virtual MuTyV *   GetRow(sa_size_t n, MuTyV* mtvp=NULL) const ;
+  //! Return the information stored in line \b n of the table. Alias of GetLine 
+  inline  MuTyV *   GetLine(sa_size_t n) const 
+  { return GetRow(n); }
+
+  //! Return the information stored in column \b k of the table, converted to double 
+  virtual TVector<r_8>  GetColumnD(sa_size_t k) const ;
+
+  //! Return the information stored in column named \b nom of the table, converted to double 
+  inline TVector<r_8>  GetColumnD(char const * nom) const 
+  { return  GetColumnD(IndexNom(nom)) ; }
+  //! Return the information stored in column named \b nom of the table, converted to double 
+  inline TVector<r_8>  GetColumnD(string const & nom) const 
+  { return  GetColumnD(IndexNom(nom)) ; }
+
+  //! Return the index for column name \b nom  
+  sa_size_t         IndexNom(char const* nom) const ; 
+  //! Return the index for column name \b nom  
+  inline sa_size_t  IndexNom(string const & nom) const 
+  { return IndexNom(nom.c_str()); }
+  //! Return the column name for column index \b k
+  string            NomIndex(sa_size_t k) const ; 
+
+  //! Return the column type for column \b k (no check on index range)
+  inline FieldType  GetColumType(sa_size_t k) const
+  { return mNames[k].type; }
+  //! Return the column name  for column \b k (no check on index range)
+  inline const string & GetColumName(sa_size_t k)  const
+  { return mNames[k].nom; }
+  
+  
+  //! Copy or merges  the data from \b a into the data table (cp=true -> copy)
+  virtual void      CopyMerge(BaseDataTable const& a, bool cp=false) ; 
+
+  //! Clear/reset the table content and structure.
+  virtual void Clear() = 0;
+
+  //! Prints  the table content (ascii dump)
+  virtual ostream&  Print(ostream& os, sa_size_t lstart, sa_size_t lend, 
+			  sa_size_t lstep=1) const ;
+  //! Prints  the table content (ascii dump) on stream \b os
+  inline ostream&   Print(ostream& os) const
+  { return Print(os, 0, NEntry(), 1); }
+  //! Prints  the table content (ascii dump) on stream \b os
+  inline ostream&   WriteASCII(ostream& os) const 
+  { return Print(os, 0, NEntry(), 1); }
+
+  
+  //! Prints table definition and number of entries 
+  void              Show(ostream& os) const ; 
+  //! Prints table definition and number of entries on the standard output stream \b cout
+  inline void       Show() const { Show(cout) ; } 
+  
+  //! Return the associated DVList (info) object. 
+  DVList&           Info() const ; 
+  
+  // Remplissage depuis fichier ASCII 
+  sa_size_t	    FillFromASCIIFile(istream& is, char clm='#', const char* sep=" \t");
+  
+  //-------------------------------------------------------------
+  //-----------  Declaration de l interface NTuple --------------
+
+  virtual sa_size_t NbLines() const ;
+  virtual sa_size_t NbColumns() const ;
+  virtual r_8 *     GetLineD(sa_size_t n) const ;
+  virtual r_8	    GetCell(sa_size_t n, sa_size_t k) const ;
+  virtual r_8	    GetCell(sa_size_t n, string const & nom) const ;
+  virtual string    GetCelltoString(sa_size_t n, sa_size_t k) const ;
+  virtual void      GetMinMax(sa_size_t k, double& min, double& max)   const ; 
+  virtual void      GetMinMax(string const & nom, double& min, double& max)   const ; 
+  virtual sa_size_t ColumnIndex(string const & nom)  const ;
+  virtual string    ColumnName(sa_size_t k) const;
+  virtual string    VarList_C(const char* nomx=NULL) const ;
+  virtual string    LineHeaderToString() const;
+  virtual string    LineToString(sa_size_t n) const;  
+
+  //! Return a table row (line), formatted and converted to a string
+  virtual string    TableRowToString(sa_size_t n, bool qstr, const char* sep=" ",
+				     int fw=12) const; 
+
+  //  Pour la gestion de persistance PPF
+  friend class ObjFileIO<BaseDataTable> ;
+  // pour fichiers FITS
+  friend class FitsHandler<BaseDataTable>;
+  
+protected:
+  uint_8   mNEnt ;   // nb total d'entrees 
+  uint_8   mSegSz ;  // taille bloc/segment 
+  uint_8   mNSeg;    // Nb total de segments
+  mutable r_8 *  mVarD;    // Pour retourner une ligne de la table
+  mutable MuTyV *  mVarMTV;    // Pour retourner une ligne de la table en MuTyV
+
+  //! \cond   Pour pas inclure ds la documentation doxygen
+  typedef struct { 
+    string nom; 
+    FieldType type;
+    sa_size_t ser;
+  } colst;
+  //! \endcond  
+  std::vector<colst> mNames;
+
+  mutable DVList* mInfo;        // Infos (variables) attachees au NTuple
+
+  // Pour calculer et garder le min/max   
+  mutable std::vector<r_8> mMin;
+  mutable std::vector<r_8> mMax;
+  mutable std::vector<uint_8> mMinMaxNEnt;
+  
+  // Les pointeurs des SegDataBlock ...  
+  std::vector< SegDBInterface<int_4> * > mIColsP; 
+  std::vector< sa_size_t > mIColIdx;
+  std::vector< SegDBInterface<int_8> * > mLColsP; 
+  std::vector< sa_size_t > mLColIdx;
+  std::vector< SegDBInterface<r_4> * > mFColsP;
+  std::vector< sa_size_t > mFColIdx; 
+  std::vector< SegDBInterface<r_8> * > mDColsP; 
+  std::vector< sa_size_t > mDColIdx;
+  std::vector< SegDBInterface< complex<r_4> > * > mYColsP;
+  std::vector< sa_size_t > mYColIdx; 
+  std::vector< SegDBInterface< complex<r_8> > * > mZColsP; 
+  std::vector< sa_size_t > mZColIdx;
+  std::vector< SegDBInterface<string> * > mSColsP; 
+  std::vector< sa_size_t > mSColIdx;
+
+  ThSafeOp* mThS;       // != NULL -> Thread safe operations
+  
+}; 
+/*! Prints table information (Column name and type, min/max) on stream \b s (bd.Show(s)) */
+inline ostream& operator << (ostream& s, BaseDataTable const & bd)
+  {  bd.Show(s);  return(s);  }
+  
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/HiStats/datatable.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/datatable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/datatable.cc	(revision 3445)
@@ -0,0 +1,291 @@
+#include "datatable.h"
+#include "strutil.h"
+#include "pexceptions.h"
+#include "fiosegdb.h"
+#include "thsafeop.h"
+
+namespace SOPHYA { 
+
+/*!
+   \class DataTable
+   \ingroup HiStats
+   This class can be used to organize data in table (row-column) form.
+   Each column holds homogeneous data (same data type), while different
+   columns can be used for different data types 
+   (integer, float, string ...).
+   The whole data set is kept in memory.
+   \sa SOPHYA::MuTyV
+   \sa SOPHYA::DataTableRow
+   \sa SOPHYA::BaseDataTable
+   \sa SOPHYA::SegDataBlock
+
+   \code
+   #include "datatable.h"
+   // ...
+   DataTable dt(64);
+   dt.AddFloatColumn("X0_f");
+   dt.AddFloatColumn("X1_f");
+   dt.AddDoubleColumn("X0X0pX1X1_d");
+   double x[5];
+   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];
+     dt.AddRow(x);
+   }
+   // Printing table info
+   cout << dt ;
+   // Saving object into a PPF file
+   POutPersist po("dtable.ppf");
+   po << dt ;
+   \endcode
+
+  DataTableRow objects can also be used to fill the table, or access the data, as
+  shown in the example below:
+  \code
+  // We use the same table as in the example above:
+  DataTableRow row = dt.EmptyRow();
+  row[0] = 83.3; row[1] = 20.;   row[2] = 83.3*83.3+20.*20.;
+  dt.AddRow(row);
+  row["X0_f"] = 7.5; row["X1_f"] = 6.;  row["X0X0pX1X1_d"] = 7.5*7.5+6.*6.;
+  dt.AddRow(row);  
+  \endcode
+*/
+
+
+//! Default constructor - optional specification of block (or segment) size
+DataTable::DataTable(sa_size_t segsz)
+  : BaseDataTable(segsz)
+{
+}
+
+//! copy constructor 
+/*!
+  The copy constructur shares the data if \b share=true. 
+  Otherwise, the Clone() method is called to make a complete copy.
+  This constructor copies also the thread safety state from \b a .
+*/
+DataTable::DataTable(DataTable const & a, bool share)
+  : BaseDataTable(a.SegmentSize())
+{
+  if (share) Share(a);
+  else Clone(a);
+  mNEnt = a.mNEnt;
+  mNSeg = a.mNSeg;
+  if (a.mInfo)  mInfo = new DVList(*(a.mInfo));
+}
+/*! 
+  Copy the table structure from \b a and shares the data (columns content).
+  The tread-safety state is copied from \b a .
+*/
+void DataTable::Share(DataTable const & a)
+{
+  // On copie la structure de table 
+  CopyStructure(a);
+  if (a.IsThreadSafe())  SetThreadSafe(true);
+  else SetThreadSafe(false);
+  // Et on partage les donnees des colonnes 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    sa_size_t ska = a.mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk].Share(a.mICols[ska]); 
+    break;
+    case LongField :
+      mLCols[sk].Share(a.mLCols[ska]); 
+      break;
+    case FloatField :
+      mFCols[sk].Share(a.mFCols[ska]); 
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk].Share(a.mDCols[ska]); 
+      break;
+    case ComplexField :
+      mYCols[sk].Share(a.mYCols[ska]); 
+      break;
+    case DoubleComplexField :
+      mZCols[sk].Share(a.mZCols[ska]); 
+      break;
+    case StringField :
+      mSCols[sk].Share(a.mSCols[ska]); 
+      break;
+    default:
+      throw ForbiddenError("DataTable::Share() : unknown column type ");
+    break;
+    }
+  }  
+}
+
+//! Copy the table structure from \b a and duplicate (copy) the data (columns content)
+void DataTable::Clone(DataTable const & a)
+{
+  // On copie la structure de table 
+  CopyStructure(a);
+  if (a.IsThreadSafe())  SetThreadSafe(true);
+  else SetThreadSafe(false);
+  // Et on copie les donnees des colonnes 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    sa_size_t ska = a.mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk].Clone(a.mICols[ska], true); 
+    break;
+    case LongField :
+      mLCols[sk].Clone(a.mLCols[ska], true); 
+      break;
+    case FloatField :
+      mFCols[sk].Clone(a.mFCols[ska], true); 
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk].Clone(a.mDCols[ska], true); 
+      break;
+    case ComplexField :
+      mYCols[sk].Clone(a.mYCols[ska], true); 
+      break;
+    case DoubleComplexField :
+      mZCols[sk].Clone(a.mZCols[ska], true); 
+      break;
+    case StringField :
+      mSCols[sk].Clone(a.mSCols[ska], true); 
+      break;
+    default:
+      throw ForbiddenError("DataTable::Clone() : unknown column type ");
+    break;
+    }
+  }  
+}
+//! Reset (/clear) the table content and structure
+void DataTable::Clear()
+{
+  if ( (NVar() == 0) && (NEntry() == 0)) return;
+  mNEnt = 0;
+  mNSeg = 0;
+  if (mVarD) delete[] mVarD;
+  mVarD = NULL;
+  if (mVarMTV) delete[] mVarMTV;
+  mVarMTV = NULL;
+  mNames.clear();
+  if (mInfo) delete mInfo;
+  mInfo = NULL;
+  if (mThS) delete mThS;
+  mThS = NULL;
+  mMin.clear();
+  mMax.clear();
+  mMinMaxNEnt.clear();
+  mIColsP.clear();
+  mLColsP.clear();
+  mFColsP.clear();
+  mDColsP.clear();
+  mYColsP.clear();
+  mZColsP.clear();
+  mSColsP.clear();
+
+  mIColIdx.clear();
+  mLColIdx.clear();
+  mFColIdx.clear();
+  mDColIdx.clear();
+  mYColIdx.clear();
+  mZColIdx.clear();
+  mSColIdx.clear();
+
+  mICols.clear();
+  mLCols.clear();
+  mFCols.clear();
+  mDCols.clear();
+  mYCols.clear();
+  mZCols.clear();
+  mSCols.clear();
+}
+
+
+/*! 
+  Implements the action defined in the BaseDataTable interface.
+  In the current implementation, throws an exception (ParmError) 
+  if the table contains some data already.
+*/
+sa_size_t DataTable::AddColumn(FieldType ft, string const & cnom)
+{
+  if (NEntry() > 0) 
+    throw ParmError("DataTable::AddColumn() Table contains already data ");
+  CheckColName(cnom);
+  sa_size_t ser; 
+  sa_size_t idx = NVar(); 
+  switch (ft) {
+  case IntegerField :
+    ser = mICols.size();
+    mICols.push_back(SegDataBlock<int_4>(mSegSz));
+    mIColIdx.push_back(idx);
+    mIColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mICols.size(); kk++)
+      mIColsP[kk] = &(mICols[kk]);
+    break;
+  case LongField :
+    ser = mLCols.size();
+    mLCols.push_back(SegDataBlock<int_8>(mSegSz));
+    mLColIdx.push_back(idx);
+    mLColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mLCols.size(); kk++)
+      mLColsP[kk] = &(mLCols[kk]);
+    break;
+  case FloatField :
+    ser = mFCols.size();
+    mFCols.push_back(SegDataBlock<r_4>(mSegSz));
+    mFColIdx.push_back(idx);
+    mFColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mFCols.size(); kk++)
+      mFColsP[kk] = &(mFCols[kk]);
+    break;
+  case DoubleField :
+  case DateTimeField :
+    ser = mDCols.size();
+    mDCols.push_back(SegDataBlock<r_8>(mSegSz));
+    mDColIdx.push_back(idx);
+    mDColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mDCols.size(); kk++)
+      mDColsP[kk] = &(mDCols[kk]);
+    break;
+  case ComplexField :
+    ser = mYCols.size();
+    mYCols.push_back(SegDataBlock< complex<r_4> >(mSegSz));
+    mYColIdx.push_back(idx);
+    mYColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mYCols.size(); kk++)
+      mYColsP[kk] = &(mYCols[kk]);
+    break;
+  case DoubleComplexField :
+    ser = mZCols.size();
+    mZCols.push_back(SegDataBlock< complex<r_8> >(mSegSz));
+    mZColIdx.push_back(idx);
+    mZColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mZCols.size(); kk++)
+      mZColsP[kk] = &(mZCols[kk]);
+    break;
+  case StringField :
+    ser = mSCols.size();
+    mSCols.push_back(SegDataBlock<string>(mSegSz));
+    mSColIdx.push_back(idx);
+    mSColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mSCols.size(); kk++)
+      mSColsP[kk] = &(mSCols[kk]);
+    break;
+  default:
+    throw ParmError("DataTable::AddColumn() unknown field type ");
+    break;
+  }
+  colst col;
+  col.nom = cnom;
+  col.type = ft;
+  col.ser = ser;
+  mNames.push_back(col);
+
+  // Tableaux de calcul min-max
+  mMin.push_back(0.);
+  mMax.push_back(0.);
+  mMinMaxNEnt.push_back(0);
+
+  return NVar();
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/datatable.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/datatable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/datatable.h	(revision 3445)
@@ -0,0 +1,66 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Class DataTable  (Row-Column data table in memory) 
+//   R. Ansari -  Avril 2005
+//   (C)  LAL-IN2P3/CNRS    CEA-DAPNIA  
+
+#ifndef DATATABLE_H_SEEN
+#define DATATABLE_H_SEEN
+
+#include "basedtable.h"
+#include "objfio.h"
+
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+//! An implementation of BaseDataTable with data (columns) stored in memory.
+class DataTable : public BaseDataTable {
+public:
+  DataTable(sa_size_t segsz=512); 
+  DataTable(DataTable const& a, bool share=true); 
+  
+  virtual sa_size_t AddColumn(FieldType ft, string const & cnom);
+
+  //! Equal (copy) operator - Copies the data and the structure if necessary from \b a   
+  inline DataTable&  operator = (BaseDataTable const& a) 
+  { CopyMerge(a, true) ; return *this ; } 
+  //! Equal (copy) operator - Copies the data and the structure if necessary from \b a   
+  inline DataTable& operator = (DataTable const& a) 
+  { CopyMerge(a, true) ; return *this ; } 
+
+  //  Pour la gestion de persistance PPF
+  friend class ObjFileIO<BaseDataTable> ;
+  // pour fichiers FITS
+  friend class FitsHandler<BaseDataTable>;
+
+  //! Reset the table content and structure
+  virtual void Clear();
+protected:
+  void Share(DataTable const & a);
+  void Clone(DataTable const & a);
+
+  // Donnees en memoire
+  std::vector< SegDataBlock<int_4> > mICols; 
+  std::vector< SegDataBlock<int_8> > mLCols; 
+  std::vector< SegDataBlock<r_4> > mFCols;
+  std::vector< SegDataBlock<r_8> > mDCols; 
+  std::vector< SegDataBlock< complex<r_4> > > mYCols;
+  std::vector< SegDataBlock< complex<r_8> > > mZCols;
+  std::vector< SegDataBlock<string> > mSCols;     
+}; 
+  
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, DataTable & obj)
+{ ObjFileIO<BaseDataTable> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, DataTable & obj)
+{ ObjFileIO<BaseDataTable> fio(&obj); is.SkipToNextObject(); 
+  fio.Read(is); return(is); }
+// Classe pour la gestion de persistance
+// ObjFileIO<BaseDataTable>
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/fio_dtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/fio_dtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/fio_dtable.cc	(revision 3445)
@@ -0,0 +1,297 @@
+#include "datatable.h"
+#include "swppfdtable.h"
+#include "pexceptions.h"
+#include "fiosegdb.h"
+
+namespace SOPHYA {
+
+
+/*!
+   \class ObjFileIO<BaseDataTable>
+   \ingroup HiStats
+   Persistence (serialisation) handler for class DataTable classes
+*/
+/* --Methode-- */ 
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void   ObjFileIO<BaseDataTable>::WriteSelf(POutPersist& s)  const
+//	Serialisation en ecriture du DataTable sur stream PPF
+{
+  if (dobj == NULL)   
+    throw NullPtrError("ObjFileIO<BaseDataTable>::WriteSelf() NULL dobj pointer ");
+  //-------  On ecrit 3 uint_4 .... 
+  //  [0]: Numero de version ;
+  //  [1] : bit1 non nul -> has info  
+  //  [2] : =1 DataTable , =2 SwPPFDataTable 
+  //  [3] : reserve
+
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  SwPPFDataTable* swdt = dynamic_cast< SwPPFDataTable *> (dobj);
+  if ( (dt == NULL) && (swdt == NULL) )
+    throw IOExc("ObjFileIO<BaseDataTable>::WriteSelf() object not a DataTable or SwPPFDataTable");
+  if ( swdt && (swdt->mSwOut != &s) )
+    throw IOExc("ObjFileIO<SwPPFDataTable>::WriteSelf() (obj=SwPPFDataTable) OutputStream <> SwapStream");
+  uint_4 itab[4];
+  itab[0] = 1;  // Numero de version a 1
+  itab[1] = itab[2] = itab[3] = 0;
+  if (dobj->mInfo)  itab[1] = 1;
+  if (dt != NULL) itab[2] = 1;
+  else if (swdt != NULL) itab[2] = 2;
+  s.Put(itab, 4);
+
+  //-------- Ecriture de segment size, nb de colonnes, nb de lignes ...  
+  // [0] : SegmentSize()        [1] : NVar()
+  // [2] : NEntry()             [3] : NbSegments()
+  // [4] : reserve utilisation future
+  uint_8 ltab[5];
+  ltab[0] = dobj->SegmentSize();
+  ltab[1] = dobj->NVar();
+  ltab[2] = dobj->NEntry();
+  ltab[3] = dobj->NbSegments();
+  ltab[4] = 0;
+  s.Put(ltab, 5);
+
+  //------ Ecriture du nom et type des colonnes
+  for(sa_size_t k=0; k<dobj->NVar(); k++) { 
+    uint_2 typ = dobj->mNames[k].type;
+    s.Put(typ);
+    s.Put(dobj->mNames[k].nom);
+  }
+  // ------- Ecriture des tableaux min,max et n_minmax
+  for(uint_8 k=0; k<ltab[1]; k++) { 
+    s.Put(dobj->mMin[k]);
+    s.Put(dobj->mMax[k]);
+    s.Put(dobj->mMinMaxNEnt[k]);
+  }  
+  //------- Ecriture du DVList Info() associe, si existant
+  if (dobj->mInfo)  s << (*(dobj->mInfo));
+
+  //------- Ecriture des blocs de donnees Sw/SegDataBlock<T>
+  if (dt) {  // C'est un DataTable 
+  //.... Ecriture des SegDataBlock<T>
+    for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
+      sa_size_t sk = dobj->mNames[kk].ser;
+      switch (dobj->mNames[kk].type) {
+      case BaseDataTable::IntegerField :
+	s << dt->mICols[sk]; 
+	break;
+      case BaseDataTable::LongField :
+	s << dt->mLCols[sk]; 
+	break;
+      case BaseDataTable::FloatField :
+	s << dt->mFCols[sk]; 
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	s << dt->mDCols[sk]; 
+	break;
+      case BaseDataTable::ComplexField :
+	s << dt->mYCols[sk]; 
+	break;
+      case BaseDataTable::DoubleComplexField :
+	s << dt->mZCols[sk]; 
+	break;
+      case BaseDataTable::StringField :
+	s << dt->mSCols[sk]; 
+	break;
+      default:
+	throw IOExc("ObjFileIO<BaseDataTable>::WriteSelf() (DataTable) unknown column type ");
+	break;
+      }
+    }    
+  }
+  else if (swdt) {  // C'est un SwPPFDataTable
+    //.... Ecriture des tables de positionnement de SwSegDataBlock<T> 
+    for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
+      sa_size_t sk = dobj->mNames[kk].ser;
+      switch (dobj->mNames[kk].type) {
+      case BaseDataTable::IntegerField :
+	s.PutPosTagTable(swdt->mICols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::LongField :
+	s.PutPosTagTable(swdt->mLCols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::FloatField :
+	s.PutPosTagTable(swdt->mFCols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	s.PutPosTagTable(swdt->mDCols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::ComplexField :
+	s.PutPosTagTable(swdt->mYCols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::DoubleComplexField :
+	s.PutPosTagTable(swdt->mZCols[sk].GetSwapPosTagTable()); 
+	break;
+      case BaseDataTable::StringField :
+	s.PutPosTagTable(swdt->mSCols[sk].GetSwapPosTagTable()); 
+	break;
+      default:
+	throw IOExc("ObjFileIO<BaseDataTable>::WriteSelf() (SwPPFDataTable) unknown column type ");
+	break;
+      }
+    }    
+  }
+  return;
+  }
+  
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void  ObjFileIO<BaseDataTable>::ReadSelf(PInPersist& s)
+//	Serialisation en lecture du DataTable sur stream PPF
+{
+  // ------- On lit les 3 premiers uint_4
+  //  [0]: Numero de version ;
+  //  [1] : bit1 non nul -> has info  
+  //  [2] : =1 DataTable , =2 SwPPFDataTable 
+  //  [3] : reserve
+  uint_4 itab[4] = {0,0,0,0};
+  s.Get(itab, 4);
+  bool hadinfo = false;
+  if ((itab[1]&1) == 1)  hadinfo = true;
+  if ((itab[2] != 1) && (itab[2] != 2))
+    throw IOExc("ObjFileIO<BaseDataTable>::ReadSelf(): (itab[2]=type=1 or 2) supported only");    
+
+  // -------- Lecture de segment size, nb de colonnes, nb de lignes ...  
+  // [0] : SegmentSize()        [1] : NVar()
+  // [2] : NEntry()             [3] : NbSegments()
+  uint_8 ltab[5] = {0,0,0,0,0};
+  s.Get(ltab, 5);
+  if (dobj == NULL) {
+    if (itab[2] == 1)  dobj = new DataTable(ltab[0]);
+    else if (itab[2] == 2) dobj = new SwPPFDataTable(s, ltab[0]);
+  }
+  else {     
+    dobj->Clear();  
+    dobj->mSegSz = ltab[0]; 
+    SwPPFDataTable* swdtc = dynamic_cast< SwPPFDataTable *> (dobj);
+    // Copie brutale en utilisant l'operateur = 
+    if (swdtc && (itab[2] == 2)) *swdtc = SwPPFDataTable(s, ltab[0]);
+  }
+
+  DataTable* dt = dynamic_cast< DataTable *> (dobj);
+  SwPPFDataTable* swdt = dynamic_cast< SwPPFDataTable *> (dobj);
+  if ( (dt == NULL) && (swdt == NULL) )
+    throw IOExc("ObjFileIO<BaseDataTable>::ReadSelf() object not a DataTable or SwPPFDataTable");
+  if ( (itab[2] == 1) && (dt == NULL) )
+    throw IOExc("ObjFileIO<BaseDataTable>::ReadSelf() object not a DataTable and itab[2]=1");
+  if ( (itab[2] == 2) && (swdt == NULL) )
+    throw IOExc("ObjFileIO<BaseDataTable>::ReadSelf() object not a DataTable and itab[2]=1");
+
+  // -------- Lecture nom/type colonnes et allocation des colonnes
+  uint_2 typ; 
+  string cnom;
+  for(uint_8 k=0; k<ltab[1]; k++) { 
+    s.Get(typ);
+    s.Get(cnom);
+    BaseDataTable::FieldType ft = (BaseDataTable::FieldType)typ;
+    dobj->AddColumn(ft, cnom);
+  }
+  // ------- Lecture des tableaux min,max et n_minmax
+  for(uint_8 k=0; k<ltab[1]; k++) { 
+    s.Get(dobj->mMin[k]);
+    s.Get(dobj->mMax[k]);
+    s.Get(dobj->mMinMaxNEnt[k]);
+  }  
+  // ------- Lecture du DVList Info() associe, si necessaire
+  if (hadinfo) {    // Lecture eventuelle du DVList Info
+    if (dobj->mInfo == NULL)  dobj->mInfo = new DVList;
+    s >> (*(dobj->mInfo));
+  }
+  // ------- Mise a jour des champs Nb d'entrees, nb segments ...
+  dobj->mNEnt = ltab[2];
+  dobj->mNSeg = ltab[3];
+  // ------- Lecture des donnees Sw/SegDataBlock<T> ou Sw 
+  if (itab[2] == 1) {   // On lit un DataTable
+  // .... Lecture des SegDataBlock<T> 
+    for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
+      sa_size_t sk = dobj->mNames[kk].ser;
+      switch (dobj->mNames[kk].type) {
+      case BaseDataTable::IntegerField :
+	s >> dt->mICols[sk]; 
+	break;
+      case BaseDataTable::LongField :
+	s >> dt->mLCols[sk]; 
+	break;
+      case BaseDataTable::FloatField :
+	s >> dt->mFCols[sk]; 
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	s >> dt->mDCols[sk]; 
+	break;
+      case BaseDataTable::ComplexField :
+	s >> dt->mYCols[sk]; 
+	break;
+      case BaseDataTable::DoubleComplexField :
+	s >> dt->mZCols[sk]; 
+	break;
+      case BaseDataTable::StringField :
+	s >> dt->mSCols[sk]; 
+	break;
+      default:
+	throw IOExc("ObjFileIO<BaseDataTable>::ReadSelf() : unknown column type ");
+	break;
+      }
+    }    
+  }
+  else if (itab[2] == 2) {  // C'est un SwPPFDataTable
+    // .... Lecture des tag de positionnement des SwSegDataBlock<T> 
+    vector<int_8> swpos;
+    for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
+      sa_size_t sk = dobj->mNames[kk].ser;
+      switch (dobj->mNames[kk].type) {
+      case BaseDataTable::IntegerField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mICols[sk] = SwSegDataBlock<int_4>(swdt->mISwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::LongField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mLCols[sk] = SwSegDataBlock<int_8>(swdt->mLSwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::FloatField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mFCols[sk] = SwSegDataBlock<r_4>(swdt->mFSwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::DoubleField :
+      case BaseDataTable::DateTimeField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mDCols[sk] = SwSegDataBlock<r_8>(swdt->mDSwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::ComplexField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mYCols[sk] = SwSegDataBlock< complex<r_4> >(swdt->mYSwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::DoubleComplexField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mZCols[sk] = SwSegDataBlock< complex<r_8> >(swdt->mZSwapper, swpos, swdt->SegmentSize());
+	break;
+      case BaseDataTable::StringField :
+	swpos.clear();
+	s.GetPosTagTable(swpos);
+	swdt->mSCols[sk] = SwSegDataBlock<string>(swdt->mSSwapper, swpos, swdt->SegmentSize());
+	break;
+      default:
+	throw IOExc("ObjFileIO<SwPPFDataTable>::ReadSelf() : unknown column type ");
+	break;
+      }
+    }    
+  }
+return;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<BaseDataTable>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<BaseDataTable>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/hbook.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/hbook.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/hbook.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/HiStats/hisprof.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/hisprof.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/hisprof.cc	(revision 3445)
@@ -0,0 +1,423 @@
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "hisprof.h"
+#include "perrors.h"
+
+namespace SOPHYA {
+
+/*!
+  \class HProf
+  \ingroup HiStats
+  Classe de profil d'histogrammes.
+*/
+
+/********* Methode *********/
+/*!
+  Constructeur par defaut.
+*/
+HProf::HProf()
+: Histo(), mSumY(NULL), mSumY2(NULL), mSumW(NULL)
+, mOk(false), mYMin(1.), mYMax(-1.), mOpt(0)
+{
+}
+
+/********* 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(), mSumY(NULL), mSumY2(NULL), mSumW(NULL)
+{
+  CreateOrResize(xMin,xMax,nBin,yMin,yMax);
+}
+
+/********* Methode *********/
+/*!
+  Constructeur.
+*/
+HProf::HProf(r_4 xMin, r_4 xMax, int_4 nBin, r_4 yMin, r_4 yMax)
+: Histo(), mSumY(NULL), mSumY2(NULL), mSumW(NULL)
+{
+  CreateOrResize((r_8)xMin,(r_8)xMax,nBin,(r_8)yMin,(r_8)yMax);
+}
+
+/********* Methode *********/
+/*!
+  Constructeur par copie.
+*/
+HProf::HProf(const HProf& H)
+: Histo(H)
+, mSumY((H.mBins>0)  ? new r_8[H.mBins] : NULL)
+, mSumY2((H.mBins>0) ? new r_8[H.mBins] : NULL)
+, mSumW((H.mBins>0)  ? new r_8[H.mBins] : NULL)
+, mOk(H.mOk), mYMin(H.mYMin), mYMax(H.mYMax), mOpt(H.mOpt)
+{
+  if(mBins>0) {
+    memcpy(mSumY,  H.mSumY,  mBins*sizeof(r_8));
+    memcpy(mSumY2, H.mSumY2, mBins*sizeof(r_8));
+    memcpy(mSumW,  H.mSumW,  mBins*sizeof(r_8));
+  }
+  UpdateHisto();
+}
+
+/********* Methode *********/
+/*!
+  allocation
+*/
+void HProf::CreateOrResize(r_8 xMin, r_8 xMax, int_4 nBin, r_8 yMin, r_8 yMax)
+{
+  //cout<<"HProf::CreateOrResize()"<<endl;
+  bool samelen = (nBin==mBins)? true: false;
+  Histo::CreateOrResize(xMin,xMax,nBin);
+  Histo::Errors();
+  if(mSumW!=NULL && !samelen) { //si un est alloue alors les autres aussi
+    delete[] mSumY;  mSumY = NULL;
+    delete[] mSumY2; mSumY2= NULL;
+    delete[] mSumW;  mSumW = NULL;
+  }
+  if(nBin>0 && mSumW==NULL) {
+    mSumY  = new r_8[nBin];
+    mSumY2 = new r_8[nBin];
+    mSumW  = new r_8[nBin];
+  }
+  if(mSumW) {
+    memset(mSumY, 0, nBin*sizeof(r_8));
+    memset(mSumY2,0, nBin*sizeof(r_8));
+    memset(mSumW, 0, nBin*sizeof(r_8));
+  }
+  mYMin = yMin; mYMax = yMax;
+  mOk = false;
+  mOpt = 0;
+}
+
+/********* Methode *********/
+/*!
+  Des-allocation
+*/
+void HProf::Delete()
+{
+  //cout<<"HProf::Delete()"<<endl;
+  Histo::Delete();
+  if(mSumY != NULL) {delete[] mSumY;  mSumY = NULL;}
+  if(mSumY2!= NULL) {delete[] mSumY2; mSumY2 = NULL;}
+  if(mSumW != NULL) {delete[] mSumW;  mSumW = NULL;}
+  mOk = 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(!mOk || force) updatehisto();
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void HProf::Zero()
+{
+  Histo::Zero();
+  memset(mSumY,  0, mBins*sizeof(r_8));
+  memset(mSumY2, 0, mBins*sizeof(r_8));
+  memset(mSumW,  0, mBins*sizeof(r_8));
+  mOk = false;
+}
+
+
+/********* 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*w), E(j) = sum(y^2*w), L(j) = sum(w)
+    ->  h(j) = H(j)/L(j)   moyenne dans le bin
+    ->  s(j) = sqrt(E(j)/L(j) - (H(j)/L(j))^2)  dispersion dans le bin
+    ->  e(j) = s(j)/sqrt(L(j)) erreur sur la moyenne dans le bin
+    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!=mOpt) {mOpt=opt; mOk=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(mSumW[i]<=0.) {
+    m = e2 = 0.;
+  } else {
+    m  = mSumY[i]/mSumW[i];
+    e2 = mSumY2[i]/mSumW[i] - m*m;
+    if(mOpt) e2 /= mSumW[i];
+  }
+  mData[i] = m;
+  mErr2[i] = e2;
+}
+mOk = true;
+// Attention, a cause de "WriteSelf const" updatehisto doit etre "const".
+// Comme on veut modifier mOk, on est oblige de faire cette entourloupe:
+HProf *buff = (HProf *) this;
+buff->mOk = 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(mYMax>mYMin && (y<mYMin || mYMax<y)) return;
+  int_4 numBin = FindBin(x);
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    mOk = false;
+    mSumY[numBin]  += y*w;
+    mSumY2[numBin] += y*y*w;
+    mSumW[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(mYMax>mYMin && (y<mYMin || mYMax<y)) return;
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    mOk = false;
+    mSumY[numBin]  += y*w;
+    mSumY2[numBin] += y*y*w;
+    mSumW[numBin]  += w;
+    nHist += w;
+    nEntries++;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Operateur HProf H = H1
+*/
+HProf& HProf::operator = (const HProf& h)
+{
+ if(this == &h) return *this;
+ CreateOrResize(h.mMin,h.mMax,h.mBins,h.mYMin,h.mYMax);
+ if(mData) memcpy(mData,h.mData,mBins*sizeof(r_8));
+ if(mErr2) memcpy(mErr2,h.mErr2,mBins*sizeof(r_8));
+ mUnder = h.mUnder; mOver = h.mOver;
+ nHist = h.nHist; nEntries = h.nEntries;
+ if(mSumY)  memcpy(mSumY,  h.mSumY,  mBins*sizeof(r_8));
+ if(mSumY2) memcpy(mSumY2, h.mSumY2, mBins*sizeof(r_8));
+ if(mSumW)  memcpy(mSumW,  h.mSumW,  mBins*sizeof(r_8));
+ mOk = h.mOk;
+ mOpt = h.mOpt;
+
+ 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 SzMismatchError(PExcLongMessage(""));
+Histo *hthis = (Histo *) this;
+*hthis += (Histo) a;
+if(mBins>0) for(int_4 i=0;i<mBins;i++) {
+  mSumY[i]  += a.mSumY[i];
+  mSumY2[i] += a.mSumY2[i];
+  mSumW[i]  += a.mSumW[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 [] mSumY;  mSumY  = new r_8[nbinew]; memset(mSumY, 0,mBins*sizeof(r_8));
+    delete [] mSumY2; mSumY2 = new r_8[nbinew]; memset(mSumY2,0,mBins*sizeof(r_8));
+    delete [] mSumW;  mSumW  = new r_8[nbinew]; memset(mSumW, 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.mSumY[imi]  * binWidth/H.binWidth;
+      wY2 = H.mSumY2[imi] * binWidth/H.binWidth;
+      wW  = H.mSumW[imi]  * binWidth/H.binWidth;
+    } else {
+      wY  += H.mSumY[imi]  * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wY  += H.mSumY[ima]  * (xma -H.BinLowEdge(ima))/H.binWidth;
+      wY2 += H.mSumY2[imi] * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wY2 += H.mSumY2[ima] * (xma -H.BinLowEdge(ima))/H.binWidth;
+      wW  += H.mSumW[imi]  * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wW  += H.mSumW[ima]  * (xma -H.BinLowEdge(ima))/H.binWidth;
+      if(ima>imi+1) for(int_4 ii=imi+1;ii<ima;ii++)
+	{wY += H.mSumY[ii]; wY2 += H.mSumY2[ii]; wW += H.mSumW[ii];}
+    }
+    mSumY[i] += wY; mSumY2[i] += wY2; mSumW[i] += wW;
+  }
+  // On synchronise les tableaux mSum?? et l'Histogramme
+  updatehisto();
+}
+
+void HProf::Show(ostream & os) const
+{
+  UpdateHisto();
+  Histo::Show(os);
+  os <<"       ymin="<<mYMin<<" ymax="<<mYMax<<"  opt="<<mOpt<< endl;
+}
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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->mYMin);
+is.Get(dobj->mYMax);
+is.Get(dobj->mOpt);
+dobj->mOk = true;
+
+// Lecture des donnees propres a l'histogramme de profil.
+is.GetLine(strg,255);
+if(dobj->mBins>0) {
+  dobj->mSumY  = new r_8[dobj->mBins];
+  dobj->mSumY2 = new r_8[dobj->mBins];
+  dobj->mSumW  = new r_8[dobj->mBins];
+}
+is.Get(dobj->mSumY,  dobj->mBins);
+is.Get(dobj->mSumY2, dobj->mBins);
+is.Get(dobj->mSumW,  dobj->mBins);
+
+// Lecture de l'histogramme
+is >> (Histo&)(*dobj);
+
+return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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->mYMin,dobj->mYMax,dobj->mOpt);
+os.PutLine(strg);
+
+// Ecriture des valeurs
+os.Put(dobj->mBins);
+os.Put(dobj->mYMin);
+os.Put(dobj->mYMax);
+os.Put(dobj->mOpt);
+
+// Ecriture des donnees propres a l'histogramme de profil.
+sprintf(strg,"HProf: SumY SumY2 SumW");
+os.PutLine(strg);
+os.Put(dobj->mSumY,  dobj->mBins);
+os.Put(dobj->mSumY2, dobj->mBins);
+os.Put(dobj->mSumW,  dobj->mBins);
+
+// Ecriture de l'histogramme
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/hisprof.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/hisprof.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/hisprof.h	(revision 3445)
@@ -0,0 +1,117 @@
+#ifndef HISPROF_SEEN
+#define HISPROF_SEEN
+
+#include <stdio.h>
+#include "peida.h"
+#include "tvector.h"
+#include "ppersist.h"
+#include "histos.h"
+
+namespace SOPHYA {
+
+template <class T>  class FitsHandler;
+
+//! 1 dimension profile histograms
+class HProf : public Histo {
+  friend class ObjFileIO<HProf>;
+  friend class FitsHandler<Histo>;
+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.;}
+  //! Retourne le carre de la dispersion/erreur du bin i
+  inline r_8 SumW(int_4 i) const {return mSumW[i];}
+
+  // 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;
+  inline  void Show() const { Show(cout); }
+  //! 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 CreateOrResize(r_8 xMin, r_8 xMax, int_4 nBin, r_8 yMin=1., r_8 yMax=-1.);
+  void Delete();
+  void updatehisto() const;
+
+  r_8*         mSumY;  //!< somme
+  r_8*         mSumY2; //!< somme des carres
+  r_8*         mSumW;  //!< somme des poids
+  mutable bool mOk;    //!< true if update fait
+  r_8          mYMin;  //!< limite minimum Y pour somme
+  r_8          mYMax;  //!< limite maximum Y pour somme
+  uint_2       mOpt;   //!< options pour les erreurs
+};
+
+/*! Prints histogram information on stream \b s (h.Show(s)) */
+inline ostream& operator << (ostream& s, HProf const & h)
+  {  h.Show(s);  return(s);  }
+
+/*! \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); is.SkipToNextObject(); 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 SzMismatchError("HProf::operator +");
+HProf c(a);
+return (c += b);
+}
+
+} // Fin du namespace
+
+#endif // HISPROF_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/hist2err.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/hist2err.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/hist2err.cc	(revision 3445)
@@ -0,0 +1,440 @@
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "perrors.h"
+#include "fioarr.h"
+#include "hist2err.h"
+
+namespace SOPHYA {
+
+/*!
+  \class Histo2DErr
+  \ingroup HiStats
+  Classe d'histogrammes 1D avec erreurs donnees par l'utilisateur
+*/
+
+/********* Methode *********/
+/*! Constructeur par defaut */
+Histo2DErr::Histo2DErr(void)
+: xmin_(1.), xmax_(-1.), dx_(0.) , ymin_(1.), ymax_(-1.), dy_(0.)
+  , nx_(0), ny_(0), mMean(0)
+{
+}
+
+/********* Methode *********/
+/*! Constructeur d'un histo */
+Histo2DErr::Histo2DErr(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny)
+{
+ CreateOrResize(xmin,xmax,nx,ymin,ymax,ny);
+}
+
+/********* Methode *********/
+/*! Constructeur par copie */
+Histo2DErr::Histo2DErr(const Histo2DErr& H)
+: xmin_(1.), xmax_(-1.), dx_(0.) , ymin_(1.), ymax_(-1.), dy_(0.)
+  , nx_(0), ny_(0), mMean(0)
+{
+ if(H.nx_<=0 || H.ny_<=0) return;
+ CreateOrResize(H.xmin_,H.xmax_,H.nx_,H.ymin_,H.ymax_,H.ny_);
+ data_  = H.data_; 
+ err2_  = H.err2_; 
+ ndata_ = H.ndata_; 
+ mMean = H.mMean;
+}
+
+/********* Methode *********/
+/*! Destructeur */
+Histo2DErr::~Histo2DErr(void)
+{
+ mMean = 0;
+}
+
+/********* Methode *********/
+/*! Gestion de l'allocation */
+void Histo2DErr::CreateOrResize(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny)
+{
+  xmin_ = xmin; xmax_ = xmax; nx_ = nx; dx_=0.;
+  ymin_ = ymin; ymax_ = ymax; ny_ = ny; dy_=0.;
+  if(nx_>0 && ny_>0) {
+    data_.ReSize(nx_,ny_);  data_ = 0.;
+    err2_.ReSize(nx_,ny_);  err2_ = 0.;
+    ndata_.ReSize(nx_,ny_); ndata_ = 0.;
+    dx_ = (xmax_-xmin_)/nx_;
+    dy_ = (ymax_-ymin_)/ny_;
+  }
+  mMean = 0;
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void Histo2DErr::Zero(void)
+{
+ if(nx_<=0 || ny_<=0) return;
+ data_ = 0.;
+ err2_ = 0.;
+ ndata_ = 0.;
+ mMean = 0;
+}
+
+/********* Methode *********/
+/*!
+ Recompute XMin (YMin) and XMax (YMax) so that
+ the CENTER of the first bin is exactly XMin (YMin) and
+ the CENTER of the last bin is exactly XMax (YMax).
+ Remember that otherwise
+ XMin (YMin) is the beginning of the first bin
+ and XMax (YMax) is the end of the last bin
+ WARNING: number of bins is kept, bin width is changed
+*/
+void Histo2DErr::ReCenterBinX(void)
+{
+ if(nx_<=1) return;
+ double dx = (xmax_-xmin_)/(nx_-1);
+ xmin_ -= dx/2.;
+ xmax_ += dx/2.;
+ dx_ = (xmax_-xmin_)/nx_;
+}
+
+void Histo2DErr::ReCenterBinY(void)
+{
+ if(ny_<=1) return;
+ double dy = (ymax_-ymin_)/(ny_-1);
+ ymin_ -= dy/2.;
+ ymax_ += dy/2.;
+ dy_ = (ymax_-ymin_)/ny_;
+}
+
+void Histo2DErr::ReCenterBin(void)
+{
+ ReCenterBinX();
+ ReCenterBinY();
+}
+
+/********* Methode *********/
+/*!
+ Recompute XMin (YMin) and XMax (YMax) so that
+ the CENTER of the first bin is exactly XMin (YMin) and
+ the CENTER of the last bin is exactly XMax (YMax).
+ Remember that otherwise
+ XMin (YMin) is the beginning of the first bin
+ and XMax (YMax) is the end of the last bin
+ WARNING: bin widths are kept, numbers of bins are increased by 1
+*/
+void Histo2DErr::ReCenterBinW(void)
+{
+ CreateOrResize(xmin_-dx_/2.,xmax_+dx_/2.,nx_+1,ymin_-dy_/2.,ymax_+dy_/2.,ny_+1);
+}
+
+/********* Methode *********/
+/*!
+  Compute the mean histogram.
+  Each bin content is divided by the number of entries in the bin.
+  Each squared error is divided by the number of entries in the bin.
+  The number of entries by bin is NOT set to 1
+  (calling ToMean many time will change the histogram !)
+*/
+void Histo2DErr::ToMean(void)
+{
+ if(nx_<1 || ny_<1) return;
+ mMean++;
+ for(int_4 i=0;i<nx_;i++) {
+   for(int_4 j=0;j<ny_;j++) {
+     if(ndata_(i,j)<1.) continue;
+     data_(i,j) /= ndata_(i,j);
+     err2_(i,j) /= ndata_(i,j);
+   }
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Recompute back the original Histo2DErr after ToMean action
+*/
+void Histo2DErr::FromMean(void)
+{
+ if(nx_<1 || ny_<1) return;
+ mMean--;
+ for(int_4 i=0;i<nx_;i++) {
+   for(int_4 j=0;j<ny_;j++) {
+     if(ndata_(i,j)<1.) continue;
+     data_(i,j) *= ndata_(i,j);
+     err2_(i,j) *= ndata_(i,j);
+   }
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+  Compute the mean histogram and replace the "error table" by the variance.
+  This should be done if Add(x,w,w) has been used.
+  The "value table" is divided by the number of entries to get the mean
+  The "error table" is replace by the variance
+  The number of entries by bin is NOT set to 1 
+  (calling ToMean many time will change the histogram !)
+  Mixing ToMean and ToVariance leads to unpredictable results
+*/
+void Histo2DErr::ToVariance(void)
+{
+ if(nx_<1 || ny_<1) return;
+ mMean++;
+ for(int_4 i=0;i<nx_;i++) {
+   for(int_4 j=0;j<ny_;j++) {
+     if(ndata_(i,j)<1.) continue;
+     data_(i,j) /= ndata_(i,j);
+     err2_(i,j) = err2_(i,j)/ndata_(i,j) - data_(i,j)*data_(i,j);
+   }
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Recompute back the original HistoErr after ToVariance action
+  Mixing FromMean and FromVariance leads to unpredictable results
+*/
+void Histo2DErr::FromVariance(void)
+{
+ if(nx_<1 || ny_<1) return;
+ mMean--;
+ for(int_4 i=0;i<nx_;i++) {
+   for(int_4 j=0;j<ny_;j++) {
+     if(ndata_(i,j)<1.) continue;
+     err2_(i,j) = ndata_(i,j)*(err2_(i,j) + data_(i,j)*data_(i,j));
+     data_(i,j) *= ndata_(i,j);
+   }
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Fill the histogram with an other histogram
+*/
+void Histo2DErr::FillFrHErr(Histo2DErr& hfrom)
+{
+ if(nx_<=0 || ny_<=0) return;
+ if(hfrom.nx_<=0 || hfrom.ny_<=0) return;
+
+ Zero();
+
+ for(int_4 i=0;i<hfrom.nx_;i++) {
+   for(int_4 j=0;j<hfrom.ny_;j++) {
+     r_8 x,y;  hfrom.BinCenter(i,j,x,y);
+     int ii,jj; FindBin(x,y,ii,jj);
+     if(jj<0 || jj>=ny_ || ii<0 || ii>=nx_) continue;
+     data_(ii,jj)  += hfrom.data_(ii,jj);
+     err2_(ii,jj)  += hfrom.err2_(ii,jj);
+     ndata_(ii,jj) += hfrom.ndata_(ii,jj);
+   }
+ }
+ mMean = hfrom.mMean;
+
+}
+
+/********* Methode *********/
+/*!
+  Operateur egal Histo2DErr = Histo2DErr
+*/
+Histo2DErr& Histo2DErr::operator = (const Histo2DErr& h)
+{
+  if(this==&h) return *this;
+  CreateOrResize(h.xmin_,h.xmax_,h.nx_,h.ymin_,h.ymax_,h.ny_);
+  data_  = h.data_;
+  err2_  = h.err2_;
+  ndata_ = h.ndata_;
+  mMean = h.mMean;
+  return *this;
+}
+
+/********* Methode *********/
+/*!
+  Operateur de multiplication par une constante
+*/
+Histo2DErr& Histo2DErr::operator *= (r_8 b)
+{
+r_8 b2 = b*b;
+for(int_4 i=0;i<nx_;i++) {
+  for(int_4 j=0;j<ny_;j++) {
+    data_(i,j) *= b;
+    err2_(i,j) *= b2;
+  }
+}
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Print info
+*/
+void Histo2DErr::Show(ostream & os) const
+{
+  os <<"Histo2DErr(nmean="<<mMean<<")"<<endl
+     <<"          nx="<<nx_<<" ["<<xmin_<<","<<xmax_<<"] dx="<<dx_<<endl
+     <<"          ny="<<ny_<<" ["<<ymin_<<","<<ymax_<<"] dy="<<dy_<<endl;
+}
+
+/********* Methode *********/
+/*!
+  Write to an ASCII file
+*/
+int Histo2DErr::WriteASCII(string fname)
+{
+  FILE *file = fopen(fname.c_str(),"w");
+  if(file==NULL) {
+    cout<<"Histo2DErr::WriteASCII_Error: error opening "<<fname<<endl;
+    return -1;
+  }
+
+  if(NBinX()<=0 || NBinY()<=0) {
+    cout<<"Histo2DErr::WriteASCII_Error: wrong number of bins"<<endl;
+    return -2;
+  }
+
+  fprintf(file,"%ld %.17e %.17e %.17e %ld %.17e %.17e %.17e %d\n"
+	 ,(long)NBinX(),XMin(),XMax(),WBinX()
+	 ,(long)NBinY(),YMin(),YMax(),WBinY()
+         ,NMean());
+  for(long i=0;i<NBinX();i++) for(long j=0;j<NBinY();j++) {
+    // ligne = i*NY+j
+    fprintf(file,"%ld %ld %.17e %.17e %.0f\n"
+           ,i,j,(*this)(i,j),Error2(i,j),NEntBin(i,j));
+  }
+
+  fclose(file);
+  return 0;
+}
+
+/*!
+  Read from an ASCII file
+*/
+#define __LENLINE_Histo2DErr_ReadASCII__ 2048
+int Histo2DErr::ReadASCII(string fname)
+{
+  FILE *file = fopen(fname.c_str(),"r");
+  if(file==NULL) {
+    cout<<"Histo2DErr::ReadASCII_Error: error opening "<<fname<<endl;
+    return -1;
+  }
+
+  char line[__LENLINE_Histo2DErr_ReadASCII__];
+  long n=0, nbinx=0, nbiny=0;
+
+  while ( fgets(line,__LENLINE_Histo2DErr_ReadASCII__,file) != NULL ) {
+
+    if(n==0) {
+
+      r_8 xmin,xmax,wx, ymin,ymax,wy; long mnmean=1;
+      sscanf(line,"%ld %lf %lf %lf %ld %lf %lf %lf %ld"
+            ,&nbinx,&xmin,&xmax,&wx
+            ,&nbiny,&ymin,&ymax,&wy
+            ,&mnmean);
+      if(nbinx<=0 || nbiny<=0) {
+        cout<<"Histo2Err::ReadASCII_Error: wrong number of bins"<<endl;
+        return -2;
+      }
+      CreateOrResize(xmin,xmax,nbinx,ymin,ymax,nbiny);
+      SetMean(mnmean);
+
+    } else {
+
+      long i,j; r_8 v,e2,nb;
+      sscanf(line,"%ld %ld %lf %lf %lf",&i,&j,&v,&e2,&nb);
+      SetBin(i,j,v);
+      SetErr2(i,j,e2);
+      SetNentB(i,j,nb);
+
+    }
+
+    n++;
+  }
+
+  fclose(file);
+  return 0;
+}
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<Histo2DErr>::ReadSelf(PInPersist& is)
+{
+string strg;
+
+if(dobj==NULL) dobj = new Histo2DErr;
+
+// Lecture entete
+is.GetStr(strg);
+
+// Nombre d'appels a ToMean/FromMean
+is.Get(dobj->mMean);
+
+// Lecture des parametres Histo2DErr
+is.Get(dobj->xmin_);
+is.Get(dobj->xmax_);
+is.Get(dobj->nx_);
+is.Get(dobj->dx_);
+is.Get(dobj->ymin_);
+is.Get(dobj->ymax_);
+is.Get(dobj->ny_);
+is.Get(dobj->dy_);
+
+// Lecture des donnees
+if(dobj->nx_>0 && dobj->ny_>0) {
+  is >> dobj->data_;
+  is >> dobj->err2_;
+  is >> dobj->ndata_;
+}
+
+return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<Histo2DErr>::WriteSelf(POutPersist& os) const
+{
+if(dobj == NULL)   return;
+string strg;
+
+// Ecriture entete
+strg = "Hist2DErr";
+os.PutStr(strg);
+
+// Nombre d'appels a ToMean/FromMean
+os.Put(dobj->mMean);
+
+// Ecriture des parametres Histo2DErr
+os.Put(dobj->xmin_);
+os.Put(dobj->xmax_);
+os.Put(dobj->nx_);
+os.Put(dobj->dx_);
+os.Put(dobj->ymin_);
+os.Put(dobj->ymax_);
+os.Put(dobj->ny_);
+os.Put(dobj->dy_);
+
+// Ecriture des donnees
+if(dobj->nx_>0 && dobj->ny_>0) {
+  os << dobj->data_;
+  os << dobj->err2_;
+  os << dobj->ndata_;
+}
+
+return;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Histo2DErr>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Histo2DErr>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/hist2err.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/hist2err.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/hist2err.h	(revision 3445)
@@ -0,0 +1,186 @@
+#ifndef HIST2ERR_SEEN
+#define HIST2ERR_SEEN
+
+#include "objfio.h"
+#include <iostream>
+#include <stdio.h>
+#include "tmatrix.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+//! 2 dimensions histograms with errors given by user
+class Histo2DErr : public AnyDataObj {
+  friend class ObjFileIO<Histo2DErr>;
+  friend class FitsHandler<Histo2DErr>;
+public:
+
+  //! Create or destroy
+  Histo2DErr(void);
+  Histo2DErr(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny);
+  Histo2DErr(const Histo2DErr& H);
+  virtual ~Histo2DErr(void);
+
+  //! Updating or Setting
+  void ReCenterBinX(void);
+  void ReCenterBinY(void);
+  void ReCenterBin(void);
+  void ReCenterBinW(void);
+  void Zero(void);
+
+  //! Getting Info
+  int_4 NBinX(void) {return nx_;}
+  int_4 NBinY(void) {return ny_;}
+  r_8 XMin(void) {return xmin_;}
+  r_8 YMin(void) {return ymin_;}
+  r_8 XMax(void) {return xmax_;}
+  r_8 YMax(void) {return ymax_;}
+  r_8 WBinX(void) {return dx_;}
+  r_8 WBinY(void) {return dy_;}
+
+  //! Retourne le contenu du bin
+  inline r_8 operator()(int_4 i,int_4 j) const
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return 0.;
+    return data_(i,j);
+    }
+  inline r_8& operator()(int_4 i,int_4 j)
+    {
+    return data_(i,j);
+    }
+
+  //! Retourne le nombre l'erreur au carre dans le bin
+  inline r_8 Error2(int_4 i,int_4 j) const
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return 0.;
+    return err2_(i,j);
+    }
+  inline r_8 Error(int_4 i,int_4 j) const
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return 0.;
+    if(err2_(i,j)>0.) return sqrt(err2_(i,j)); else return 0.;
+    }
+
+  //! Retourne le nombre d'entree dans le bin
+  inline r_8 NEntBin(int_4 i,int_4 j) const
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return 0.;
+    return ndata_(i,j);
+    }
+
+  //! 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 = xmin_ + i*dx_; y = ymin_ + j*dy_;}
+  //! 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 = xmin_ + (i+0.5)*dx_; y = ymin_ + (j+0.5)*dy_;}
+  //! 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 = xmin_ + (i+1)*dx_; y = ymin_ + (j+1)*dy_;}
+  //! 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-xmin_)/dx_); j=(int_4) floor((y-ymin_)/dy_);}
+
+  //! Addition du contenu de l'histo pour abscisse x poids w et l'erreur e2
+  inline void Add(r_8 x, r_8 y, r_8 w, r_8 e)
+    {
+    int_4 i,j; FindBin(x,y,i,j);
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return;
+    data_(i,j) += w; ndata_(i,j) += 1.; err2_(i,j) += e*e;
+    }
+  inline void Add(r_8 x,r_8 y, r_8 w) {Add(x,y,w,w);}
+
+  //! Addition du contenu de l'histo pour le bin numBin poids w et l'erreur e
+  inline void AddBin(int_4 i,int_4 j, r_8 w, r_8 e)
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return;
+    data_(i,j) += w; ndata_(i,j) += 1.; err2_(i,j) += e*e;
+    }
+  inline void AddBin(int_4 i,int_4 j, r_8 w) {AddBin(i,j,w,w);}
+
+  //! remplissage contenu de l'histo pour le bin i poids w et l'erreur e
+  inline void SetBin(int_4 i,int_4 j, r_8 w, r_8 e, r_8 nb)
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return;
+    data_(i,j)  = w;
+    err2_(i,j)  = e*e;
+    ndata_(i,j) = nb;
+    }
+  //! remplissage de la valeur pour le bin i
+  inline void SetBin(int_4 i,int_4 j, r_8 w)
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return;
+    data_(i,j) = w;
+    }
+  //! remplissage de l'erreur carree pour le bin i
+  void SetErr2(int_4 i,int_4 j, r_8 e2)
+    {
+    if(i<0 || i>=nx_) return;
+    err2_(i,j) = e2;
+    }
+  //! remplissage nombre d'entrees pour le bin i
+  void SetNentB(int_4 i,int_4 j, r_8 nb)
+    {
+    if(i<0 || i>=nx_ || j<0 || j>=ny_) return;
+    ndata_(i,j) = nb;
+    }
+
+  //! Compute the Mean histogram
+  void ToMean(void);
+  void FromMean(void);
+  int_4 NMean(void) {return mMean;}
+  void SetMean(int_4 nmean) {mMean = nmean;}
+
+  //! Replace the errors by the variance
+  void ToVariance(void);
+  void FromVariance(void);
+
+  //! Fill an histogram with an histogram
+  void FillFrHErr(Histo2DErr& hfrom);
+
+  //! Recuperation des matrices elementaires
+  void GetData(TMatrix<r_8>& data) {data = data_;}
+  void GetError2(TMatrix<r_8>& err2) {err2 = err2_;}
+  void GetNData(TMatrix<r_8>& ndata) {ndata = ndata_;}
+
+  // Operators
+  Histo2DErr& operator = (const Histo2DErr& h);
+  Histo2DErr& operator *= (r_8 b);
+
+  // Print
+  void Show(ostream& os) const;
+  void Show() const { Show(cout); }
+
+  // Write ASCII
+  int WriteASCII(string fname);
+  int ReadASCII(string fname);
+
+protected:
+  void CreateOrResize(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny);
+
+  r_4 xmin_,xmax_,dx_,ymin_,ymax_,dy_;
+  int_4 nx_,ny_;
+  TMatrix<r_8> data_;
+  TMatrix<r_8> err2_;
+  TMatrix<r_8> ndata_;
+  int_4 mMean;  //!< Nombre d'appels a ToMean/Variance(+1) ou FromMean/Variance(-1)
+};
+
+/*! Prints histogram information on stream \b s (h.Show(s)) */
+inline ostream& operator << (ostream& s, Histo2DErr const & h)
+  {  h.Show(s);  return(s);  }
+
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo2DErr)
+  \brief Persistance management */
+inline POutPersist& operator << (POutPersist& os, Histo2DErr & obj)
+{ ObjFileIO<Histo2DErr> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo2DErr)
+  \brief Persistance management */
+inline PInPersist& operator >> (PInPersist& is, Histo2DErr & obj)
+{ ObjFileIO<Histo2DErr> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif // HIST2ERR_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/histats.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histats.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histats.h	(revision 3445)
@@ -0,0 +1,15 @@
+#ifndef HISTATS_SEEN
+#define HISTATS_SEEN
+
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "histerr.h"
+#include "hist2err.h"
+#include "ntuple.h"
+#include "xntuple.h"
+#include "datatable.h"
+#include "swppfdtable.h"
+
+#endif // HISTATS_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/histerr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histerr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histerr.cc	(revision 3445)
@@ -0,0 +1,437 @@
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "perrors.h"
+#include "fioarr.h"
+#include "histerr.h"
+
+namespace SOPHYA {
+
+/*!
+  \class HistoErr
+  \ingroup HiStats
+  Classe d'histogrammes 1D avec erreurs donnees par l'utilisateur
+*/
+
+/********* Methode *********/
+/*! Constructeur par defaut */
+HistoErr::HistoErr(void)
+: xmin_(1.), xmax_(-1.), dx_(0.), nx_(0), mMean(0)
+{
+}
+
+/********* Methode *********/
+/*! Constructeur d'un histo */
+HistoErr::HistoErr(r_8 xmin,r_8 xmax,int_4 nx)
+{
+ CreateOrResize(xmin,xmax,nx);
+}
+
+/********* Methode *********/
+/*! Constructeur par copie */
+HistoErr::HistoErr(const HistoErr& H)
+: xmin_(1.), xmax_(-1.), dx_(0.), nx_(0), mMean(0)
+{
+ if(H.nx_<=0) return;
+ CreateOrResize(H.xmin_,H.xmax_,H.nx_);
+ data_  = H.data_; 
+ err2_  = H.err2_; 
+ ndata_ = H.ndata_; 
+ mMean = H.mMean;
+}
+
+/********* Methode *********/
+/*! Destructeur */
+HistoErr::~HistoErr(void)
+{
+ mMean = 0;
+}
+
+/********* Methode *********/
+/*! Gestion de l'allocation */
+void HistoErr::CreateOrResize(r_8 xmin,r_8 xmax,int_4 nx)
+{
+  xmin_ = xmin; xmax_ = xmax; nx_ = nx; dx_=0.;
+  if(nx_>0) {
+    data_.ReSize(nx_);  data_ = 0.;
+    err2_.ReSize(nx_);  err2_ = 0.;
+    ndata_.ReSize(nx_); ndata_ = 0.;
+    dx_ = (xmax_-xmin_)/nx_;
+  }
+  mMean = 0;
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void HistoErr::Zero(void)
+{
+ if(nx_<=0) return;
+ data_ = 0.;
+ err2_ = 0.;
+ ndata_ = 0.;
+ mMean = 0;
+}
+
+/********* Methode *********/
+/*!
+ Recompute XMin and XMax so that
+ the CENTER of the first bin is exactly XMin and
+ the CENTER of the last bin is exactly XMax.
+ Remember that otherwise
+ XMin is the beginning of the first bin
+ and XMax is the end of the last bin
+ WARNING: number of bins is kept, bin width is changed
+*/
+void HistoErr::ReCenterBin(void)
+{
+ if(nx_<=1) return;
+ double dx = (xmax_-xmin_)/(nx_-1);
+ xmin_ -= dx/2.;
+ xmax_ += dx/2.;
+ dx_ = (xmax_-xmin_)/nx_;
+}
+
+/********* Methode *********/
+/*!
+ Recompute XMin and XMax so that
+ the CENTER of the first bin is exactly XMin and
+ the CENTER of the last bin is exactly XMax.
+ Remember that otherwise
+ XMin is the beginning of the first bin
+ and XMax is the end of the last bin
+ WARNING: bin width is kept, number of bins is increased by 1
+*/
+void HistoErr::ReCenterBinW(void)
+{
+ if(nx_<=1) return;
+ CreateOrResize(xmin_-dx_/2.,xmax_+dx_/2.,nx_+1);
+}
+
+/********* Methode *********/
+/*!
+  Compute the mean histogram.
+  Each bin content is divided by the number of entries in the bin.
+  Each squared error is divided by the number of entries in the bin.
+  The number of entries by bin is NOT set to 1 
+  (calling ToMean many time will change the histogram !)
+*/
+void HistoErr::ToMean(void)
+{
+ if(nx_<1) return;
+ mMean++;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   data_(i) /= ndata_(i);
+   err2_(i) /= ndata_(i);
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Recompute back the original HistoErr after ToMean action
+*/
+void HistoErr::FromMean(void)
+{
+ if(nx_<1) return;
+ mMean--;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   data_(i) *= ndata_(i);
+   err2_(i) *= ndata_(i);
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+  Compute the mean histogram and replace the "error table" by the variance.
+  This should be done if Add(x,w,w) has been used.
+  The "value table" is divided by the number of entries to get the mean
+  The "error table" is replace by the variance
+  The number of entries by bin is NOT set to 1 
+  (calling ToMean many time will change the histogram !)
+  Mixing ToMean and ToVariance leads to unpredictable results
+*/
+void HistoErr::ToVariance(void)
+{
+ if(nx_<1) return;
+ mMean++;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   data_(i) /= ndata_(i);
+   err2_(i) = err2_(i)/ndata_(i) - data_(i)*data_(i);
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Recompute back the original HistoErr after ToVariance action
+  Mixing FromMean and FromVariance leads to unpredictable results
+*/
+void HistoErr::FromVariance(void)
+{
+ if(nx_<1) return;
+ mMean--;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   err2_(i) = ndata_(i)*(err2_(i) + data_(i)*data_(i));
+   data_(i) *= ndata_(i);
+ }
+ return;
+}
+
+/********* Methode *********/
+/*!
+ Fill the histogram with an other histogram
+*/
+void HistoErr::FillFrHErr(HistoErr& hfrom)
+{
+ if(nx_<=0) return;
+ if(hfrom.nx_<=0) return;
+
+ Zero();
+
+ for(int_4 i=0;i<hfrom.nx_;i++) {
+   r_8 x = hfrom.BinCenter(i);
+   int ii = FindBin(x);
+   if(ii<0 || ii>=nx_) continue;
+   data_(ii)  += hfrom.data_(ii);
+   err2_(ii)  += hfrom.err2_(ii);
+   ndata_(ii) += hfrom.ndata_(ii);
+ }
+ mMean = hfrom.mMean;
+
+}
+
+/********* Methode *********/
+/*!
+  Return the sum of bin value
+*/
+double HistoErr::Sum(void)
+{
+ double s = 0.;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   s += data_(i);
+ }
+ return s;
+}
+
+/********* Methode *********/
+/*!
+  Return the sum of the bin value squared
+*/
+double HistoErr::Sum2(void)
+{
+ double s = 0.;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   s += data_(i)*data_(i);
+ }
+ return s;
+}
+
+/********* Methode *********/
+/*!
+  Return the sum of the number of entries
+*/
+double HistoErr::SumN(void)
+{
+ double s = 0.;
+ for(int_4 i=0;i<nx_;i++) {
+   if(ndata_(i)<1.) continue;
+   s += ndata_(i);
+ }
+ return s;
+}
+
+/********* Methode *********/
+/*!
+  Operateur egal HistoErr = HistoErr
+*/
+HistoErr& HistoErr::operator = (const HistoErr& h)
+{
+  if(this==&h) return *this;
+  CreateOrResize(h.xmin_,h.xmax_,h.nx_);
+  data_  = h.data_;
+  err2_  = h.err2_;
+  ndata_ = h.ndata_;
+  mMean = h.mMean;
+  return *this;
+}
+
+/********* Methode *********/
+/*!
+  Operateur de multiplication par une constante
+*/
+HistoErr& HistoErr::operator *= (r_8 b)
+{
+r_8 b2 = b*b;
+for(int_4 i=0;i<nx_;i++) {
+  data_(i) *= b;
+  err2_(i) *= b2;
+}
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Print info
+*/
+void HistoErr::Show(ostream & os) const
+{
+  os <<"HistoErr(nmean="<<mMean<<")"
+     <<" nx="<<nx_<<" ["<<xmin_<<","<<xmax_<<"] dx="<<dx_<<endl;
+}
+
+/********* Methode *********/
+/*!
+  Write to an ASCII file
+*/
+int HistoErr::WriteASCII(string fname)
+{
+  FILE *file = fopen(fname.c_str(),"w");
+  if(file==NULL) {
+    cout<<"HistoErr::WriteASCII_Error: error opening "<<fname<<endl;
+    return -1;
+  }
+
+  if(NBins()<=0) {
+    cout<<"HistoErr::WriteASCII_Error: nbin= "<<NBins()<<endl;
+    return -2;
+  }
+
+  fprintf(file,"%ld %.17e %.17e %d\n",(long)NBins(),XMin(),XMax(),NMean());
+  for(long i=0;i<NBins();i++) {
+      fprintf(file,"%ld %.17e %.17e %.17e %.0f\n"
+             ,i,BinCenter(i),(*this)(i),Error2(i),NEntBin(i));
+  }
+
+  fclose(file);
+  return 0;
+}
+
+/*!
+  Read from an ASCII file
+*/
+#define __LENLINE_HistoErr_ReadASCII__ 2048
+int HistoErr::ReadASCII(string fname)
+{
+  FILE *file = fopen(fname.c_str(),"r");
+  if(file==NULL) {
+    cout<<"HistoErr::ReadASCII_Error: error opening "<<fname<<endl;
+    return -1;
+  }
+
+  char line[__LENLINE_HistoErr_ReadASCII__];
+  long n=0, nbin=0;
+
+  while ( fgets(line,__LENLINE_HistoErr_ReadASCII__,file) != NULL ) {
+
+    if(n==0) {
+
+      r_8 xmin,xmax; long mnmean=1;
+      sscanf(line,"%ld %lf %lf %ld",&nbin,&xmin,&xmax,&mnmean);
+      if(nbin<=0) {
+        cout<<"HistoErr::ReadASCII_Error: nbin= "<<nbin<<endl;
+        return -2;
+      }
+      CreateOrResize(xmin,xmax,nbin);
+      SetMean(mnmean);
+
+    } else {
+
+      long i; r_8 x,v,e2,nb;
+      sscanf(line,"%ld %lf %lf %lf %lf",&i,&x,&v,&e2,&nb);
+      SetBin(i,v);
+      SetErr2(i,e2);
+      SetNentB(i,nb);
+
+    }
+
+    n++;
+  }
+
+  fclose(file);
+  return 0;
+}
+
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<HistoErr>::ReadSelf(PInPersist& is)
+{
+string strg;
+
+if(dobj==NULL) dobj = new HistoErr;
+
+// Lecture entete
+is.GetStr(strg);
+
+// Nombre d'appels a ToMean/FromMean
+is.Get(dobj->mMean);
+
+// Lecture des parametres HistoErr
+is.Get(dobj->xmin_);
+is.Get(dobj->xmax_);
+is.Get(dobj->nx_);
+is.Get(dobj->dx_);
+
+// Lecture des donnees
+if(dobj->nx_>0) {
+  is >> dobj->data_;
+  is >> dobj->err2_;
+  is >> dobj->ndata_;
+}
+
+return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<HistoErr>::WriteSelf(POutPersist& os) const
+{
+if(dobj == NULL)   return;
+string strg;
+
+// Ecriture entete
+strg = "HistErr";
+os.PutStr(strg);
+
+// Nombre d'appels a ToMean/FromMean
+os.Put(dobj->mMean);
+
+// Ecriture des parametres HistoErr
+os.Put(dobj->xmin_);
+os.Put(dobj->xmax_);
+os.Put(dobj->nx_);
+os.Put(dobj->dx_);
+
+// Ecriture des donnees
+if(dobj->nx_>0) {
+  os << dobj->data_;
+  os << dobj->err2_;
+  os << dobj->ndata_;
+}
+
+return;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<HistoErr>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<HistoErr>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/histerr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histerr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histerr.h	(revision 3445)
@@ -0,0 +1,182 @@
+#ifndef HISTERR_SEEN
+#define HISTERR_SEEN
+
+#include "objfio.h"
+#include <iostream>
+#include <stdio.h>
+#include "tvector.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+
+//! 1 dimensions histograms with errors given by user
+class HistoErr : public AnyDataObj {
+  friend class ObjFileIO<HistoErr>;
+  friend class FitsHandler<HistoErr>;
+public:
+
+  //! Create or destroy
+  HistoErr(void);
+  HistoErr(r_8 xmin,r_8 xmax,int_4 nx);
+  HistoErr(const HistoErr& H);
+  virtual ~HistoErr(void);
+
+  //! Updating or Setting
+  void ReCenterBin(void);
+  void ReCenterBinW(void);
+  void Zero(void);
+
+  //! Getting Info
+  int_4 NBins(void) {return nx_;}
+  r_8 XMin(void) {return xmin_;}
+  r_8 XMax(void) {return xmax_;}
+  r_8 BinWidth(void) {return dx_;}
+
+  //! Retourne le contenu du bin
+  inline r_8 operator()(int_4 i) const
+    {
+    if(i<0 || i>=nx_) return 0.;
+    return data_(i);
+    }
+  inline r_8& operator()(int_4 i)
+    {
+    return data_(i);
+    }
+
+  //! Retourne le nombre l'erreur au carre dans le bin
+  inline r_8 Error2(int_4 i) const
+    {
+    if(i<0 || i>=nx_) return 0.;
+    return err2_(i);
+    }
+  inline r_8 Error(int_4 i) const
+    {
+    if(i<0 || i>=nx_) return 0.;
+    if(err2_(i)>0.) return sqrt(err2_(i)); else return 0.;
+    }
+
+  //! Retourne le nombre d'entree dans le bin
+  inline r_8 NEntBin(int_4 i) const
+    {
+    if(i<0 || i>=nx_) return 0.;
+    return ndata_(i);
+    }
+
+  //! Retourne l'abscisse et l'ordonnee du coin inferieur du bin i.
+  inline r_8 BinLowEdge(int_4 i) const {return xmin_ + i*dx_;}
+  //! Retourne l'abscisse et l'ordonnee du centre du bin i.
+  inline r_8 BinCenter(int_4 i) const  {return xmin_ + (i+0.5)*dx_;}
+  //! Retourne l'abscisse et l'ordonnee du coin superieur du bin i.
+  inline r_8 BinHighEdge(int_4 i) const {return xmin_ + (i+1)*dx_;}
+  //! Retourne les numeros du bin contenant l'abscisse et l'ordonnee x,y.
+  inline int_4 FindBin(r_8 x) const {return (int_4)floor((x-xmin_)/dx_);}
+
+  //! Addition du contenu de l'histo pour abscisse x poids w et l'erreur e
+  inline void Add(r_8 x, r_8 w, r_8 e)
+    {
+    int_4 i = FindBin(x);
+    if(i<0 || i>=nx_) return;
+    data_(i) += w; ndata_(i) += 1.; err2_(i) += e*e;
+    }
+  inline void Add(r_8 x, r_8 w) {Add(x,w,w);}
+
+  //! Addition du contenu de l'histo pour le bin i poids w et l'erreur e
+  inline void AddBin(int_4 i, r_8 w, r_8 e)
+    {
+    if(i<0 || i>=nx_) return;
+    data_(i) += w; ndata_(i) += 1.; err2_(i) += e*e;
+    }
+  inline void AddBin(int_4 i, r_8 w) {AddBin(i,w,w);}
+
+  //! remplissage contenu de l'histo pour le bin i poids w et l'erreur e
+  inline void SetBin(int_4 i, r_8 w, r_8 e, r_8 nb)
+    {
+    if(i<0 || i>=nx_) return;
+    data_(i)  = w;
+    err2_(i)  = e*e;
+    ndata_(i) = nb;
+    }
+  //! remplissage de la valeur pour le bin i
+  inline void SetBin(int_4 i, r_8 w)
+    {
+    if(i<0 || i>=nx_) return;
+    data_(i)  = w;
+    }
+  //! remplissage de l'erreur carree pour le bin i
+  void SetErr2(int_4 i, r_8 e2)
+    {
+    if(i<0 || i>=nx_) return;
+    err2_(i) = e2;
+    }
+  //! remplissage nombre d'entrees pour le bin i
+  void SetNentB(int_4 i, r_8 nb)
+    {
+    if(i<0 || i>=nx_) return;
+    ndata_(i) = nb;
+    }
+
+  //! Compute the mean histogram
+  void ToMean(void);
+  void FromMean(void);
+  int_4 NMean(void) {return mMean;}
+  void SetMean(int_4 nmean) {mMean = nmean;}
+
+  //! Replace the errors by the variance
+  void ToVariance(void);
+  void FromVariance(void);
+
+  //! Fill an histogram with an histogram
+  void FillFrHErr(HistoErr& hfrom);
+
+  //! Recuperation des matrices elementaires
+  void GetData(TVector<r_8>& data) {data = data_;}
+  void GetError2(TVector<r_8>& err2) {err2 = err2_;}
+  void GetNData(TVector<r_8>& ndata) {ndata = ndata_;}
+
+  //! Recuperation d'information
+  double Sum(void);
+  double Sum2(void);
+  double SumN(void);
+
+  // Operators
+  HistoErr& operator = (const HistoErr& h);
+  HistoErr& operator *= (r_8 b);
+
+  // Print
+  void Show(ostream& os) const;
+  void Show() const { Show(cout); }
+
+  // Write ASCII
+  int WriteASCII(string fname);
+  int ReadASCII(string fname);
+
+protected:
+  void CreateOrResize(r_8 xmin,r_8 xmax,int_4 nx);
+
+  r_4 xmin_,xmax_,dx_;
+  int_4 nx_;
+  TVector<r_8> data_;
+  TVector<r_8> err2_;
+  TVector<r_8> ndata_;
+  int_4 mMean;  //!< Nombre d'appels a ToMean/Variance(+1) ou FromMean/Variance(-1)
+};
+
+/*! Prints histogram information on stream \b s (h.Show(s)) */
+inline ostream& operator << (ostream& s, HistoErr const & h)
+  {  h.Show(s);  return(s);  }
+
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,HistoErr)
+  \brief Persistance management */
+inline POutPersist& operator << (POutPersist& os, HistoErr & obj)
+{ ObjFileIO<HistoErr> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,HistoErr)
+  \brief Persistance management */
+inline PInPersist& operator >> (PInPersist& is, HistoErr & obj)
+{ ObjFileIO<HistoErr> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif // HISTERR_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/histinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histinit.cc	(revision 3445)
@@ -0,0 +1,92 @@
+// Classe d'initialisation du module HiStats 
+//                        (Histogram and Statistics)
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "histinit.h"
+
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "histerr.h"
+#include "hist2err.h"
+#include "ntuple.h"
+#include "xntuple.h"
+#include "datatable.h"
+#include "swppfdtable.h"
+
+/*!
+   \defgroup HiStats HiStats module
+   This module contains histograms (1D, 2D) and 
+   classes for management of data sets as tables (NTuple, DataTable ...)
+*/
+ 
+int HiStatsInitiator::FgInit = 0;
+
+// Module version number - 2.0 , Jul 2006
+// Module version number - 2.1 , Jan 2007  (Nouvelle version de HistoErr + 2DErr)
+#define MOD_VERS   2.1 
+
+/*!
+  \class SOPHYA::HiStatsInitiator
+  \ingroup HiStats
+  This class performs the initialisation for HiStats module.
+  More specifically, it registers PPF handlers for the following classes :
+  - Histo
+  - HProf
+  - Histo2D
+  - HistoErr
+  - Histo2DErr
+  - NTuple
+  - XNTuple
+  - DataTable
+  - SwPPFDataTable
+
+  If the system linker/loader handles correctly static object initialisation, there
+  is no action required when writing programs. If not, an instance of the class must
+  be present before any other operation on the libray classes. 
+*/
+
+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<HistoErr>);
+  DObjRegister(ObjFileIO<HistoErr>, HistoErr);
+  PPRegister(ObjFileIO<Histo2DErr>);
+  DObjRegister(ObjFileIO<Histo2DErr>, Histo2DErr);
+
+  PPRegister(ObjFileIO<NTuple>);
+  DObjRegister(ObjFileIO<NTuple>, NTuple);
+  PPRegister(ObjFileIO<XNTuple>);
+  DObjRegister(ObjFileIO<XNTuple>, XNTuple);
+
+  PPRegister(ObjFileIO<BaseDataTable>);
+  DObjRegister(ObjFileIO<BaseDataTable>, DataTable);
+  DObjRegister(ObjFileIO<BaseDataTable>, SwPPFDataTable);
+
+  SophyaInitiator::RegisterModule("HiStats", MOD_VERS);  // Module name and version number registration
+
+}
+
+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_Nov2007/SophyaLib/HiStats/histinit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histinit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/HiStats/histos.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histos.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histos.cc	(revision 3445)
@@ -0,0 +1,1595 @@
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "histos.h"
+#include "perrors.h"
+#include "poly.h"
+#include "strutil.h"
+
+namespace SOPHYA {
+
+/*!
+  \class 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.)
+{
+}
+
+/********* 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(NULL), mErr2(NULL)
+{
+  CreateOrResize(xMin,xMax,nBin);
+}
+
+/********* 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(NULL), mErr2(NULL)
+{
+  CreateOrResize((r_8)xMin,(r_8)xMax,nBin);
+}
+
+/********* Methode *********/
+/*! Constructeur par copie */
+Histo::Histo(const Histo& H)
+: mData((H.mBins>0)? new r_8[H.mBins] : NULL),
+  mErr2((H.mBins>0 && H.mErr2!=NULL)? new r_8[H.mBins]: 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) return;
+  memcpy(mData,H.mData,mBins*sizeof(r_8));
+  if(H.mErr2) memcpy(mErr2, H.mErr2, mBins*sizeof(r_8));
+}
+
+/********* Methode *********/
+/*! Destructeur */
+Histo::~Histo()
+{
+  Delete();
+}
+
+/********* Methode *********/
+/*! Gestion de l'allocation */
+void Histo::CreateOrResize(r_8 xMin, r_8 xMax, int_4 nBin)
+{
+  //cout<<"Histo::CreateOrResize()"<<endl;
+  bool samelen = (nBin==mBins)? true: false;
+  if(mData!=NULL && !samelen) {delete[] mData; mData = NULL;}
+  if(mErr2!=NULL) {delete[] mErr2; mErr2 = NULL;} // On des-alloue toujours
+  if(nBin>0 && mData==NULL) mData = new r_8[nBin];
+  if(mData) memset(mData,0,nBin*sizeof(r_8));
+  mBins = nBin;
+  mMin = xMin; mMax = xMax;
+  binWidth = (nBin>0) ? (mMax-mMin)/nBin : 0.;
+  mUnder = mOver = nHist = 0.;
+  nEntries = 0;
+}
+
+/********* Methode *********/
+/*! Gestion de la des-allocation */
+void Histo::Delete()
+{
+ //cout<<"Histo::Delete()"<<endl;
+ if(mData != NULL) {delete[] mData; mData = NULL;}
+ if(mErr2 != NULL) {delete[] mErr2; mErr2 = NULL;}
+ mUnder = mOver = mMin = mMax = binWidth = nHist = 0.;
+ mBins = 0;
+ nEntries = 0;
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void Histo::Zero()
+{
+  if(mBins<=0 || mData==NULL) return;
+  memset(mData,0,mBins*sizeof(r_8));
+  if(mErr2) memset(mErr2,0, mBins*sizeof(r_8));
+  mUnder = mOver = nHist = 0;
+  nEntries = 0;
+}
+
+/********* Methode *********/
+/*!
+  Pour avoir le calcul des erreurs
+*/
+void Histo::Errors()
+{
+ if(mErr2 != NULL) {delete[] mErr2; mErr2 = NULL;}
+ if(mBins<=0) return;
+ mErr2 = new r_8[mBins];
+ memset(mErr2,0,mBins*sizeof(r_8));
+}
+
+/********* Methode *********/
+/*!
+ Recompute XMin and XMax so that
+ the CENTER of the first bin is exactly XMin and
+ the CENTER of the last bin is exactly XMax.
+ Remember that otherwise
+ XMin is the beginning of the first bin
+ and XMax is the end of the last bin
+*/
+void Histo::ReCenterBin(void)
+{
+ if(mBins<=1) return;
+ double dx = (mMax-mMin)/(mBins-1);
+ mMin -= dx/2.;
+ mMax += dx/2.;
+ binWidth = (mMax-mMin)/mBins;
+}
+
+/********* Methode *********/
+/*!
+  Operateur egal Histo = Histo
+*/
+Histo& Histo::operator = (const Histo& h)
+{
+  if(this == &h) return *this;
+  CreateOrResize(h.mMin,h.mMax,h.mBins);
+  if(h.mErr2) Errors();
+  if(mData) memcpy(mData,h.mData,mBins*sizeof(r_8));
+  if(mErr2) memcpy(mErr2,h.mErr2,mBins*sizeof(r_8));
+  mUnder = h.mUnder; mOver = h.mOver;
+  nHist = h.nHist; nEntries = h.nEntries;
+  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 ParmError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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
+{
+  if(mBins<=0)  return 0;
+  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
+{
+  if(mBins<=0)  return 0;
+  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
+{
+  if(mBins<=0)  return 0.;
+  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
+{
+  if(mBins<=0)  return 0.;
+  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 somme des valeurs des bins
+*/
+r_8 Histo::Sum() const
+{
+  if(mBins<=0)  return 0.;
+  r_8 sx = 0.;
+  for (int_4 i=0; i<mBins; i++) sx += mData[i];
+  return sx;
+}
+
+/********* Methode *********/
+/*!
+  Valeur somme des carres des valeurs des bins
+*/
+r_8 Histo::Sum2() const
+{
+  if(mBins<=0)  return 0.;
+  r_8 sx2 = 0.;
+  for (int_4 i=0; i<mBins; i++) sx2 += mData[i]*mData[i];
+  return sx2;
+}
+
+/********* Methode *********/
+/*!
+  Valeur moyenne
+*/
+r_8 Histo::Mean() const
+{
+  if(mBins<=0)  return 0.;
+  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
+{
+  if(mBins<=0)  return 0.;
+  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(mBins<=0)  return 0.;
+  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(mBins<=0)  return 0.;
+  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
+{
+  if(mBins<=0)  return 0.;
+  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
+{
+  if(mBins<=0)  return 0.;
+  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(mBins<=0)  return 0.;
+  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(mBins<=0)  return 0.;
+  if (!nHist) return 0;
+  r_8 s=0;
+  return CleanedMean(s);
+}
+
+/********* Methode *********/
+/*!
+  Retourne le nombre de bins non-nul
+*/
+int_4 Histo::BinNonNul() const
+{
+if(mBins<=0)  return -1;
+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
+{
+if(mBins<=0)  return -1;
+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
+{
+if(mBins<=0)  return -3;
+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
+{
+if(mBins<=0)  return -1;
+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(mBins<=0)  return mMin;
+  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 ParmError(PExcLongMessage(""));
+
+  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 ParmError(PExcLongMessage(""));
+  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 ParmError(PExcLongMessage(""));
+    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 ParmError(PExcLongMessage(""));
+    pol.Derivate();
+    fd = (pol(r1)<0) ? r1 + xCenter : r2 + xCenter;
+  } else {
+    // on est dans un cas non prevu
+    throw ParmError(PExcLongMessage(""));
+  }
+
+  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
+{
+  if(mBins<=0)  return 0;
+  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(mBins<=0)  return 0;
+  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 ParmError(PExcLongMessage(""));
+  if (NBins() < 3) throw ParmError(PExcLongMessage(""));
+
+  int_4 iMax = FindBin(xmax);
+  if (iMax<0 || iMax>=NBins()) throw ParmError(PExcLongMessage(""));
+  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
+{
+if(mBins<=0)  return -1;
+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
+{
+if(mBins<=0) {frac=0.; return;}
+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(mBins<=0) return;
+ 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 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<Histo>::ReadSelf(PInPersist& is)
+{
+char strg[256];
+
+if(dobj==NULL) dobj=new Histo;
+  else         dobj->Delete();
+
+// Lecture entete
+is.GetLine(strg, 255);
+bool nentries_en_8_bytes=false;
+if(strg[0]=='V' && strg[1]=='_' && strg[2]=='2') nentries_en_8_bytes=true;
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+
+// Lecture des valeurs
+is.Get(dobj->mBins);
+if(nentries_en_8_bytes) is.Get(dobj->nEntries);
+ else {int_4 dum; is.Get(dum); dobj->nEntries=(uint_8)dum;}
+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
+is.GetLine(strg, 255);
+if(dobj->mBins>0) dobj->mData = new r_8[dobj->mBins];
+is.Get(dobj->mData, dobj->mBins);
+
+// Lecture des erreurs
+if(errok) {
+  is.GetLine(strg, 255);
+  if(dobj->mBins>0) dobj->mErr2 = new r_8[dobj->mBins];
+  is.Get(dobj->mErr2, dobj->mBins);
+}
+
+return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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,"V_2 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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/histos.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histos.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histos.h	(revision 3445)
@@ -0,0 +1,288 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: histos.h,v 1.26 2006-11-20 13:15:35 cmv Exp $
+//
+
+#ifndef HISTOS_SEEN
+#define HISTOS_SEEN
+
+#include "objfio.h"
+#include <iostream>
+#include <stdio.h>
+#include "peida.h"
+#include "tvector.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+//! 1 dimension histograms
+class Histo : public AnyDataObj {
+  friend class ObjFileIO<Histo>;
+  friend class FitsHandler<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();
+  void ReCenterBin();
+
+  // UPDATING or SETTING
+  void Zero();
+  void Add(r_8 x, r_8 w);
+  inline void Add(r_8 x) {Add(x,1.);}
+  void AddBin(int_4 numBin, r_8 w);
+  inline void AddBin(int_4 numBin) {AddBin(numBin,1.);}
+  void SetBin(r_8 x, r_8 w);
+  inline void SetBin(r_8 x) {SetBin(x,1.);}
+  void SetBin(int_4 numBin, r_8 w);
+  inline void SetBin(int_4 numBin) {SetBin(numBin,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 uint_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       Sum() const;
+  r_8       Sum2() 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 CreateOrResize(r_8 xMin, r_8 xMax, int_4 nBin);
+  void Delete(); // Ne pas passer en "virtual"
+
+  r_8*   mData;    //!< donnees
+  r_8*   mErr2;	   //!< erreurs carrees
+  r_8    mUnder;   //!< underflow
+  r_8    mOver;    //!< overflow
+  r_8    nHist;    //!< somme ponderee des entrees
+  uint_8 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); is.SkipToNextObject(); 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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+Histo c(a);
+return (c /= b);
+}
+
+} // Fin du namespace
+
+#endif // HISTOS_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/histos2.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histos2.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histos2.cc	(revision 3445)
@@ -0,0 +1,1726 @@
+#include "machdefs.h"
+#include <string.h>
+#include <new>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef NO_VALUES_H
+#include <values.h>
+#endif
+
+#include "histos2.h"
+
+namespace SOPHYA {
+
+/*!
+  \class 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
+*/
+
+///////////////////////////////////////////////////////////////////
+
+/*!
+  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;
+}
+
+/*!
+  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(NULL), mErr2(NULL), mHprojx(NULL), mHprojy(NULL)
+{
+  CreateOrResize(xMin,xMax,nxBin,yMin,yMax,nyBin);
+}
+
+/*!
+  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(NULL), mErr2(NULL), mHprojx(NULL), mHprojy(NULL)
+{
+  CreateOrResize((r_8)xMin,(r_8)xMax,nxBin,(r_8)yMin,(r_8)yMax,nyBin);
+}
+
+/*!
+  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));
+}
+
+}
+
+/*!
+  Destructeur.
+*/
+Histo2D::~Histo2D()
+{
+  Delete();
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  allocation de la place de l'histogramme (fct privee).
+*/
+void Histo2D::CreateOrResize(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin)
+{
+  int_8 n = nxBin*nyBin;
+  bool samelen = (n==mNx*mNy)? true: false;
+  if(mData!=NULL && !samelen) {delete[] mData; mData=NULL;}
+  if(mErr2!=NULL) {delete[] mErr2; mErr2=NULL;} // On des-alloue toujours
+  if(n>0 && mData==NULL) mData = new r_8[n];
+  if(mData) memset(mData, 0, n*sizeof(r_8));
+  mNx = nxBin; mNy = nyBin; mNxy = nxBin*nyBin;
+  mXmin = xMin; mXmax = xMax; mYmin = yMin; mYmax = yMax;
+  mWBinx = (nxBin>0) ? (xMax - xMin)/nxBin: 0.;
+  mWBiny = (nyBin>0) ? (yMax - yMin)/nyBin: 0.;
+  nHist = 0; nEntries = 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;
+
+  DelProjX(); DelProjY();
+  DelBandX(); DelBandY();
+  DelSliX(); DelSliY();
+}
+
+/*!
+  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;  // Ne pas faire de 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(mErr2!=NULL) {delete[] mErr2; mErr2 = NULL;}
+ if(mNxy <= 0) return;
+ mErr2 = new r_8[mNxy];
+ memset(mErr2,0,mNxy*sizeof(r_8));
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+ Recompute XMin (YMin) and XMax (YMax) so that
+ the CENTER of the first bin is exactly XMin (YMin) and
+ the CENTER of the last bin is exactly XMax (YMax).
+ Remember that otherwise
+ XMin (YMin) is the beginning of the first bin
+ and XMax (YMax) is the end of the last bin
+*/
+void Histo2D::ReCenterBinX(void)
+{
+ if(mNx<=1) return;
+ double dx = (mXmax-mXmin)/(mNx-1);
+ mXmin -= dx/2.;
+ mXmax += dx/2.;
+ mWBinx = (mXmax-mXmin)/mNx;
+}
+
+void Histo2D::ReCenterBinY(void)
+{
+ if(mNy<=1) return;
+ double dy = (mYmax-mYmin)/(mNy-1);
+ mYmin -= dy/2.;
+ mYmax += dy/2.;
+ mWBiny = (mYmax-mYmin)/mNy;
+}
+
+void Histo2D::ReCenterBin(void)
+{
+ ReCenterBinX();
+ ReCenterBinY();
+}
+
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Operateur H2 = H1
+*/
+Histo2D& Histo2D::operator = (const Histo2D& h)
+{
+  if(this == &h) return *this;
+  CreateOrResize(h.mXmin,h.mXmax,h.mNx,h.mYmin,h.mYmax,h.mNy);
+  if(h.mErr2) Errors();
+  if(mData) memcpy(mData, h.mData, mNxy*sizeof(r_8));
+  if(mErr2) memcpy(mErr2, h.mErr2, mNxy*sizeof(r_8));
+
+  for(int i=0;i<3;i++) for(int j=0;j<3;j++) mOver[i][j] = h.mOver[i][j];
+  nHist = h.nHist;  nEntries = h.nEntries;  
+
+  if(h.mHprojx) {SetProjX(); *mHprojx = *(h.mHprojx);}
+  if(h.mHprojy) {SetProjY(); *mHprojy = *(h.mHprojy);}
+
+  int_4 nb;
+  nb = h.NSliX();
+  if(nb>0) {
+    SetSliX(nb);
+    for(int i=0; i<NSliX();i++) *HSliX(i) = *(h.HSliX(i));
+  }
+  nb = h.NSliY();
+  if(nb>0) {
+    SetSliY(nb);
+    for(int i=0; i<NSliY();i++) *HSliY(i) = *(h.HSliY(i));
+  }
+
+  nb = h.NBandX();
+  if(nb>0) {
+    for(int i=0; i<nb;i++) {
+      r_8 min,max;
+      h.GetBandX(i,min,max);
+      SetBandX(min,max);
+      *HBandX(i) = *(h.HBandX(i));
+    }
+    for(int i=0; i<NBandX();i++) *HBandX(i) = *(h.HBandX(i));
+  }
+  nb = h.NBandY();
+  if(nb>0) {
+    for(int i=0; i<nb;i++) {
+      r_8 min,max;
+      h.GetBandY(i,min,max);
+      SetBandY(min,max);
+      *HBandY(i) = *(h.HBandY(i));
+    }
+    for(int 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 ParmError("Histo2D::operator / (0) ");
+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 SzMismatchError("Histo2D::operator += ");
+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 SzMismatchError("Histo2D::operator -= ");
+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 SzMismatchError("Histo2D::operator *= ");
+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 SzMismatchError("Histo2D::operator /= ");
+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 SzMismatchError("Histo2D::PutValue()");
+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 SzMismatchError("Histo2D::PutValueAdd ");
+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 SzMismatchError("Histo2D::PutError2 ");
+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 SzMismatchError("Histo2D::PutError2Add ");
+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 SzMismatchError("Histo2D::PutError ");
+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(mNxy<=0) {imax = jmax = -1; return;}
+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(mNxy<=0) {imax = jmax = -1; return;}
+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(mNxy<=0) return 0.;
+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(mNxy<=0) return 0.;
+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
+{
+if(mNxy<=0) return -1;
+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(mNxy<=0) return -1;
+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
+{
+if(mNxy<=0) return;
+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 && mHprojx) mHprojx->Errors();
+}
+
+/*!
+  Pour creer la projection Y.
+*/
+void Histo2D::SetProjY()
+{
+if( mHprojy != NULL ) DelProjY();
+mHprojy = new Histo(mYmin,mYmax,mNy);
+if(mErr2 && mHprojy) 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);
+if(mErr2 && mB_s.H) mB_s.H->Errors();
+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);
+if(mErr2 && mB_s.H) mB_s.H->Errors();
+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);
+  if(mErr2 && mB_s.H) mB_s.H->Errors();
+  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);
+  if(mErr2 && mB_s.H) mB_s.H->Errors();
+  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;
+}
+
+/*!
+  Retourne les limites de la bande equidistante numero `n' selon X.
+*/
+void Histo2D::GetSliX(int_4 n,r_8& ybmin,r_8& ybmax) const
+{
+ybmin = 0.; ybmax = 0.;
+if( mLSlix.size() <= 0 || n < 0 || n >= (int_4) mLSlix.size() ) return;
+for(list<bande_slice>::const_iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
+  if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
+return;
+}
+
+/*!
+  Retourne les limites de la bande equidistante numero `n' selon Y.
+*/
+void Histo2D::GetSliY(int_4 n,r_8& xbmin,r_8& xbmax) const
+{
+xbmin = 0.; xbmax = 0.;
+if( mLSliy.size() <= 0 || n < 0 || n >= (int_4) mLSliy.size() ) return;
+for(list<bande_slice>::const_iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
+  if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
+return;
+}
+
+/*!
+  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 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/histos2.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/histos2.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/histos2.h	(revision 3445)
@@ -0,0 +1,367 @@
+//
+// 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 {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+//! 2 dimensions histograms
+class Histo2D : public AnyDataObj {
+  friend class ObjFileIO<Histo2D>;
+  friend class FitsHandler<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();
+  void ReCenterBinX(void);
+  void ReCenterBinY(void);
+  void ReCenterBin(void);
+
+  // 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 Show() const { Show(cout); }
+  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 GetSliX(int_4 n,r_8& ybmin,r_8& ybmax) const;
+  void GetSliY(int_4 n,r_8& xbmin,r_8& xbmax) 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 CreateOrResize(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin);
+  void Delete(void);
+
+  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); is.SkipToNextObject(); 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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+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 SzMismatchError(PExcLongMessage(""));
+Histo2D c(a);
+return (c /= b);
+}
+
+} // Fin du namespace
+
+#endif // HISTOS2_SEEN
Index: /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.cc	(revision 3445)
@@ -0,0 +1,191 @@
+
+#include "sopnamsp.h"
+#include "ntupintf.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.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-- */
+sa_size_t NTupleInterface::NbLines() const
+{
+return(0);
+}
+
+//! Retuns the number of columns of the data set 
+/* --Methode-- */
+sa_size_t 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(sa_size_t ) const
+{
+  throw NotAvailableOperation("NTupleInterface::GetLineD(sa_size_t ) must be redefined in derived classes");
+}
+
+//! 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(sa_size_t , sa_size_t ) 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(sa_size_t 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(sa_size_t n, sa_size_t 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(sa_size_t n, string const & nom) const
+{
+return(GetCelltoString(n, ColumnIndex(nom)));
+}
+
+//! Returns the minimum and maximum values for a given column
+/* --Methode-- */
+void NTupleInterface::GetMinMax(sa_size_t , 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 & nom, double& min, double& max)   const
+{
+  GetMinMax(ColumnIndex(nom), min, max);
+}
+
+/* --Methode-- */
+//! Returns the column index given the column name
+sa_size_t NTupleInterface::ColumnIndex(string const & nom)  const
+{
+return(-1);
+}
+
+/* --Methode-- */
+//! Returns the column name corresponding to a column index.
+string NTupleInterface::ColumnName(sa_size_t k) const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::VarList_C(const char*) const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::LineHeaderToString() const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::LineToString(sa_size_t ) const
+{
+return("");
+}
+
+
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/ntupintf.h	(revision 3445)
@@ -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 sa_size_t     NbLines() const ;
+// Nombre de colonnes (nb de variables)
+  virtual sa_size_t     NbColumns() const ;
+// La ligne numero n, sous forme d'un tableau de double
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+// Cellule de la ligne n, colonne k
+  virtual r_8		GetCell(sa_size_t n, sa_size_t k) const ;
+// Cellule de la ligne n, colonne nom
+  virtual r_8		GetCell(sa_size_t n, string const & nom) const ;
+// Cellule de la ligne n, colonne k, converti en chaine de caracteres
+  virtual string	GetCelltoString(sa_size_t n, sa_size_t k) const ;
+// Cellule de la ligne n, colonne nom, converti en chaine de caracteres
+  virtual string	GetCelltoString(sa_size_t n, string const & nom) const ;
+// Min et Max pour la colonne k
+  virtual void		GetMinMax(sa_size_t 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 sa_size_t     ColumnIndex(string const & nom)  const ;
+// Nom de colonne numero k
+  virtual string        ColumnName(sa_size_t 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(sa_size_t n) const;  
+};
+
+} // namespace SOPHYA
+
+#endif   /*  NTUPLEINTERFACE_H_SEEN  */
+
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/ntuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/ntuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/ntuple.cc	(revision 3445)
@@ -0,0 +1,869 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "strutil.h"
+#include "perrors.h"
+#include "ntuple.h"
+#include "thsafeop.h"
+
+namespace SOPHYA {
+
+#define LENNAME 8
+#define LENNAME1  (LENNAME+1)
+#define BADVAL -1.e19
+
+/*!
+   \class NTuple
+   \ingroup HiStats
+   Simple NTuple class (a Table or 2-D data set) with double or 
+   single precision floating point value columns. 
+   \warning 
+   Thread safe fill operation can be activated using the method SetThreadSafe()
+   Default mode is NON thread-safe fill.
+   \sa SOPHYA::ObjFileIO<NTuple>
+
+   \code
+   #include "ntuple.h"
+   // ...
+   char * names[3] = {"XPos", "YPos", "Val"};
+   // NTuple (Table) creation with 3 columns (double precision)
+   NTuple  nt(3, names);
+   // Filling the NTuple
+   r_8 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 - To be used when reading in an NTuple.
+//++
+NTuple::NTuple()
+//
+//	Createur par defaut
+//--
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mFgDouble = true;
+mInfo = NULL;
+mThS = 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
+  \param fgdouble : if \b true: internal data kept as double precision values (r_8),
+  simple precision (r_4) otherwise
+ */
+//++
+NTuple::NTuple(int nvar, char** noms, int blk, bool fgdouble)
+//
+//	Createur d'un ntuple de `nvar' variables dont les
+//	noms sont dans le tableau de chaines de caracteres `noms'
+//	avec `blk' d'evenements par blocks.
+//--
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mInfo = NULL;
+mThS = NULL; 
+if (nvar <= 0)  throw ParmError("NTuple::NTuple(nvar<=0) "); 
+mNVar = nvar;
+mVar = new r_4[nvar];
+mVarD = new r_8[nvar];
+if (blk < 10) blk = 10;
+mBlk = blk;
+
+if (fgdouble) {
+  r_8* pt = new r_8[nvar*blk];
+  mNBlk = 1;
+  mPtrD.push_back(pt);
+  mFgDouble = true;
+}
+else { 
+  r_4* pt = new r_4[nvar*blk];
+  mNBlk = 1;
+  mPtr.push_back(pt);
+  mFgDouble = false;
+}
+for(int i=0; i<nvar; i++) mNames.push_back(noms[i]);
+return;
+}
+
+//! Constructor with specification of number of columns and column name
+/*!
+  \param noms : Array of column names (length(name) < 8 characters) 
+  \param blk : Optional argument specifying number of table lines
+  in a given data block
+  \param fgdouble : if \b true: internal data kept as double precision values (r_8),
+  simple precision (r_4) otherwise
+ */
+NTuple::NTuple(vector<string>& noms, int blk, bool fgdouble)
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mInfo = NULL;
+mThS = NULL; 
+int nvar = noms.size();
+if (nvar <= 0)  throw ParmError("NTuple::NTuple(nvar<=0) "); 
+mNVar = nvar;
+mVar = new r_4[nvar];
+mVarD = new r_8[nvar];
+if (blk < 10) blk = 10;
+mBlk = blk;
+
+if (fgdouble) {
+  r_8* pt = new r_8[nvar*blk];
+  mNBlk = 1;
+  mPtrD.push_back(pt);
+  mFgDouble = true;
+}
+else { 
+  r_4* pt = new r_4[nvar*blk];
+  mNBlk = 1;
+  mPtr.push_back(pt);
+  mFgDouble = false;
+}
+for(int i=0; i<nvar; i++) mNames.push_back(noms[i]);
+return;
+}
+
+/*! 
+  Copy constructor - Copies the table definition and associated data, 
+  as well as the tread safety state
+*/
+//                                       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), mInfo(NULL),mThS(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 = NT.mNames;
+
+int i;
+mFgDouble = NT.mFgDouble;
+if (mFgDouble) {
+  r_8* pt = new r_8[mNVar*mBlk];
+  mNBlk = 1; mPtrD.push_back(pt);
+  if(NT.mNEnt > 0)
+    for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVecD(i,NULL); Fill(pt);}
+}
+else {
+  r_4* pt = new r_4[mNVar*mBlk];
+  mNBlk = 1; mPtr.push_back(pt);
+  for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVec(i,NULL); Fill(pt);}
+}
+
+mNames = NT.mNames;
+
+if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
+mThS = NULL; 
+if(NT.mThS!=NULL) SetThreadSafe(true);
+return;
+}
+
+
+/* --Methode-- */
+NTuple::~NTuple()
+{
+Clean();
+}
+/* --Methode-- */ 
+/*!
+  \brief Activate or deactivate thread-safe \b Fill() operations
+  If fg==true, create an ThSafeOp object in order to insure atomic Fill()
+  operations. if fg==false, the ThSafeOp object (mThS) of the target NTuple
+  is destroyed. 
+  \warning The default Fill() operation mode for NTuples is NOT thread-safe. 
+  Please note also that the thread-safety state is NOt saved to PPF (or FITS) streams.
+*/
+void NTuple::SetThreadSafe(bool fg) 
+{
+if (fg) {
+  if (mThS) return;
+  else mThS = new ThSafeOp();
+}
+else {
+  if (mThS) delete mThS;
+  mThS = NULL;
+}
+}
+
+/* --Methode-- */
+//! Clear the data table definition and deletes the associated data
+void NTuple::Clean()
+{
+if (mVar) delete[] mVar;
+if (mVarD) delete[] mVarD;
+if (mInfo) delete mInfo;
+if (mThS) delete mThS;
+int i;
+if(mNBlk>0) { 
+  if (mFgDouble) for(i=0; i<mNBlk; i++)  delete[] mPtrD[i];
+  else for(i=0; i<mNBlk; i++)  delete[] mPtr[i];
+}
+if (mFgDouble) mPtrD.erase(mPtrD.begin(), mPtrD.end());
+else mPtr.erase(mPtr.begin(), mPtr.end());
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mInfo = NULL;
+mThS = 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 = NT.mNames;
+
+int i;
+mFgDouble = NT.mFgDouble; 
+if (mFgDouble) {
+  r_8* pt = new r_8[mNVar*mBlk];
+  mNBlk = 1; mPtrD.push_back(pt);
+  if(NT.mNEnt > 0)
+    for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVecD(i,NULL); Fill(pt);}
+}
+else {
+  r_4* pt = new r_4[mNVar*mBlk];
+  mNBlk = 1; mPtr.push_back(pt);
+  for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVec(i,NULL); Fill(pt);}
+}
+
+if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
+
+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'.
+//--
+{
+if (mThS)  mThS->lock();   // Thread-safe operation 
+int numb = mNEnt/mBlk;
+if (numb >= mNBlk) {
+  if (mFgDouble) {
+    r_8* pt = new r_8[mNVar*mBlk];
+    mNBlk++;
+    mPtrD.push_back(pt);
+  }
+  else {
+    r_4* pt = new r_4[mNVar*mBlk];
+    mNBlk++;
+    mPtr.push_back(pt);
+  }
+}
+
+int offb = mNEnt-numb*mBlk;
+if (mFgDouble) 
+  for(int i=0; i<mNVar; i++) (mPtrD[numb]+offb*mNVar)[i] = x[i];
+else memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4));
+mNEnt++;
+if (mThS)  mThS->unlock();   // Thread-safe operation 
+return;
+}
+
+/* --Methode-- */
+//! Adds an entry (a line) to the table (double precision)
+/*!
+  \param x : content of the line to be appended to the table
+ */
+//++
+void  NTuple::Fill(r_8* x)
+//
+//	Remplit le ntuple avec le tableau double precision `x'.
+//--
+{
+if (mThS)  mThS->lock();   // Thread-safe operation 
+int numb = mNEnt/mBlk;
+if (numb >= mNBlk) {
+  if (mFgDouble) {
+    r_8* pt = new r_8[mNVar*mBlk];
+    mNBlk++;
+    mPtrD.push_back(pt);
+  }
+  else {
+    r_4* pt = new r_4[mNVar*mBlk];
+    mNBlk++;
+    mPtr.push_back(pt);
+  }
+}
+
+int offb = mNEnt-numb*mBlk;
+if (mFgDouble) 
+  memcpy((mPtrD[numb]+offb*mNVar), x, mNVar*sizeof(r_8));
+else
+  for(int i=0; i<mNVar; i++) (mPtr[numb]+offb*mNVar)[i] = x[i];
+
+mNEnt++;
+if (mThS)  mThS->unlock();   // Thread-safe operation 
+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;
+if ( mFgDouble) return(*(mPtrD[numb]+offb*mNVar+k));
+else 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;
+string snom = nom;
+for(i=0; i<mNVar; i++)  
+  if ( mNames[i] == snom)  return(i);
+return(-1);
+}
+
+
+static char nomretour[256];
+/* --Methode-- */
+//++
+char* NTuple::NomIndex(int k)  const
+//
+//	Retourne le nom de la variable numero 'k'
+//--
+{
+nomretour[0] = '\0';
+if ((k >= 0) && (k < mNVar))  strncpy(nomretour, mNames[k].c_str(), 255);
+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;
+if (mFgDouble) for(i=0; i<mNVar; i++) ret[i] = (mPtrD[numb]+offb*mNVar)[i];
+else  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;
+if (n >= mNEnt) {
+  for(i=0; i<mNVar; i++)   ret[i] = BADVAL;
+  return(ret);
+}
+  
+int numb = n/mBlk;
+int offb = n-numb*mBlk;
+if (mFgDouble) memcpy(ret, (mPtrD[numb]+offb*mNVar), mNVar*sizeof(r_8));
+else for(i=0; i<mNVar; i++) ret[i] = (mPtr[numb]+offb*mNVar)[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].c_str());
+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.
+//--
+{
+char * tt = "float"; 
+if (mFgDouble) tt = "double";
+os << "NTuple T=" << tt << " : 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].c_str(), 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;
+double* xv = new double[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-- */
+sa_size_t NTuple::NbLines() const
+{
+return(NEntry());
+}
+/* --Methode-- */
+sa_size_t NTuple::NbColumns() const
+{
+return(NVar());
+}
+
+/* --Methode-- */
+r_8 * NTuple::GetLineD(sa_size_t n) const
+{
+return(GetVecD(n));
+}
+
+/* --Methode-- */
+r_8 NTuple::GetCell(sa_size_t n, sa_size_t k) const
+{
+return(GetVal(n, k));
+}
+
+/* --Methode-- */
+r_8 NTuple::GetCell(sa_size_t n, string const & nom) const
+{
+return(GetVal(n, nom.c_str()));
+}
+
+/* --Methode-- */
+//++
+void  NTuple::GetMinMax(sa_size_t 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 = (mFgDouble) ? *(mPtrD[jb]+ib*mNVar+k) : *(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-- */
+sa_size_t NTuple::ColumnIndex(string const & nom)  const
+{
+return(IndexNom(nom.c_str()));
+}
+
+/* --Methode-- */
+string NTuple::ColumnName(sa_size_t 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];
+  }
+rets += "; \n";
+if (nomx) { 
+  char buff[256];
+  for(i=0; i<mNVar; i++) {
+    sprintf(buff,"%s=%s[%d]; ",  mNames[i].c_str(), 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].c_str());
+  rets += buff;
+  }
+rets += '\n';
+return(rets);
+}
+
+/* --Methode-- */
+//++
+string NTuple::LineToString(sa_size_t 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 ObjFileIO<NTuple>
+   \ingroup HiStats
+   Persistence (serialisation) handler for class NTuple
+*/
+
+/* --Methode-- */ 
+//++
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void   ObjFileIO<NTuple>::WriteSelf(POutPersist& s)  const
+//
+//	Ecriture ppersist du ntuple.
+//--
+{
+if (dobj == NULL)   return;
+
+// On ecrit cette chaine pour compatibilite avec les anciennes version (1,2) 
+string strg = "NTuple";
+s.Put(strg);
+
+//  On ecrit 3 uint_4 .... 
+//  [0]: Numero de version ;
+//  [1] : bit1 non nul -> has info, bit 2 non nul mFgDouble=true 
+//  [2] : reserve
+uint_4 itab[3];
+itab[0] = 3;  // Numero de version a 3
+itab[1] = itab[2] = 0;
+if (dobj->mInfo)  itab[1] = 1;
+if (dobj->mFgDouble) itab[1] += 2;
+s.Put(itab, 3);
+
+s.Put(dobj->mNVar);
+for(int k=0; k<dobj->mNVar; k++) s.Put(dobj->mNames[k]);
+s.Put(dobj->mNEnt);
+s.Put(dobj->mBlk);
+s.Put(dobj->mNBlk);
+
+if (dobj->mInfo)  s << (*(dobj->mInfo));
+int jb;
+if (dobj->mFgDouble) 
+  for(jb=0; jb<dobj->mNBlk; jb++)
+    s.Put(dobj->mPtrD[jb], dobj->mNVar*dobj->mBlk); 
+else 
+  for(jb=0; jb<dobj->mNBlk; jb++)
+    s.Put(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk); 
+return;
+}
+
+/* --Methode-- */
+//++
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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);
+uint_4 itab[3] = {0,0,0};
+if (strg == "NTuple") {
+  s.Get(itab, 3);
+  if ( ((itab[0] < 3) && (itab[1] != 0)) || 
+       ((itab[0] >= 3) && ((itab[1]&1) == 1)) ) 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;
+}
+if (itab[0] < 3) {  // Lecture version anterieures V= 1 , 2 
+  s.Get(dobj->mNVar);
+  dobj->mVar = new r_4[dobj->mNVar];
+  dobj->mVarD = new r_8[dobj->mNVar];
+  
+  char * names = new char[dobj->mNVar*LENNAME1];
+  s.GetBytes(names, dobj->mNVar*LENNAME1);
+  for(int k=0; k<dobj->mNVar; k++) dobj->mNames.push_back(names+k*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));
+  }
+  // Il n'y avait que des NTuple avec data float pour V < 3
+  dobj->mFgDouble = false;   
+  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); 
+  }
+}
+else {  // Lecture version V 3 
+  s.Get(dobj->mNVar);
+  dobj->mVar = new r_4[dobj->mNVar];
+  dobj->mVarD = new r_8[dobj->mNVar];
+  string nom;
+  for(int k=0; k<dobj->mNVar; k++) { 
+    s.Get(nom);
+    dobj->mNames.push_back(nom);
+  }
+  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));
+  }
+  // Il n'y avait que des NTuple avec data float pour V < 3
+  dobj->mFgDouble =  ((itab[1]&2) == 2) ? true : false;   
+  int jb; 
+  if (dobj->mFgDouble) {
+    for(jb=0; jb<dobj->mNBlk; jb++) {
+      r_8* pt = new r_8[dobj->mNVar*dobj->mBlk];
+      dobj->mPtrD.push_back(pt);
+      s.Get(dobj->mPtrD[jb], dobj->mNVar*dobj->mBlk); 
+    }
+  }
+  else {
+    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); 
+    }
+  }
+}  // Fin lecture V3 
+
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<NTuple>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<NTuple>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/ntuple.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/ntuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/ntuple.h	(revision 3445)
@@ -0,0 +1,132 @@
+// 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>
+#include <string>
+#include <vector>
+
+#include "ntupintf.h"
+#include "ppersist.h"
+#include "dvlist.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+class FITS_NTuple;
+//  Forward class declaration for Thread-safe operations
+class ThSafeOp;
+
+//! Class for creation and management of double or float data sets in a table
+class NTuple : public AnyDataObj , public NTupleInterface {
+
+public:
+  NTuple();
+  NTuple(int nvar, char** noms, int blk=512, bool fgdouble=true);
+  NTuple(vector<string>& noms, int blk=512, bool fgdouble=true);
+  NTuple(const NTuple& NT);
+  virtual ~NTuple();
+
+  // Activate/deactivate thread-safe Fill operation
+  void SetThreadSafe(bool fg=true);
+  //! Return true if Fill  operations are thread-safe
+  inline bool IsThreadSafe() const { return ((mThS)?true:false); }
+
+  NTuple& operator = (const NTuple& NT);
+ 
+  void              Fill(r_4* x);
+  void              Fill(r_8* x);
+  //! Return the number of lines (rows) in the table)
+  inline int_4      NEntry() const  { return(mNEnt); }
+  //! Return the number of columns in the tables (number of cells in a row)  
+  inline int_4      NVar() const { return(mNVar); }  
+  //! Return the bloc size 
+  inline int_4      BLock() const { return(mBlk); }  
+// $CHECK$ Reza 21/10/99 Pourquoi faire BLock() ?
+
+  //! Return the content of the cell for line (row) \b n , column \b k
+  float             GetVal(int n, int k)   const;
+  //! Return the content of the cell for line (row) \b and column name \b nom
+  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;
+  //! Return the content of line \b n as a vector of r_4 (float)
+  r_4*	            GetVec(int n, r_4* ret=NULL)  const ;
+  //! Return the content of line \b n as a vector of r_8 (double)
+  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); }
+
+  //! Return the associated DVList object 
+  DVList&           Info();
+
+// Remplissage depuis fichier ASCII 
+  int		    FillFromASCIIFile(string const& fn, float defval=0.);
+
+
+// Declaration de l interface NTuple
+  virtual sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual r_8		GetCell(sa_size_t n, sa_size_t k) const ;
+  virtual r_8		GetCell(sa_size_t n, string const & nom) const ;
+  virtual void		GetMinMax(sa_size_t k, double& min, double& max)   const ; 
+  virtual void		GetMinMax(string const & nom, double& min, double& max)   const ; 
+  virtual sa_size_t     ColumnIndex(string const & nom)  const ;
+  virtual string        ColumnName(sa_size_t k) const;
+  virtual string	VarList_C(const char* nomx=NULL) const ;
+  virtual string        LineHeaderToString() const;
+  virtual string        LineToString(sa_size_t 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;
+  vector<string> mNames;
+
+  bool mFgDouble;      // true -> les donnees sont gardees en double
+  vector<r_4*> mPtr;    // Pointeur de tableau float
+  vector<r_8*> mPtrD;   // Pointeur de tableau double
+
+  DVList* mInfo;        // Infos (variables) attachees au NTuple
+  
+  ThSafeOp* mThS;       // != NULL -> Thread safe operations
+};
+
+/*! 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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<NTuple>
+
+
+} // namespace SOPHYA
+
+#endif
+  
Index: /tags/V_Nov2007/SophyaLib/HiStats/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/objlist.list	(revision 3445)
@@ -0,0 +1,14 @@
+basedtable.o
+datatable.o
+fio_dtable.o
+hisprof.o
+hist2err.o
+histerr.o
+histinit.o
+histos2.o
+histos.o
+ntupintf.o
+ntuple.o
+proxtuple.o
+swppfdtable.o
+xntuple.o
Index: /tags/V_Nov2007/SophyaLib/HiStats/proxtuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/proxtuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/proxtuple.cc	(revision 3445)
@@ -0,0 +1,55 @@
+//--------------------------------------------------------------------------
+//
+// Description:
+// 	class ProxTuple : see header file for description.
+//
+//------------------------------------------------------------------------
+//-----------------------
+// This Class's Header --
+//-----------------------
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/HiStats/proxtuple.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/proxtuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/proxtuple.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/HiStats/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/HiStats/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/smakefile	(revision 3445)
@@ -0,0 +1,403 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libHiStats.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basedtable.o $(SOPHYAOBJP)datatable.o $(SOPHYAOBJP)fio_dtable.o $(SOPHYAOBJP)hisprof.o $(SOPHYAOBJP)hist2err.o $(SOPHYAOBJP)histerr.o $(SOPHYAOBJP)histinit.o $(SOPHYAOBJP)histos.o $(SOPHYAOBJP)histos2.o $(SOPHYAOBJP)ntupintf.o $(SOPHYAOBJP)ntuple.o $(SOPHYAOBJP)proxtuple.o $(SOPHYAOBJP)swppfdtable.o $(SOPHYAOBJP)xntuple.o
+	rm -f $(SOPHYALIBP)libHiStats.a
+ 
+$(SOPHYALIBP)libHiStats.a : $(SOPHYAOBJP)basedtable.o $(SOPHYAOBJP)datatable.o $(SOPHYAOBJP)fio_dtable.o $(SOPHYAOBJP)hisprof.o $(SOPHYAOBJP)hist2err.o $(SOPHYAOBJP)histerr.o $(SOPHYAOBJP)histinit.o $(SOPHYAOBJP)histos2.o $(SOPHYAOBJP)histos.o $(SOPHYAOBJP)ntupintf.o $(SOPHYAOBJP)ntuple.o $(SOPHYAOBJP)proxtuple.o $(SOPHYAOBJP)swppfdtable.o $(SOPHYAOBJP)xntuple.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)basedtable.o: basedtable.cc basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basedtable.cc
+ 
+$(SOPHYAOBJP)datatable.o: datatable.cc datatable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiosegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatable.cc
+ 
+$(SOPHYAOBJP)fio_dtable.o: fio_dtable.cc datatable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiosegdb.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fio_dtable.cc
+ 
+$(SOPHYAOBJP)hisprof.o: hisprof.cc $(SOPHYAINCP)machdefs.h \
+  hisprof.h $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)perrors.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  hisprof.cc
+ 
+$(SOPHYAOBJP)hist2err.o: hist2err.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h hist2err.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)tmatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  hist2err.cc
+ 
+$(SOPHYAOBJP)histerr.o: histerr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h histerr.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histerr.cc
+ 
+$(SOPHYAOBJP)histinit.o: histinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h histos2.h \
+  $(SOPHYAINCP)utils.h hisprof.h histerr.h \
+  hist2err.h $(SOPHYAINCP)tmatrix.h ntuple.h \
+  ntupintf.h $(SOPHYAINCP)dvlist.h xntuple.h \
+  datatable.h basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histinit.cc
+ 
+$(SOPHYAOBJP)histos.o: histos.cc $(SOPHYAINCP)machdefs.h \
+  histos.h $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histos.cc
+ 
+$(SOPHYAOBJP)histos2.o: histos2.cc $(SOPHYAINCP)machdefs.h \
+  histos2.h $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)utils.h histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  histos2.cc
+ 
+$(SOPHYAOBJP)ntupintf.o: ntupintf.cc $(SOPHYAINCP)sopnamsp.h \
+  ntupintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntupintf.cc
+ 
+$(SOPHYAOBJP)ntuple.o: ntuple.cc $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h ntuple.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntuple.cc
+ 
+$(SOPHYAOBJP)proxtuple.o: proxtuple.cc $(SOPHYAINCP)sopnamsp.h \
+  proxtuple.h ntuple.h $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  proxtuple.cc
+ 
+$(SOPHYAOBJP)swppfdtable.o: swppfdtable.cc swppfdtable.h basedtable.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  swppfdtable.cc
+ 
+$(SOPHYAOBJP)xntuple.o: xntuple.cc $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)perrors.h xntuple.h \
+  $(SOPHYAINCP)machdefs.h ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xntuple.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.cc	(revision 3445)
@@ -0,0 +1,407 @@
+#include "swppfdtable.h"
+#include "pexceptions.h"
+#include "thsafeop.h"
+
+namespace SOPHYA { 
+
+/*!
+   \class SwPPFDataTable
+   \ingroup HiStats
+   This class can be used to organize data in table (row-column) form.
+   Each column holds homogeneous data (same data type), while different
+   columns can be used for different data types 
+   (integer, float, string ...).
+   A PPF stream is used as swap space. Due to limitations in the current
+   implementation of PPF streams, read operations (acces to table data) cannot
+   be performed when a table is being filled. 
+
+   \warning 
+   - When creating a table, the output PPF stream (POutPersist) must not be closed
+   (destroyed) before the SwPPFDataTable object is written to the stream.
+   - It is not possible to make a complete (deep) copy of a SwPPFDataTable
+   Copy constructor and equal operator shares the data.
+   - The destructor  DOES NOT save the table object itself to the swap 
+   stream. The << operator should be used on the output PPF stream being 
+   used as swap in order to save the table. 
+
+   \sa SOPHYA::MuTyV
+   \sa SOPHYA::DataTableRow
+   \sa SOPHYA::DataTable
+   \sa SOPHYA::SwSegDataBlock  SOPHYA::PPFDataSwapper
+
+   \code
+   #include "swppfdtable.h"
+   // ...
+   {
+   // ---- Creation of the table
+   // Create the swap stream 
+   POutPersist so("myswtable.ppf");
+   SwPPFDataTable dt(so, 64);
+   // define table columns
+   dt.AddFloatColumn("X0_f");
+   dt.AddFloatColumn("X1_f");
+   dt.AddDoubleColumn("X0X0pX1X1_d");
+   // Fill the table
+   r_8 x[5];
+   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];
+     dt.AddRow(x);
+   }
+   // Printing table info
+   cout << dt ;
+   // Swap out all data and write the table structure to the PPF stream 
+   so << dt ;
+   // ....
+   }
+   {
+   // ---- Accessing information from a previously created table
+   SwPPFDataTable dt;
+   PInPersist si("myswtable.ppf");
+   si >> dt;
+   // Printing table info
+   cout << dt ;   
+   }
+   \endcode
+*/
+//! Default constructor with optional specification of block (or segment) size 
+SwPPFDataTable::SwPPFDataTable(sa_size_t segsz)
+  : BaseDataTable(segsz),
+    mSwOut(NULL), mSwIn(NULL)
+{
+}
+/*! Constructor with the specification of the output swap stream -
+    and optional specification of block (or segment) size
+*/
+SwPPFDataTable::SwPPFDataTable(POutPersist & os, sa_size_t segsz)
+  : BaseDataTable(segsz) ,
+    mSwOut(&os), mSwIn(NULL),
+    mISwapper(os), mLSwapper(os), mFSwapper(os), mDSwapper(os), 
+    mYSwapper(os), mZSwapper(os), mSSwapper(os)
+{
+}
+//! Protected constructor for creation from a swap stream 
+SwPPFDataTable::SwPPFDataTable(PInPersist & is, sa_size_t segsz)
+  : BaseDataTable(segsz) ,
+    mSwOut(NULL), mSwIn(NULL)
+{
+  PInPersist* pis = new PInPersist(is.FileName(), false);
+  mSwIn = new St_InSwap;
+  mSwIn->pis = pis;  mSwIn->refcnt = 1;
+  mISwapper.SetInStream(*pis);
+  mLSwapper.SetInStream(*pis);
+  mFSwapper.SetInStream(*pis);
+  mDSwapper.SetInStream(*pis);
+  mYSwapper.SetInStream(*pis);
+  mZSwapper.SetInStream(*pis);
+  mSSwapper.SetInStream(*pis);
+}
+
+//! copy constructor - shares the data (and copies the thread safety state)
+
+SwPPFDataTable::SwPPFDataTable(SwPPFDataTable const & a)
+  : BaseDataTable(a.SegmentSize()),
+    mSwOut(NULL), mSwIn(NULL)
+{
+  Share(a);
+}
+//! Destructor - Deletes / closes the input PPF swap stream  
+SwPPFDataTable::~SwPPFDataTable()
+{
+  if (mSwIn) { 
+    mSwIn->refcnt--;
+    if (mSwIn->refcnt == 0) {
+      delete mSwIn->pis;
+      delete mSwIn;
+      mSwIn = NULL;
+    }
+  }
+}
+
+void SwPPFDataTable::Share(SwPPFDataTable const & a)
+{
+  // Recopie (attention !) brutale des swappers  et les streams associes
+  mISwapper = a.mISwapper;
+  mLSwapper = a.mLSwapper;
+  mFSwapper = a.mFSwapper;
+  mDSwapper = a.mDSwapper;
+  mYSwapper = a.mYSwapper;
+  mZSwapper = a.mZSwapper;
+  mSSwapper = a.mSSwapper;
+  
+  mSwOut = a.mSwOut;
+  mSwIn = a.mSwIn;
+  if (mSwIn)  mSwIn->refcnt++;  // comptage de reference pour le stream input 
+
+  // On recopie la taille de segment
+  mSegSz = a.SegmentSize();
+  if (a.NVar() == 0)  return;  // Table sans colonne 
+
+  // On copie la structure de table 
+  CopyStructure(a);
+  if (a.IsThreadSafe())  SetThreadSafe(true);
+  else SetThreadSafe(false);
+
+  //
+  // Update nombre d'entree, ...
+  mNEnt = a.mNEnt;
+  mNSeg = a.mNSeg;
+  if (a.mInfo)  mInfo = new DVList(*(a.mInfo));
+
+  // mis a jour des tableax min-max 
+  mMin = a.mMin;
+  mMax = a.mMax;
+  mMinMaxNEnt = a.mMinMaxNEnt;
+
+  // Et on partage les donnees des colonnes 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    sa_size_t ska = a.mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk] = a.mICols[ska];
+    break;
+    case LongField :
+      mLCols[sk] = a.mLCols[ska]; 
+      break;
+    case FloatField :
+      mFCols[sk] = a.mFCols[ska]; 
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk] = a.mDCols[ska]; 
+      break;
+    case ComplexField :
+      mYCols[sk] = a.mYCols[ska]; 
+      break;
+    case DoubleComplexField :
+      mZCols[sk] = a.mZCols[ska]; 
+      break;
+    case StringField :
+      mSCols[sk] = a.mSCols[ska]; 
+      break;
+    default:
+      throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
+    break;
+    }
+  }  
+}
+void SwPPFDataTable::SwapOutAll() const
+{
+  // Et on vide les buffers de swap 
+  for (size_t kk=0; kk<mNames.size(); kk++) {
+    sa_size_t sk = mNames[kk].ser;
+    switch (mNames[kk].type) {
+    case IntegerField :
+      mICols[sk].SwapOutBuffer();
+    break;
+    case LongField :
+      mLCols[sk].SwapOutBuffer();
+      break;
+    case FloatField :
+      mFCols[sk].SwapOutBuffer();
+      break;
+    case DoubleField :
+    case DateTimeField :
+      mDCols[sk].SwapOutBuffer();
+      break;
+    case ComplexField :
+      mYCols[sk].SwapOutBuffer();
+      break;
+    case DoubleComplexField :
+      mZCols[sk].SwapOutBuffer();
+      break;
+    case StringField :
+      mSCols[sk].SwapOutBuffer();
+      break;
+    default:
+      throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
+    break;
+    }
+  }  
+}
+
+void SwPPFDataTable::Clear()
+{
+  if ( (NVar() == 0) && (NEntry() == 0)) return;
+  mNEnt = 0;
+  mNSeg = 0;
+  if (mVarD) delete[] mVarD;
+  mVarD = NULL;
+  if (mVarMTV) delete[] mVarMTV;
+  mVarMTV = NULL;
+  mNames.clear();
+  if (mInfo) delete mInfo;
+  mInfo = NULL;
+  if (mThS) delete mThS;
+  mThS = NULL;
+  mMin.clear();
+  mMax.clear();
+  mMinMaxNEnt.clear();
+  mIColsP.clear();
+  mLColsP.clear();
+  mFColsP.clear();
+  mDColsP.clear();
+  mYColsP.clear();
+  mZColsP.clear();
+  mSColsP.clear();
+
+  mIColIdx.clear();
+  mLColIdx.clear();
+  mFColIdx.clear();
+  mDColIdx.clear();
+  mYColIdx.clear();
+  mZColIdx.clear();
+  mSColIdx.clear();
+
+  mICols.clear();
+  mLCols.clear();
+  mFCols.clear();
+  mDCols.clear();
+  mYCols.clear();
+  mZCols.clear();
+  mSCols.clear();
+}
+
+
+/*! 
+  Implements the action defined in the BaseDataTable interface.
+  In the current implementation, throws an exception (ParmError) 
+  if the table contains some data already.
+*/
+sa_size_t SwPPFDataTable::AddColumn(FieldType ft, string const & cnom)
+{
+  if (NEntry() > 0) 
+    throw ParmError("SwPPFDataTable::AddColumn() Table contains already data ");
+  CheckColName(cnom);
+  sa_size_t ser; 
+  sa_size_t idx = NVar(); 
+  switch (ft) {
+  case IntegerField :
+    ser = mICols.size();
+    mICols.push_back(SwSegDataBlock<int_4>(mISwapper, mSegSz));
+    mIColIdx.push_back(idx);
+    mIColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mICols.size(); kk++)
+      mIColsP[kk] = &(mICols[kk]);
+    break;
+  case LongField :
+    ser = mLCols.size();
+    mLCols.push_back(SwSegDataBlock<int_8>(mLSwapper, mSegSz));
+    mLColIdx.push_back(idx);
+    mLColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mLCols.size(); kk++)
+      mLColsP[kk] = &(mLCols[kk]);
+    break;
+  case FloatField :
+    ser = mFCols.size();
+    mFCols.push_back(SwSegDataBlock<r_4>(mFSwapper, mSegSz));
+    mFColIdx.push_back(idx);
+    mFColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mFCols.size(); kk++)
+      mFColsP[kk] = &(mFCols[kk]);
+    break;
+  case DoubleField :
+  case DateTimeField :
+    ser = mDCols.size();
+    mDCols.push_back(SwSegDataBlock<r_8>( mDSwapper,mSegSz));
+    mDColIdx.push_back(idx);
+    mDColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mDCols.size(); kk++)
+      mDColsP[kk] = &(mDCols[kk]);
+    break;
+  case ComplexField :
+    ser = mYCols.size();
+    mYCols.push_back(SwSegDataBlock< complex<r_4> >(mYSwapper, mSegSz));
+    mYColIdx.push_back(idx);
+    mYColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mYCols.size(); kk++)
+      mYColsP[kk] = &(mYCols[kk]);
+    break;
+  case DoubleComplexField :
+    ser = mZCols.size();
+    mZCols.push_back(SwSegDataBlock< complex<r_8> >(mZSwapper, mSegSz));
+    mZColIdx.push_back(idx);
+    mZColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mZCols.size(); kk++)
+      mZColsP[kk] = &(mZCols[kk]);
+    break;
+  case StringField :
+    ser = mSCols.size();
+    mSCols.push_back(SwSegDataBlock<string>(mSSwapper, mSegSz));
+    mSColIdx.push_back(idx);
+    mSColsP.push_back(NULL);
+    for(sa_size_t kk=0; kk<mSCols.size(); kk++)
+      mSColsP[kk] = &(mSCols[kk]);
+    break;
+  default:
+    throw ParmError("SwPPFDataTable::AddColumn() unknown field type ");
+    break;
+  }
+  colst col;
+  col.nom = cnom;
+  col.type = ft;
+  col.ser = ser;
+  mNames.push_back(col);
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  mMin.push_back(9.E39);
+  mMax.push_back(-9.E39);
+  mMinMaxNEnt.push_back(0);
+
+  return NVar();
+}
+
+//! Adds a row (or line to the table) with r_8* input data.
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow()
+*/
+sa_size_t SwPPFDataTable::AddRow(const r_8* data)
+{
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  if (mThS) mThS->lock();   // tread-safety
+  for(sa_size_t k=0; k<NVar(); k++) {
+    double x = data[k];
+    if (x < mMin[k])  mMin[k] = x;
+    if (x > mMax[k])  mMax[k] = x;
+    mMinMaxNEnt[k]++;
+  }
+  if (mThS) mThS->unlock(); // tread-safety
+  return BaseDataTable::AddRow(data);
+}
+
+//! Adds a row (or line to the table) with input data as an array of MuTyV
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow()
+*/
+sa_size_t SwPPFDataTable::AddRow(const MuTyV * data)
+{
+  // On est oblige de calculer les min-max lors du remplissage
+  // On ne peut pas en effet 'relire' le swap pendant l'ecriture
+  if (mThS) mThS->lock();   // tread-safety
+  for(sa_size_t k=0; k<NVar(); k++) {
+    double x = (double)data[k];
+    if (x < mMin[k])  mMin[k] = x;
+    if (x > mMax[k])  mMax[k] = x;
+    mMinMaxNEnt[k]++;
+  }
+  if (mThS) mThS->unlock(); // tread-safety
+  return BaseDataTable::AddRow(data);
+}
+
+
+//! Adds a row (or line) to the table with input data as DataTableRow object
+/*! 
+  The min/max values for each column is updated, in addition 
+  to the actions performed by the base class AddRow()
+*/
+sa_size_t SwPPFDataTable::AddRow(DataTableRow const& data)
+{
+  if ( data.Size() != NCols() )
+    throw SzMismatchError(" SwPPFDataTable::AddRow() - data.Size() != NCols() ");
+  return AddRow(data.MTVPtr());
+}
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/swppfdtable.h	(revision 3445)
@@ -0,0 +1,91 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Class DataTable  (Row-Column data table in memory) 
+//   R. Ansari -  Avril 2005
+//   (C)  LAL-IN2P3/CNRS    CEA-DAPNIA  
+
+#ifndef SWPPFDTABLE_H_SEEN
+#define SWPPFDTABLE_H_SEEN
+
+#include "basedtable.h"
+#include "swsegdb.h"
+#include "ppfswapper.h"
+#include "objfio.h"
+
+
+namespace SOPHYA {
+
+//! An implementation of BaseDataTable with using a PPF stream as swap space.
+class SwPPFDataTable : public BaseDataTable {
+public:
+  SwPPFDataTable(sa_size_t segsz=512);
+  SwPPFDataTable(POutPersist & os, sa_size_t segsz=512); 
+  SwPPFDataTable(SwPPFDataTable const& a); 
+
+  virtual ~SwPPFDataTable();
+
+  virtual sa_size_t AddColumn(FieldType ft, string const & cnom);
+
+  // Filling data structures (adding lines/rows)
+  virtual sa_size_t AddRow(const r_8* data);
+  virtual sa_size_t AddRow(const MuTyV * data);
+  virtual sa_size_t AddRow(DataTableRow const& data);
+
+  //! Equal (copy) operator - Copies the data and the structure if necessary from \b a   
+  inline  SwPPFDataTable& operator = (BaseDataTable const& a) 
+  { CopyMerge(a, true) ; return *this ; } 
+  //! Equal (copy) operator - Copies the structure and shares the data \b a   
+  inline SwPPFDataTable&  operator = (SwPPFDataTable const& a) 
+  { Clear(); Share(a); return *this ; } 
+
+  //  Pour la gestion de persistance PPF
+  friend class ObjFileIO<BaseDataTable> ;
+  
+  //! Reset(Clear) the table content and structure
+  virtual void Clear();
+  /*! This method should be called in order to empty the swapout buffer, 
+     before saving object to PPF stream 
+  */
+  void SwapOutAll() const;
+protected:
+  SwPPFDataTable(PInPersist & is, sa_size_t segsz); 
+  void Share(SwPPFDataTable const & a);
+
+  // Donnees en memoire
+  std::vector< SwSegDataBlock<int_4> > mICols; 
+  PPFDataSwapper<int_4> mISwapper;
+  std::vector< SwSegDataBlock<int_8> > mLCols; 
+  PPFDataSwapper<int_8> mLSwapper;
+  std::vector< SwSegDataBlock<r_4> > mFCols;
+  PPFDataSwapper<r_4> mFSwapper;
+  std::vector< SwSegDataBlock<r_8> > mDCols; 
+  PPFDataSwapper<r_8> mDSwapper;
+  std::vector< SwSegDataBlock< complex<r_4> > > mYCols;
+  PPFDataSwapper< complex<r_4> > mYSwapper;
+  std::vector< SwSegDataBlock< complex<r_8> > > mZCols;
+  PPFDataSwapper< complex<r_8> > mZSwapper;
+  std::vector< SwSegDataBlock<string> > mSCols;    
+  PPFDataSwapper<string> mSSwapper;
+ 
+  // Output swap stream doit etre cree avant l'appel au constructeur
+  // et rester valide (non detruit) tant que l'objet SwPPFDataTable existe
+  POutPersist* mSwOut;   
+  // Input swap stream - On cree un input swap stream et on fait 
+  // un comptage de reference pour le detruire lorsque tous les tables
+  // l'utilisant sont supprimes
+  //! \cond    Pour NE PAS inclure dans la doc
+  typedef struct { PInPersist* pis; uint_4 refcnt; } St_InSwap; 
+  //! \endcond 
+  St_InSwap * mSwIn;
+}; 
+  
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, SwPPFDataTable & obj)
+{ obj.SwapOutAll();  ObjFileIO<BaseDataTable> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, SwPPFDataTable & obj)
+{  ObjFileIO<BaseDataTable> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/HiStats/xntuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/xntuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/xntuple.cc	(revision 3445)
@@ -0,0 +1,1018 @@
+#include <string.h>
+#include "ppersist.h"
+#include "perrors.h"
+#include "xntuple.h"
+#ifdef OS_MACOSX
+#include <unistd.h>
+#endif
+
+namespace SOPHYA {
+
+#define LENNAME 31 
+#define MAXLEN 128
+#define BADVAL -1.e19
+
+/*!
+   \class 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::BaseDataTable SOPHYA::DataTable SOPHYA::SwPPFDataTable
+
+   \deprecated 
+   This class is being deprecated. Use classes derived from SOPHYA::BaseDataTable 
+   whenever possible
+
+
+   \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 ; 
+
+
+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 
+// 
+// 
+sa_size_t XNTuple::NbLines() const
+{
+    return(NEntry());
+}
+
+sa_size_t XNTuple::NbColumns() const
+{
+    return(NVar());
+}
+
+r_8* XNTuple::GetLineD(sa_size_t 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(sa_size_t n, sa_size_t 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(sa_size_t 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(sa_size_t n, sa_size_t 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(sa_size_t 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) ; 
+}
+
+
+sa_size_t XNTuple::ColumnIndex(string const& nom) const 
+{
+    return IndexNom(nom.c_str()) ; 
+}
+
+
+string XNTuple::ColumnName(sa_size_t 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(sa_size_t 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 ObjFileIO<XNTuple>
+   \ingroup HiStats
+   Persistence (serialisation) handler for class XNTuple
+*/
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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() ; 
+    }
+}
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/HiStats/xntuple.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/HiStats/xntuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/HiStats/xntuple.h	(revision 3445)
@@ -0,0 +1,179 @@
+// -*- 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 
+// 
+//! \cond  Pour ne pas inclure dans la documentation
+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 ;  
+} ; 
+//! \endcond
+//  Forward class declaration for Fits handler
+class FITS_XNTuple;
+
+//! Class for creation and management of data sets organised as a table
+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 sa_size_t NbLines() const ;
+    virtual sa_size_t NbColumns() const ;
+    virtual r_8 *     GetLineD(sa_size_t n) const ;
+    virtual r_8	      GetCell(sa_size_t n, sa_size_t k) const ;
+    virtual r_8	      GetCell(sa_size_t n, string const & nom) const ;
+    virtual string    GetCelltoString(sa_size_t n, sa_size_t k) const ;
+    virtual void      GetMinMax(sa_size_t k, double& min, double& max)   const ; 
+    virtual void      GetMinMax(string const & nom, double& min, double& max)   const ; 
+    virtual sa_size_t ColumnIndex(string const & nom)  const ;
+    virtual string    ColumnName(sa_size_t k) const;
+    virtual string    VarList_C(const char* nomx=NULL) const ;
+    virtual string    LineHeaderToString() const;
+    virtual string    LineToString(sa_size_t 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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<XNTuple>
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/Manual/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/Makefile	(revision 3445)
@@ -0,0 +1,52 @@
+
+#-------------------------------------------------------
+all: doc sophya pmixer piapp
+
+#-------------------------------------------------------
+clean:
+	rm -rf *.o dox_filter
+	if [ -d /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual/ ] ; then cd /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual// ; rm -rf html latex man rtf; fi
+
+#-------------------------------------------------------
+copy: 
+	if [ ! -d /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex ] ; then mkdir /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex; fi
+	cp -p *.tex *.sty *.eps *.inc /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/.
+
+#-------------------------------------------------------
+doc: filter
+	doxygen mydoxy.conf
+
+#-------------------------------------------------------
+filter: dox_filter
+
+dox_filter : dox_filter.o
+
+dox_filter.o : dox_filter.c
+
+#-------------------------------------------------------
+sophya: copy /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/sophya.ps
+
+/home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/sophya.ps: sophya.tex defsophya.sty blue_sophya_400.eps ex1.inc
+	cd /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/; \
+	latex sophya.tex; \
+	makeindex sophya; \
+	latex sophya; \
+	dvips -o sophya.ps sophya.dvi
+
+piapp: copy /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/piapp.ps
+
+/home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/piapp.ps: piapp.tex piahelp.tex defsophya.sty
+	cd /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/; \
+	latex piapp.tex; \
+	makeindex piapp; \
+	latex piapp; \
+	dvips -o piapp.ps piapp.dvi
+
+pmixer: copy /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/pmixer.ps
+
+/home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/pmixer.ps: pmixer.tex
+	cd /home/manip/mnt/planck/cmv/SophyaWork/Linux/../Manual//latex/; \
+	latex pmixer.tex; \
+	latex pmixer; \
+	dvips -o pmixer.ps pmixer.dvi
+
Index: /tags/V_Nov2007/SophyaLib/Manual/afaire2003.txt
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/afaire2003.txt	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/afaire2003.txt	(revision 3445)
@@ -0,0 +1,139 @@
+:::::::::::: Plan de modifs pour SOPHYA V 2.0 PI/piapp V 4.0 ::::::::::::
+
+                    ----------------------------
+                    |  Gestion du code (Mgr/ ) |
+                    ----------------------------
+
+ o Chemins/variables d'environnement 
+   - Remplacer DPCDEVREP DPCBASEREP par SOPHYADEVREP et SOPHYABASEREP
+   - Remplacer EROSCXX par SOPHYACXX (?)
+ o Simplifier/rationaliser les makefiles 
+   - Mettre les flags de compils pour chaque compilo-systeme dans un fichier au lieu 
+     d'avoir tout Makefile.h 
+     Exemple fichier Mgr/linux_g++.flags 
+      CPPFLAGS = ...
+      CXXFLAGS = ... 
+      LIBS = ...
+
+o Mettre un script pour chercher les lib externes (c-fitsio, FFTW, ...) et creer 
+  eventuellement l'arborescence ExtLibs
+
+o Inclure la definition des flags influant sur le code (comme -DOSF1/Linux/Darwin/IRIX64
+ SO_BOUNDCHECKING a la fin du fichier machdefs.h que l'on fabriquera a partir de du machdef_mkmf.h )
+  PB-> ce fichier deviendra alors dependant du systeme et de l'installation !
+  Faut-il deplacer alors Include/ sous uname-$EROSCXX (Linux-g++) 
+  ou carrement considerer que la separation pour differents systemes doit se faire au 
+  niveau de SOPHYADEV/BASE/REP ?
+
+o Abandonner (?) les regles de compilation par defaut 
+  Inclure dans les Makefile la ligne de commande :
+  $(OBJ)toto.o : toto.cc toto.h titi.h ...
+        $(COMPILECXX) -$(CPPFLAGS) $(CXXFLAGS) -c -o $(OBJ)toto.o toto.cc
+
+o Garder les Makefile simple (eviter trop de tests et syntaxe complique)
+
+
+                    -----------------------------------
+                    |   Code/Librairie SOPHYA (V2.0)  |
+                    -----------------------------------
+
+o Fichiers PPersist (BaseTools) :
+  - Ajouter la possibilite d'ecrire des complex(r_4> complex<r_8>
+    (actuellement c'est ecrit sous forme de 2*r_4 ou 2*r_8)
+  - Ajouter des tag de positionnement qui pourrait servir au cas 
+    ou on utiliserait le fichier PPF comme fichier de swap
+    Ces tags ne peuvent pas etre les memes que les name-tag 
+    existant actuellement. 
+    Une utilisation annexe de ces tags peut etre alors un moyen 
+    de verifier que le fichier n'est pas corrompu
+    Ce tag se presente alors sous forme de 
+    <tag (1 byte)><FilePosition (8 byte, long int)>
+    On peut alors parcourir le fichier et verifier la coherence de
+    ces tags.
+  - Il faut aussi ajouter au niveau de POutPersist et PInPersist
+    les services pour ecrire et lire une collection de tag de 
+    positionnement, afin qu'un objet puisse utiliser une liste de
+    tag pour se positionner
+
+o BaseTools/ Voir autres remarques ds fichier Manual/sophya_afaire.txt
+  concernant en particulier les NDataBlock<T> DataBlock<T> ...
+
+o Les tableaux : TArray/ 
+  - Ajouter une classe de base abstraite GenericMatrix<T>
+    avec methode d'acces aux elements, nb de lignes, nb de colonnes,
+    ...
+  - Introduire les TinyMatrix  (TinyMatrix<T, int L, int C>)
+    avec passage de/vers TMatrix<T> (et TinyVector<T, int N>) ?
+
+  - Introduire des matrices creuses simples SpareMatrix<T>
+
+  - Introduire les DiagonalMatrix<T> 
+
+  Remarque: Les TMatrix TinyMatrix et  SparseMatrix heritent de GenericMatrix
+
+o HiStats
+  - Faire une classe SuperNTuple (!), facile a utiliser, sachant swaper sur les 
+    PPF, avec des champs de differents type
+ 
+o IFFTW/ 
+  - Passage a FFTW 3.x  ?
+
+o Voir autres remarques pour l'ensemble des modules ds Manual/sophya_afaire.txt
+
+
+                    ---------------------------------
+                    | Code/Librairie PI  (->V 4.0)  |
+                    ---------------------------------
+
+o Menu contextuel pour les Drawers
+  - Ajouter a PIImage, PIScrDrawWdg(2D), PIDraw3DWdg(3D) un menu obtenu 
+    sur <Shift><Bouton-1> par exemple, avec la liste de tous les Drawers
+    permettant d'afficher la fenetre des options graphiques, ou le fenetre 
+    des options ou la fenetre des options texte, activer deplacement/resize
+    des drawers, suppression (delete) ou detach des drawers, et en fonction
+    du widgets, la fenetre des axes ou de controle d'image
+
+o Mettre l'option auto-scale (rapport entre axes X,Y,Z) pour les Drawers3D 
+    verifer/debugger la definition de la boite 3D au niveau des Drawers3D
+
+o Traceur d'histos, NTuples, ...
+  Remplacer le trace des lignes par morceau fait par appel multiples
+  a DrawLine a un seul appel a DrawPolygon (si les lignes sont connectes
+  bien sur) --> Ca ameliore sensiblement l'aspect pour le trace en pointille
+
+o Ajouter un traceur de Bar-chart 2D OU ApplePie (facile !)
+  On donne une serie de nombres, serie de couleur, + serie de strings
+  et on trace alors une sorte d'histo, avec des barres (rectangles) espaces
+   Ou bien on trace un cercle divise en zones 
+
+o Ajouter un traceur de Lego-Plot
+
+o PIImageWindow (Une fenetre avec une PIImage, un Zoom et une vue globale)
+  Assemblage
+
+o (?) Une fonction pour faire facilement une fenetre d'alerte ou d'info (?)
+
+                    ---------------------------------
+                    |            piapp              |
+                    ---------------------------------
+
+o Verifier l'interpreteur et introduire le type de variable vecteur 
+  qui peut etre detecte par exemple lors de l'initialisation par set 
+  set a 'Bonjour CMV' # -> variable scalaire
+  set va [ 12 14 hello ... ] # variable de type vecteur $va[]
+
+o Voir comment on pourrait "joindre" deux objets ayant l'interface NTupleInterface
+  pour pouvoir plotter des objets, l'un vs l'autre
+
+o Separer la classe PIACmd en une classe de base (CShellLikeInterpreter) 
+  (a mettre ds SysTools) et la classe PIACmd  a laisser ds PIext 
+
+o (???) Introduire quelque chose du style 
+  AddDialogue("Cmd", "dialogue-description) 
+  qui pourrait fabriquer automatiquement une fenetre avec des champs a remplir 
+  pour les commandes usuelles (???)
+
+o Voir les autres commentaires ds Manual/spiapp_afaire.txt
+
+
+
Index: /tags/V_Nov2007/SophyaLib/Manual/defsophya.sty
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/defsophya.sty	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/defsophya.sty	(revision 3445)
@@ -0,0 +1,89 @@
+% Definition de commande pour les schemas de classe
+%  Definition of template class \tcls{Vector} --> Vector<T>
+\newcommand{\tcls}[1] {#1$<$T$>$}   
+\newcommand{\tclsc}[2] {#1$<$#2$>$}   
+%  Putting a class name in a box
+\newcommand{\clsbox}[1] { \framebox[45mm][c]{\mbox{\rule[-1mm]{0mm}{5mm} \bf #1} } }
+%  Emplty class box
+\newcommand{\eclbox} { \makebox[45mm][c]{\mbox{\rule[-1mm]{0mm}{5mm}} } \ }
+%  Length of \longleftarrow
+\newlength{\arrclsw}   \settowidth{\arrclsw}{$\longleftarrow$}
+%  One single class diagram
+\newcommand{\dclsa}[1]{\clsbox{#1} \\[2mm]} 
+%  two class diagram
+\newcommand{\dclsbb}[2]{\clsbox{#1} $\longleftarrow$ \clsbox{#2} \\[2mm]}
+%  two class diagram with one empty class (placeholder)
+\newcommand{\dclsb}[1]{\eclbox $\longleftarrow$ \clsbox{#1} \\[2mm]}
+%  three class diagram
+\newcommand{\dclsccc}[3]{\clsbox{#1} $\longleftarrow$ 
+	                 \clsbox{#2} $\longleftarrow$ \clsbox{#3} \\[2mm]}
+%  three class diagram with one empty class (placeholder)
+\newcommand{\dclscc}[2]{\eclbox $\longleftarrow$ \clsbox{#1} $\longleftarrow$ 
+	                \clsbox{#2} \\[2mm]}
+%  three class diagram with two empty classes (placeholder)
+\newcommand{\dclsc}[1]{\eclbox \hspace{\arrclsw} \eclbox 
+                       $\longleftarrow$ \clsbox{#1} \\[2mm]}
+
+\newcommand{\bul}{$\bullet \ $}
+
+
+% ---------- Commande pour la mise en forme de la page de titre ----------------
+
+%  L'entete de page de titre
+\newcommand{\titrehp}[1]
+{
+\vspace{1cm}
+\makebox[160mm][c]{\includegraphics[width=8cm]{blue_sophya_400.eps}}
+% \hspace{7mm} \raisebox{6mm}{\rule{100 mm}{0.5 mm} }
+% \makebox[40 mm]{\bf Sophya }
+\vspace{2cm}
+\begin{center}
+% \par \renewcommand{\baselinestretch}{2.0} \small 
+{\LARGE \bf #1}
+\end{center}
+}
+
+\newcommand{\auteurs}[1]
+{
+\vspace{3 cm}
+\begin{center}
+\begin{tabular}{ll}
+#1
+\end{tabular}
+\end{center}
+}
+
+\newcommand{\auteursall}
+{
+\vspace{3 cm}
+\begin{center}
+\begin{tabular}{ll}
+R. Ansari     &  ansari@lal.in2p3.fr       \\
+E. Aubourg    &  aubourg@hep.saclay.cea.fr \\
+G. Le Meur    &  lemeur@lal.in2p3.fr       \\
+E. Lesquoy    &  lesquoy@hep.saclay.cea.fr \\
+C. Magneville &  cmv@hep.saclay.cea.fr     \\
+S. Versille   &  versille@lal.in2p3.fr     \\
+F. Touze      &  touze@lal.in2p3.fr  
+\end{tabular}
+\end{center}
+}
+
+%  Bas de page de titre
+\newcommand{\titrebp}[1]
+{
+\vfill
+\hfill 
+\framebox[\textwidth]{\hspace{0.5cm} \bf Sophya Note  #1 
+\hspace{1cm} \today } \\
+}
+
+
+
+%  Definition de taille de page
+\setlength{\textwidth}{16cm}
+\setlength{\textheight}{21.5cm}
+\setlength{\topmargin}{0.5cm}
+\setlength{\oddsidemargin}{0.cm}
+\setlength{\evensidemargin}{0.cm}
+\setlength{\unitlength}{1mm}
Index: /tags/V_Nov2007/SophyaLib/Manual/dox_filter.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/dox_filter.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/dox_filter.c	(revision 3445)
@@ -0,0 +1,29 @@
+/*
+Filtre pour doxygen :
+  - ajoute "using namespace SOPHYA;" dans les fichiers *.cc
+*/
+#include <stdio.h>
+#define LENLINE 4096
+
+int main(int narg,char *arg[])
+{
+ FILE *file;
+ char line[LENLINE];
+
+ /* Checks */
+ if ( narg <= 1 ) {
+   strcpy(line,"No argument for dox_filter\n");
+   fputs(line,stdout);
+   exit(-1);
+ }
+ if( ( file = fopen(arg[1],"r") ) == NULL ) {
+   sprintf(line,"File %s could not be opened\n",arg[1]);
+   fputs(line,stdout);
+   exit(-2);
+ }
+
+ /* filter */
+ strcpy(line,"using namespace SOPHYA;\n");
+ fputs(line,stdout);
+ while ( fgets(line,LENLINE,file) != NULL ) fputs(line,stdout);
+}
Index: /tags/V_Nov2007/SophyaLib/Manual/dox_sophya.conf
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/dox_sophya.conf	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/dox_sophya.conf	(revision 3445)
@@ -0,0 +1,1231 @@
+# Doxyfile 1.4.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = SOPHYA
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = .
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = 
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = *.h \
+                         *.cc \
+                         *.c \
+                         *.f \
+                         *.cc \
+                         *.C
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = ./dox_filter
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 3
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = SOPHYA::
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = __cplusplus
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
Index: /tags/V_Nov2007/SophyaLib/Manual/ex1.inc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/ex1.inc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/ex1.inc	(revision 3445)
@@ -0,0 +1,74 @@
+\begin{verbatim}
+#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;
+  }
+}
+\end{verbatim}
Index: /tags/V_Nov2007/SophyaLib/Manual/mkmf
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/mkmf	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/mkmf	(revision 3445)
@@ -0,0 +1,232 @@
+#!/bin/csh
+#####################################################
+if( $#argv >= 1 ) then
+  if( "$1" == "-h" ) then
+    echo "mkmf [-options] [-o dir] [module1] [module2] [...]"
+    echo "  generate documentation for all Sophya"
+    echo "  or only for module [module...]"
+    echo "  **** [-options] :"
+    echo "  -libmod : generate doc for library modules (default)"
+    echo "  -prgmod : generate doc for program modules"
+    echo "  -allmod : generate doc for library+program modules"
+    echo "  -html : generate HTML doc"
+    echo "  -latex : generate LATEX doc"
+    echo "  -man : generate MAN doc"
+    echo "  -rtf : generate RTF doc"
+    echo "  default is : html + latex"
+    echo "  **** [-o dir] : directory where doc have to be put"
+    echo "  default is ."
+    exit -1
+  endif
+endif
+#####################################################
+
+##################################
+######## Decode arguments ########
+##################################
+set libmodules = ( \
+  BaseTools HiStats NTools Samba SkyMap SUtils SysTools TArray \
+  SkyT FitsIOServer IFFTW LinAlg XAstroPack \
+  )
+set prgmodules = ( PMixer PrgMap PrgUtil ProgPI )
+
+set allmodules = ( $libmodules $prgmodules )
+
+unset modules; unset latex; unset html; unset man; unset rtf
+set outdir = "."
+if( $#argv >= 1 ) then
+  while ( $#argv > 0)
+    if( "$1" == "-o" ) then
+      shift
+      set outdir = $1
+    else if( "$1" == "-html" ) then
+      set html
+    else if( "$1" == "-latex" ) then
+      set latex
+    else if( "$1" == "-man" ) then
+      set man
+    else if( "$1" == "-rtf" ) then
+      set rtf
+    else if( "$1" == "-libmod" ) then
+      set modules = ( $libmodules )
+    else if( "$1" == "-prgmod" ) then
+      set modules = ( $prgmodules )
+    else if( "$1" == "-allmod" ) then
+      set modules = ( $allmodules )
+    else
+      if( ! $?modules ) set modules
+      set modules = ( $modules $1 )
+    endif
+    shift
+  end
+endif
+if( ! $?html  && ! $?latex  && ! $?man  && ! $?rtf ) then
+  set html
+  set latex
+endif
+if( ! $?modules ) then
+  set modules = ( $allmodules )
+endif
+
+##########################################
+######## Test de la configuration ########
+##########################################
+
+#------------
+# mydoxy.conf
+#------------
+cp dox_sophya.conf mydoxy.conf
+
+#---------------
+# doxygen path ?
+#---------------
+which doxygen >! /dev/null
+if( $status != 0 ) then
+  echo 'ERROR: doxygen is not installed...'
+  exit -2
+else
+    set s = `which doxygen`
+  echo 'doxygen is installed in : ' $s:h
+  echo 'mkmf will automatically update the config file.'
+    echo "BIN_ABSPATH = $s:h" >>  mydoxy.conf
+    grep 'BIN_ABSPATH' mydoxy.conf | grep -v ^\#
+endif
+
+#-----------------
+# Version number ?
+#-----------------
+set f = ../BaseTools/sversion.h
+if( -e $f ) then
+  set v = `grep 'SOPHYA_VERSION'  $f | awk '{print $3}'`
+  set r = `grep 'SOPHYA_REVISION' $f | awk '{print $3}'`
+  set t = `grep 'SOPHYA_TAG'      $f | awk '{print $3}'`
+  echo "PROJECT_NUMBER = V${v}_R${r}_${t}" >>  mydoxy.conf
+else
+  echo "PROJECT_NUMBER = Not_Defined" >>  mydoxy.conf
+endif
+grep 'PROJECT_NUMBER = ' mydoxy.conf | tail -1
+
+#---------------
+# What modules ?
+#---------------
+set lf =
+foreach f ( $modules )
+  echo "... Generating doc for ../$f"
+  set lf = ( ../$f $lf )
+end
+echo "INPUT = $lf" >>  mydoxy.conf
+grep 'INPUT = ' mydoxy.conf | tail -1
+
+set lf =
+foreach f ( $allmodules )
+  set lf = ( ../$f $lf )
+end
+echo "EXAMPLE_PATH = $lf" >>  mydoxy.conf
+
+#-------------------
+# What kind of doc ?
+#-------------------
+if( $?html ) then
+  echo "GENERATE_HTML = YES" >>  mydoxy.conf
+  echo "...... generating HTML"
+else
+  echo "GENERATE_HTML = NO" >>  mydoxy.conf
+endif
+if( $?latex ) then
+  echo "GENERATE_LATEX = YES" >>  mydoxy.conf
+  echo "...... generating LATEX"
+else
+  echo "GENERATE_LATEX = NO" >>  mydoxy.conf
+endif
+if( $?man ) then
+  echo "GENERATE_MAN = YES" >>  mydoxy.conf
+  echo "...... generating MAN"
+else
+  echo "GENERATE_MAN = NO" >>  mydoxy.conf
+endif
+if( $?rtf ) then
+  echo "GENERATE_RTF = YES" >>  mydoxy.conf
+  echo "...... generating RTF"
+else
+  echo "GENERATE_RTF = NO" >>  mydoxy.conf
+endif
+
+#------------------------
+# What output directory ?
+#------------------------
+if( ! -d $outdir ) then
+  echo ERROR: Not existing directory : $outdir
+  exit -1
+endif
+echo "OUTPUT_DIRECTORY = $outdir" >>  mydoxy.conf
+grep 'OUTPUT_DIRECTORY = ' mydoxy.conf | tail -1
+
+#--------------------------
+# Configuration file update
+#--------------------------
+doxygen -u mydoxy.conf >! /dev/null
+rm -f mydoxy.conf.bak
+
+#########################################
+######## Creation de la Makefile ########
+#########################################
+
+rm -f Makefile
+touch Makefile
+chmod +x Makefile
+cat >> Makefile << EOF_
+
+#-------------------------------------------------------
+all: doc sophya pmixer piapp
+
+#-------------------------------------------------------
+clean:
+	rm -rf *.o dox_filter
+	if [ -d ${outdir} ] ; then cd ${outdir}/ ; rm -rf html latex man rtf; fi
+
+#-------------------------------------------------------
+copy: 
+	if [ ! -d ${outdir}/latex ] ; then mkdir ${outdir}/latex; fi
+	cp -p *.tex *.sty *.eps *.inc ${outdir}/latex/.
+
+#-------------------------------------------------------
+doc: filter
+	doxygen mydoxy.conf
+
+#-------------------------------------------------------
+filter: dox_filter
+
+dox_filter : dox_filter.o
+
+dox_filter.o : dox_filter.c
+
+#-------------------------------------------------------
+sophya: copy ${outdir}/latex/sophya.ps
+
+${outdir}/latex/sophya.ps: sophya.tex defsophya.sty blue_sophya_400.eps ex1.inc
+	cd ${outdir}/latex/; \
+	latex sophya.tex; \
+	makeindex sophya; \
+	latex sophya; \
+	dvips -o sophya.ps sophya.dvi
+
+piapp: copy ${outdir}/latex/piapp.ps
+
+${outdir}/latex/piapp.ps: piapp.tex piahelp.tex defsophya.sty
+	cd ${outdir}/latex/; \
+	latex piapp.tex; \
+	makeindex piapp; \
+	latex piapp; \
+	dvips -o piapp.ps piapp.dvi
+
+pmixer: copy ${outdir}/latex/pmixer.ps
+
+${outdir}/latex/pmixer.ps: pmixer.tex
+	cd ${outdir}/latex/; \
+	latex pmixer.tex; \
+	latex pmixer; \
+	dvips -o pmixer.ps pmixer.dvi
+
+EOF_
+
+exit 0
Index: /tags/V_Nov2007/SophyaLib/Manual/modifs.tex
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/modifs.tex	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/modifs.tex	(revision 3445)
@@ -0,0 +1,1470 @@
+\documentclass[twoside,11pt,A4]{article}
+% \documentclass[twoside,11pt,A4]{report}
+\usepackage[french]{babel}
+
+% \usepackage[T1]{fontenc}
+\usepackage[applemac]{inputenc}
+\usepackage{palatino}
+% \usepackage{times}
+% package pour ecrire DRAFT en fond de page 
+% \usepackage[light,all,draft]{draftcopy}
+
+% \usepackage{epsfig}
+\usepackage{graphicx}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\setlength{\textwidth}{16cm}
+\setlength{\textheight}{23 cm}
+\setlength{\topmargin}{0.5cm}
+\setlength{\oddsidemargin}{0.cm}
+\setlength{\evensidemargin}{0.cm}
+\setlength{\unitlength}{1mm}
+
+\newcommand{\rond}{$\bullet \ $}
+\newcommand{\etoile}{$\star \ $}
+\newcommand{\cercle}{$\circ \ $}
+\newcommand{\carre}{$\Box \ $}
+
+%%%% Pour le decoupage en sections
+% \newcommand{\groupe}[1]{\chapter{#1}}
+% \newcommand{\titre}[1]{\section{#1}}
+% \newcommand{\soustitre}[1]{\subsection{#1}}
+%%%
+\newcommand{\groupe}[1]{\section{#1}}
+\newcommand{\titre}[1]{\subsection{#1}}
+\newcommand{\soustitre}[1]{\subsubsection{#1}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{document}
+\begin{titlepage}
+\begin{center}
+{\Large \bf Liste de modifications de SOPHYA } \\[5mm] 
+{\large Septembre 2003 - Novembre  2007 } \\[25mm]
+Liste des tags et dates : \\[5mm]
+{\large 
+\begin{tabular}{lcl}
+V = 0.727 &   \hspace{10mm}  & Octobre 1999 \\
+V = 0.8  &   \hspace{10mm}  &  F\'evrier 2000 \\
+V = 1.1  &   \hspace{10mm}  &  F\'evrier 2001 \\
+V = 1.2  &   \hspace{10mm}  &  Juillet 2001 \\
+V = 1.3  &   \hspace{10mm}  &  Novembre  2001 \\
+V = 1.5  &   \hspace{10mm}  &   D\'ecembre  2002 \\
+V = 1.7  &   \hspace{10mm}  &   Septembre 2003 \\
+V = 1.9  &   \hspace{10mm}  &   Juin 2005 - SANS tag CVS \\
+V = 1.9xx  &   \hspace{10mm}  & 09/2005 ... 09/2006  \\
+V = 2.0  &   \hspace{10mm}  &  Septembre 2006 - tag CVS \\
+V = 2.046  &   \hspace{10mm}  &  Ao\^{u}t 2007 - NO tag  \\
+V = 2.1  &   \hspace{10mm}  &  Novembre 2007 - tag CVS \\
+
+\end{tabular}
+} \\[8mm]
+%%%%%%
+\begin{tabular}{ll}
+R. Ansari            &  ansari@lal.in2p3.fr       \\
+C. Magneville        &  cmv@hep.saclay.cea.fr     
+\end{tabular}
+
+\end{center}
+\end{titlepage}
+
+\newpage
+\tableofcontents
+\newpage
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\groupe{De V2.0 (Sep2006)  V2.1 (Nov2007) }
+\titre{BuildMgr} 
+\begin{itemize}
+\item[\rond] Nov 2007 : configure detecte Linux 64 bits {(\tt -> /usr/X11R6/lib64)}
+et correction bug lors de l'execution de sed pour la creation de sophyamake.inc 
+{\tt AIX, -X 64 }.
+\item[\rond] Oct 2007 : Ajout flag {\tt -alsofftwfloat} au script pour compilation/link
+methodes float (r\_4) de FFTWServer.
+\item[\rond] Avril 2007 :  Amlioration du script configure, qui prend en charge 
+la gestion des diffrents flags de compilation (mis dans fichier machdefs.h gnr
+ou dans sophyamake.inc (pour les flags du compilateur) - Nettoyage du fichier 
+BaseTools/machdefs\_mkmf.h et des fichiers osname\_compilo.inc
+\begin{verbatim}
+csh> cd BuildMgr/
+csh> ./configure -h
+configure [-sbase SOPHYABASE] [-scxx SOPHYACXX] [-incln] 
+  [-minc mymake.inc]  [-compopt 'cc/cxxOptions'] 
+  [-arch64] [-sasz64] [-nofpic] [-nothsafe] [-boundcheck] [-sodebug]
+  [-extp dir1 -extp dir2 ...] [-extip dir1 -extip dir2 ... ] 
+                   [-extlp dir1 -extlp dir2 ... ]
+  [-noextlib] [-noext fits] [-noext fftw] 
+                     [-noext lapack] [-noext astro]
+  [-noPI] [-slballinone]
+  [-usefftw2 -uselapack2] 
+  (See SOPHYA manual/web pages for a detailed description 
+   of configure options)
+\end{verbatim}
+\end{itemize}
+
+%%%%%%
+\titre{BaseTools} 
+\begin{itemize}
+\item[\rond] Novembre 2007 : Ajout de la classe de gnrateur alatoire
+thread-safe {\bf RandomGenerator } - fichiers {\tt stsrand.h .cc} - 
+Ajout du programme {\tt Tests/tmtrnd,3.cc }.\\
+Correction , protection I/O PPF pour NDataBlock de taille nulle.
+\item[\rond] Aout 2007 : Passage numro de version SOPHYA V=2.135 
+ V=2.046 - Les numros V=A.B sont dsormais rservs aux versions 
+avec un tag cvs.
+\item[\rond] Avril 2007 : {\bf ThreadSafe } \hspace{5mm}
+Les oprations de partage de rfrence rendues thread-safe pour les classes 
+{\bf NDataBlock$<$T$>$ , SegDataBlock$<$T$>$, SwSegDataBlock$<$T$>$} 
+\begin{itemize}
+\item Ajout de la classe {\bf ThSafeOp} avec les mthodes {\tt lock() , unlock() } utilisant 
+un mutex. 
+\item Ces mthodes peuvent tre rendues transparentes (sans effet) en activant le flag \\
+{\tt SO\_NOTHSAFE} (option -nothsafe de configure) 
+\item Cette protection / synchronisation semble tre efficace en ce qui concerne les 
+constructeurs de copie et l'extraction de sous-tableaux pour TArray, TMatrix,TVector.
+(programme de vrification Tests/zthr.cc - option sync ).  
+\item En ce qui concerne les classes SegDataBlock , SwSegDataBlock, l'efficacit 
+de la protection n'a pas t teste. Les oprations d'criture sur les DataTable 
+devront aussi  tre protges pour l'utilisation multi-thread.
+\end{itemize}
+\item[\rond] Avril 2007 :  Nettoyage du fichier machdefs\_mkmf.h, suppression des flags 
+de compilation optionnelle MacOS 8.x  9.x / compilo CodeWarrior
+\item[\rond]  Fev 2007 :  Ajout methode NDataBlock::RenewObjId() , et Dealloc() (alias de Delete())
+et correction bug ds SwSegDataBlock::GetCstSegment() 
+\end{itemize}
+
+%%%%%%
+\titre{TArray} 
+\begin{itemize}
+\item[\rond] Oct 07 : Mthode TArray::SumX2() renomme en SumSq(), Norm2() appelle SumSq() sauf pour les tableaux complexes, o on calcule une norme relle positive (Sum[el x conj(el)).
+\item[\rond] Avr 07 : Constructeur de copie et extraction de sous-tableaux rendus thread-safe 
+(voir ci-dessus)
+\item[\rond]  Jan 07 : Ajout classes/methodes de cast de contenu - sans conversion (fichier arrctcast.h)
+\item[\rond]  Fev 07 :  Ajout methode TArray::RenewObjId() (reecriture PPF), et ZeroSize()
+(deallocation tableau / le rendre vierge=sans taille)
+\end{itemize}
+
+%%%%%%
+\titre{HiStats} 
+
+\begin{itemize}
+\item[\rond] Novembre 2007 : Les methodes de remplissage de NTuple {\tt Fill() }
+et de DataTable, SwPPFDataTable {\tt AddRow() }, ainsi que 
+{\tt BaseDataTable::GetRow() } rendues thread-safe. \\
+Activation avec la methode {\tt SetThreadSafe(bool fg=true)  }
+pour chaque NTuple ou DataTable / SwPPFDataTable. Ajout du programme Tests/tmtdt.cc.
+\item[\rond]  Janvier 2007 : Remaniement de la classe HistoErr: elle n'h\'erite plus
+de Histo et devient stand-alone avec des TVector comme support des donne\'ees. \\
+Introduction de la classe Histo2DErr qui fait la meme chose que HistoErr
+mais \`a $2$ dimensions. \\
+Modifs des adaptateurs: NOMAdapter\_Histo ne contient plus HistoErr,
+et NOMAdapter\_HistoErr, NOMAdapter\_Histo2DErr sont cr\'ees dans PIext.
+
+\end{itemize}
+
+%%%%%%
+\titre{SkyMap} 
+
+\begin{itemize}
+\item[\rond]  Aou 2007 :  Correction de signe dans {\tt LocalMap::PixToSphereC()} suite message de
+S. Plaszczynski du 12/07/07
+\item[\rond]  Fev 2007 :  Ajout methode RenewObjId() (reecriture PPF) pour les cartes spheriques 
+et localmap
+\end{itemize}
+
+%%%%%%
+\titre{SysTools} 
+
+\begin{itemize}
+\item[\rond]  Jul 2007 :  Ajout d'acces au temps CPU et elapsed ds la classe Timer - et 
+ajout test specifique dans Tests/tcmd.cc {\tt (tcmd timer)}. \\
+{\tt Timer::TotalElapsedTime() , PartialElapsedTime() , TotalCPUTime() , PartialCPUTime() }
+\end{itemize}
+
+%%%%%%
+\titre{FitsIOServer}
+
+\begin{itemize}
+\item[\rond] Nov 2007 : propagation des modifs BaseDataTable-Thread-safe dans 
+SwFitsDataTable. Mais les SwFitsDataTable NE sont toujours pas thread-safe.
+\item[\rond]  Jan/Fev 2007 :  Passage a la version LONGLONG  ( fits\_xxxll ) permettant 
+la gestion de tailles $ > 2^{32} $
+\end{itemize}
+
+\titre{IFFTW}
+
+\begin{itemize}
+\item[\rond] Nov 2007 : Correction resize tableau de sortie {\tt FFT(complexe -> reel)} multi-dim.
+\item[\rond]  Oct 2007 :  Ajout version float (r\_4) des methodes {\tt FFTForward} et {\tt FFTBackward}
+a la classe FFTWServer. (compilation sous condition et flag -alsofftwfloat du script configure)
+\end{itemize}
+
+%%%%%%
+\titre{PI/piapp}
+\begin{itemize}
+\item[\rond] Novembre 2007 {\bf PIext/ProgPI}: \\
+- Ajout commande de trace d'ellipse d'erreur {\tt errorellipse} \\
+- Axes en degres (0..360, -90..90) pour la projection molleweide et adaptation de la commande {\tt mollgrid}. Suppression de mollgridsph. \\
+- Ajout fonctions tetphi2mollX/Y() et longlat2mollX/Y() ds les fichiers d'expressi
+on ntuple generes par piapp pour trace sur projection de type molleweide. \\
+- Ajout flag [-s] a openppf . openfits/savefits comme alias de readfits/writefits.
+- Verification arret thread Reveil avant destruction de l'objet. 
+\item[\rond] Octobre 2007 {\bf (PI/PIext)}: Ajout methodes de redirection stdout/stderr vers un objet PIConsole, 
+a travers un fichier disque (fichiers PI/piapplx.h .cc) avec possibilite de recopie sur stdout/stderr 
+original (terminal) - en plus d'affichage sur PIConsole. \\
++ Adaptation au niveau de PIext/pistdimgapp.h .cc et ProgPI/piapp.cc \\
++ la redirection passe par les fichiers PIATmp\_xxx/sout.log /serr.log \\
++ le flag (s)piapp -doublered permet la redirection avec recopie sur terminal
+%%%
+\item[\rond] Octobre 2007 {\bf (PIext)}: Correction/protection au niveau de gestion des locks de mutex 
+(classes NamedObjMgr , PIStdImgApp) pour eviter les blocages de l'application sous certaines 
+conditions ( lors de l'affichage de la fenetre de gestion d'objets  et lecture PPF). \\
+Modification des classes NamedObjMgr . ObjMgrWind, la methode 
+{ \tt UpdateObjMgrWindow() } de NamedObjMgr en particulier. \\
+Ajout de la classe {\bf SOpExObj} (ds piacmd.h piacmd.cc) pour executer 
+- de maniere asynchrone - 
+les commandes display,print \ldots  sur les objets, initiees au niveau 
+de la boucle d'evenements (fenetre ObjMgrWind).
+\item[\rond] Octobre 2007 {\bf (PIext)}: Ajout attributs graphiques \\
+{\tt samew=WdgName } specification de widget cible pour trace en superposition \\
+{\tt wname=Nom } Pour specifier un nom de widget (= nom d'objet par defaut) \\
+{\tt inset=fx1,fx2,fy1,fy2 } pour specifier la position du drawer en inset (medaillon)
+\item[\rond] Octobre 2007 {\bf (PIGcont/PIext)}: Codage mthode PIContourDrawer::GetOptionsHelpInfo() pour le traceur de contour. \\
+Ajout accs aux attributs {\tt min max minmax sumsq norm2 } aux niveau des adaptateurs 
+des objets de type TArray, TMatrix, TVector ({\tt \$\{arrName.sumsq\} \$\{arrName.min\} } \ldots).
+\item[\rond]  Aout 2007 {\bf (PI)}: Nouvelles mthodes de calcul de limite de LUT
+dans PIImage (AutoLut) et ajout du dcodage de l'option {\tt autolut=alt[,ns[,minp,maxp]]}.
+Si {\tt minp,maxp} spcifis, seuls les pixels entre {\tt minp <= pixval <= maxp} 
+sont utiliss pour le calcul des limites.
+\begin{verbatim}
+  autolut=minmax,frac   Fraction de la dynamique totale
+  autolut=meansig,ns   min=mean-ns*sigma , max=mean+ns*sigma
+  autolut=histail,ns   Queue de l'histo des pixels 
+  autolut=hispeak,ns  Pic de l'histo des pixels
+\end{verbatim}
+%
+\item[\rond]  Aout 2007 {\bf (PI)}:  Contournement d'un problme d'venements X expose 
+perdu - apparu avec des versions rcentes du serveur XFree ou le serveur X sur Linux
+ou une combinaison des deux. Rsultat, contenu non affich lors d'une cration de fentre
+suivi d'un ajout de PIBaseWidget (sauf PIImage) et plantage lors du click dans la fentre.
+Correction: Ajout de {\tt XFlush() + usleep(5000)} (5 $\mu$s). 
+\item[\rond]  Juin 2007 {\bf (PI/PIext)}:  Ajout des mthodes 
+{\tt PIGraphicAtt::ColNameToColor() , ColIndexToColor()} et possibilit d'utiliser le contenu
+d'une colonne d'une table comme nom de couleur ou numro de couleur pour le trac
+des markers par PINTuple {\tt PINTuple::SelectColorByName() , SelectColorByIndex()}.
+Ajout des commandes {\bf nt2dcn} et {\bf nt2dci}  et {\bf plot2dc}  ds piapp. 
+\item[\rond]  Avril 2007 {\bf (PI)}:  La source des problmes sur MacOS/PowerPC (G4/G5)
+et AIX (architecture Power) a finalement t identifi et corrig/
+Parmi ces problmes:  des pull-down menus mal placs (MenuBar), ou encore des 
+dysfonctionnement de boutons dans les fentres de dialogues. \\
+Source et correction: \hspace{5mm} {\tt XtMoveWidget / XtResizeWidget} remplac par \\
+\hspace*{10mm} {\tt XtMakeGeometryRequest}   
+\item[\rond]  Avril 2007 {\bf (PIext/piapp)}: 
+\begin{itemize}
+\item Ajout de la classe {\bf NOMAdapter\_DVList}
+pour la prise en charge des objets DVList. 
+Accs aux variables par {\tt \$\{dvlName.varName\} } 
+\item Accs  l'objet DVList attach aux TArray, TMatrix, DataTable et NTuple par \\
+\hspace*{5mm}  {\tt \$\{objName.info.varName\} }
+\item L'adaptateur de DataTable permet aussi d'accder aux lignes de la table par \\
+\hspace*{5mm} {\tt \$\{tableName.row.num\} }
+\item Prise en charge de la classe {\tt Image<T>} par l'adaptateur des matrices 
+{\tt NOMAdapter\_TMatrix<T> } au lieu de l'adaptateur spcifique 
+{\tt NOMAdapter\_Image<T>  }
+\end{itemize}
+\item[ \rond] Janvier 2007  {\bf (PIext)}:  modification des trac\'es des histogrammes PIHisto.
+La classe PIHisto prend en entr\'ee un wrapper P1DHistoWrapper.
+Les wrappers HistoWrapper et HistoErrWrapper sont cr\'ees.
+Ainsi les HistoErr peuvent \^etre dessin\'es sous forme d'histogrammes.
+Mise en place des options graphiques permettant de dessiner les
+valeurs (``val''), erreurs (``err'') et le nombre d'entr\'ees par bin (``nb'')
+pour les HistoErr. Idem pour les versions $2$ dimensions.
+\end{itemize}
+
+%%%%%%%%
+\titre{Documentation (Manual/) } 
+\begin{itemize}
+\item[\rond]  Jan 2007 :  Ajout fichier de mesure de performances comparees entre 
+differentes processeur / OS / compilateur {\tt perfmachine.txt }
+\end{itemize}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\groupe{De V1.7 (Sep2003)  V2.0 (Sep2006) }
+\titre{BuildMgr} 
+\begin{itemize}
+\item[\rond] Juin 2006 :  Ajout targets cleanobj prgall tests prgutil
+\item[\rond] Avril 2006 :  suppression de libextsophya.so pour fabriquer libPI.so 
+(PIext rendu independant de FitsIOServer) 
+\item[\rond] Dec 2005/Jan 2006 :  Portage sur AIX - xlC 
+\item[\rond] Dec 2005 : check Compil avec icc , compil avec gcc-4
+\item[\rond] Avril-Mai 2005 : Introduction de la nouvelle version de
+scripts de gestion du code - avec un script principal configure. \\
+Variable d'environnement {\bf SOPHYABASE } - \\
+Pour les makefiles, l'ensemble des dfinitions se trouve dans : \\
+SOPHYABASE/include/sophyamake.ic \\
+\end{itemize}
+
+%%%%%%
+\titre{BaseTools} 
+
+\soustitre{Modifs} 
+
+\begin{itemize}
+\item[\rond] Jun/Jul 2006 : Amelioration gestion initialiseur modules \\
+- Ajout methodes statique  {\tt RegisterModule(const char* name, double version)
+ListModules(ostream\& os) } a la classe de base SophyaInitiator. \\
+- Enregistrement des modules avec leur nom et un numero de version par module,
+independante du numero de version SOPHYA \\
+- le programme scanppf peut donner la liste des modules enregistrees et leur numero 
+de version. 
+\item[\rond] Octobre-Novembre 2005 :  \\
+1/ Correction bug TimeStamp::ToDays() + petites amelioration \\
+2/ Prise en compte du type TimeStamp dans MuTyV (sous forme de double en interne) \\
+3/ Adaptation DVList a modifs MuTyV (typ TimeStamp) et R/W PPersist \\
+4/ Gestion format YYYY-MM-DDThh:mm:ss par TimeStamp \\
+5/ Gestionnaire PPersist pour TimeStamp
+%
+\item[\rond] Septembre 2004 - {\bf Namespace SOPHYA } \\
+Suppression de {\tt using namespace SOPHYA ; } ds machdefs.h - 
+Ajout fichier {\tt \#include "sopnamsp.h"} dans les .cc de SOPHYA,
+ainsi que lors de la gnration automatique du code (runxx, c++exec) 
+\end{itemize}
+ 
+\soustitre{PPF}
+\begin{itemize}
+\item[\rond] Avril 2005 - Ajout de wrapper de lecture/ecriture PPF pour les vecteurs de
+la librairie standard (classe PPFWrapperSTLVector$<$T$>$ ) fichier ppfwrapstlv.h
+\item[\rond] Ajout de la classes utilitaire PPF\_TPointer\_IO$<$T$>$ 
+(fichiers ppftpointer.h .cc)
+\item[\rond] Amelioration de l'impression ds AnalyseTags (ppfbinstream.cc)
+\item[\rond] scanppf.cc revision 1.8 (2005/04/05)
+modification programme scanppf: ajout option -lh -lho pour lister les classes PP
+ersist handler
+\item[\rond] Dcembre 2003 (9/12/2003) Fin de l'ensemble des modifs pour les
+PPF V3 \\
+- Ecriture nombre complexes r4, r8 avec tag spcifique. \\
+Tag de positionnement sous forme de \\
+\centerline{\tt <tag (1 byte)><FilePosition (8 byte, long int)> } \\
+- Ecriture PosTagTable \\
+- Ecriture Statistiques en fin de fichier \\
+- Voir BaseTools/ppfbinstream.h: \\
+\centerline{\tt  GotoPositionTag(int\_8 pos) , } 
+\centerline{\tt  GetPosTagTable(...) } 
+\centerline{\tt  int\_8 WritePositionTag() PutPosTagTable(...) } 
+- Ajout programme de test Tests/ppftswap.cc
+\item[\rond] Dcembre 2003 - Ajout ppfbinstream.h .cc \\
+Classes PPFBinaryIOStream , PPFBinaryInputStream , PPFBinaryOutputStream
+\item[\rond] Novembre 2003 (21/11/2003) - Ajout rawstream.h .cc \\
+Classes RawInOutStream  ,  RawInFileStream , RawOutFileStream
+
+\end{itemize}
+
+
+\soustitre{Nouvelles classes}
+\begin{itemize}
+\item[\rond] Ajout de la classe {\bf TimeStamp} pour la manipulation de date et heure - 
+calcul de duree. - Ajout du prog. test Tests/ttimestamp.cc (Mars 2005) 
+\item[\rond] { \bf Segmented Data Block :}  \\
+Mars-Avril 2005: Introduction des classes similaires aux NDataBlock, mais permettant 
+de gerer des blocs de donnees segementes, pour tout type de donnees, de structures
+et de classes (template pour tout type T). 
+\begin{enumerate}
+\item  Ajout de la classe {\tt SegDataBlock<T>} (et l'interface { \tt SegDBInterface<T>} )
+pour la gestion de blocs de donnees segmentes (segdatablock.h) et son
+gestionnaire PPF {\tt FIO\_SegDataBlock<T>}  (fichier fiosegdb.h )
+\item Ajout de la classe {\tt SwSegDataBlock<T>} (Data bloc segmente avec gestion
+de swap) et la classe swapper PPF {\tt PPFDataSwapper<T>} (fichiers
+ppfswapper.h et swsegdb.h)
+\item Ajout programme de test Tests/tstsegdb.cc 
+\end{enumerate}
+\end{itemize}
+
+%%%%%
+\titre{TArray}
+%%
+Il s'agit essentiellement des ameliorations en terme de performances et 
+de correction d'erreur. 
+
+\begin{itemize}
+\item[\rond] Avril 2006  \\
+- Instanciation explicite des tableaux , matrices et vecteurs en types \\
+{\tt int\_2 uint\_2 uint\_4 uint\_8 } \\
+- Optimisation du code (ds tarray.cc) des operations sur tableaux  \\
+{\tt (TArray::Add/Mul/Sub/DivCst  TArray::Add/Mul/Sub/DivElt ) } \\ 
+a travers le  choix entre Share() ou Allocation si le tableau resultat est non alloue. 
+D'apres les tests de performances (TCPU), {\bf (tjet , spar)}, il ne semble pas y 
+avoir de cas de pertes, et on a en general des gains de l'ordre de 20\% dans la plupart 
+des cas de tests,  et un ou deux cas avec des gains de 50-80\%. \\
+- Declaration de l'operateur / entre tableaux (DivElt) et l'operateur \& \& pour la 
+multiplication element par element (MulElt)   
+\item[\rond] Janvier, Fvrier 2006  \\
+- Amlioration des fonctionalits de la classe {\bf Range} et  des mthodes d'extraction
+de sous-tableaux (+ correction bugs et amlioration documentation) \\ 
+- Ajout de la methode BaseArray::ValueAtPositionDB() pour corriger un gros bug au 
+niveau de la conversion de type (r\_4 r\_8 ...) des tableaux \\
+- Compil avec g++ 4 : ajouts fichiers declarations privees tmatrix\_tsnl.h tvector\_tsnl.h 
+
+\item[\rond] Juillet 2004 \\
+- Optimisation de la multiplication matricielle (CMV) - Extrait du 
+message (from CMV) du 30 Juillet 2004: \\
+\begin{verbatim}
+- on definit un flag d'optimisation
+  Contrairement a ce qu'on avait dit, je n'ai pas ajoute
+  un argument a Multiply car on ne peut pas jouer
+  avec qiand on utilise l'operateur * surcharge.
+  Or au vu des performance il'ma parut interessant que l'utilisateur
+  meme lambda puisse choisir le niveau d'optimisation
+  --> donc j'ai ajoute une methode statis dans BaseArray::
+    void BaseArray::SetMatProdOpt(uint_2);
+    uint_2 BaseArray::GetMatProdOpt();
+
+- Je n'ai refait les test de rapidite que sur OSF:
+
+1./  pour les matrices 1000x1000 (grosses)
+  on arrive effectivement au meme temps pour les 4 cas
+  si on copie dans le cas lent (FxC)
+  ---EndMultiply FxC  CPUTime: Total= 93.1296  (Partial= 69.3806) Sec.
+  devient
+  ---EndMultiply FxC  CPUTime: Total= 34.9653  (Partial= 11.1829) Sec.
+  exactement comme les copains:
+  La copie prend de la place mais ne prend absolument
+  pas de temps pour les grosses matrices
+
+2./ pour les matrices 10x10 (1000000 multiplications par cas)
+  on a bien ce que l'on attend a savoir que
+  la copie faites 100000 fois finie par nous faire perdre du temps
+  ---EndMultiply FxC  CPUTime: Total= 37.4152  (Partial= 12.4662) Sec.
+  devient
+  ---EndMultiply FxC  CPUTime: Total= 53.9978  (Partial= 28.8322) Sec.
+  dans ce cas on perd un gros facteur 2 a cause de la copie
+  mais rien de surprenant la dedans.
+
+-----------------------------------------------------------------------
+- ensuite j'ai implemente une prise de decision au niveau de
+l'optimisation pour les petites matrices:
+le test est simple mais me semble OK:
+je calcule sza taille du NDataBlock de A
+           szb                         B
+si ((sza+szb)*sizeof(T) < 100000 ) pas d'optimisation
+IDEE: on pifometre que raisonnablement il y a 100 koctets
+   de disponible pour les matrices A et B dans le cache processeur
+   et que dans ce cas elles sont copiees toutes les 2 dans le cache
+   par l'optimiseur du compilo qui est tres malin et surtout qui
+   veux absolument nous faire plaisir......
+
+-----------------------------------------------------------------
+===> Les resultats sont dans le fichier toto.calc en attached
+.. En tete tu as l'explication des flags d'optimisation
+...Avec les 2 sections:
+    GROSSE MATRICE
+       et
+    PETITE MATRICE
+\end{verbatim}
+
+\item[\rond] Juillet 2004 : Optimisation operations diverses, en particulier \\
+1) Remplacement des methodes Add/Sub/Mul/DivElt(a) par
+   Add/Sub/Mul/DivElt(TArray a, TArray res) \\
+2)  Operateurs += -= A+B A-B TArray et TMatrix/TVecteur modifies en consequence
+\item[\rond] Extrait de {\tt cvs log tarray.cc } 
+{\small \begin{verbatim}
+----------------------------
+revision 1.38
+date: 2004/07/30 13:31:39;  author: ansari;  state: Exp;  lines: +28 -24
+Diverses petites optimisations ds les methodes operations/affectations de TArray - Reza 30 Juillet 2004
+----------------------------
+----------------------------
+revision 1.36
+date: 2004/07/27 11:44:23;  author: ansari;  state: Exp;  lines: +4 -1
+Corrections bug apres modifs methods Add/Sub/Mul/DivCst(x,res) - Reza 27 Juillet 2004
+----------------------------
+revision 1.35
+date: 2004/07/26 17:30:40;  author: ansari;  state: Exp;  lines: +187 -108
+Remplacement methodes Add/Mul/Sub/Div(T x) par AddCst/MulCst/SubCst/DivCst(T x, TArray<T> res) ds TArray - Reza 26 Juillet 2004
+----------------------------
+\end{verbatim} }
+
+\item[\rond] Extrait de {\tt cvs log tarray.cc } 
+{\small \begin{verbatim}
+----------------------------
+revision 1.27
+date: 2004/07/30 10:24:12;  author: cmv;  state: Exp;  lines: +97 -32
+- Intro decision auto d'optimisation produit de matrices
+- Possibilite a l'utilisateur pour choisir l'optimisation
+- cas FxC optimise par copie
+                cmv 30/07/04
+----------------------------
+revision 1.26
+date: 2004/07/29 12:31:16;  author: ansari;  state: Exp;  lines: +7 -5
+1/ Remplacement des methodes Add/Sub/Mul/DivElt(a) par
+   Add/Sub/Mul/DivElt(TArray a, TArray res)
+2/ Operateurs += -= A+B A-B TArray et TMatrix/TVecteur modifies en consequence
+3/ Ajout methode TArray::ScalarProduct()
+4/ Methode TArray::SetT renomme en SetCst() SetT garde en alias
+5/ Ajout parametre bool fzero (mise a zero) ajoute ds constructeur et
+   ReSize() de TMatrix et TVecteur.
+                                          Reza 29/07/2004
+----------------------------
+revision 1.25
+date: 2004/07/29 08:40:49;  author: cmv;  state: Exp;  lines: +148 -1
+Optimisation produit de matrice a la sauce cmv 29/07/04
+----------------------------
+\end{verbatim}  }
+
+\end{itemize}
+
+
+%%%%%%%%
+\titre{HiStats} 
+%%%%%
+\soustitre{Classe Histo,HProf,HistoErr,Histo2D } 
+\noindent
+- Aout 2006 : refonte profonde des allocations memoire et delete de
+ Histo,HProf,HistoErr,Histo2D pour faciliter la gestion des IO FITS. \\
+- Sept 2004 : Ajout classe HistoErr. 
+C'est un Histo qui garde le nombre d'entr\'ees dans chaque bin) \\
+\soustitre{NTuple}
+la classe NTuple peut maintenant avoir des colonnes float ou double.
+Il y a maintenant deux methodes Fill(r\_4 *) et Fill(r\_8 *)
+Les noms ne sont plus limites a 8 caracteres.
+
+
+\soustitre{ Les DataTable (SuperNTuple) }
+
+{\bf Octobre-Novembre 2005 } \\
+\begin{itemize}
+\item[\rond] Ajout classe {\bf DataTableRow} pour manipulation d'une ligne de la table.
+Ajout/maj methode BaseDataTable::EmptyRow() AddRow() GetRow() 
+\item[\rond] Gestion des types {\tt complex<r\_4>  ,   complex<r\_8>  , TimeStamp } par 
+BaseDataTable, DataTable et SwPPFDataTable
+\item[\rond] Codage methode Print() (Dump ascii) et NTFrAscii (decodage fichier 
+text) dans BaseDataTable. 
+\item[\rond] Codage mthode BaseDataTable::GetColumnD() pour recuperer
+une colonne de la table en {\tt TVector<r\_8>} - NON TESTE 
+\end{itemize}
+
+\begin{verbatim}
+BaseDataTable                                    
+              --------  DataTable
+              --------  SwPPFDataTable
+\end{verbatim}
+
+\noindent {\bf BaseDataTable} : Classe de base, avec qques methodes virtuelles
+pures, implementent la presque totalite des fonctionalites, en particulier
+celles de l'interface NTupleInterface.
+
+\noindent {\bf DataTable} : Implementation concrete de BaseDataTable avec donnees en 
+memoire \\ 
+(utilise SegDataBlock$<$T$>$ pour stocker les colonnes)
+
+\noindent {\bf SwPPFDataTable} : Implementation concrete de BaseDataTable avec donnees 
+en swap sur stream PPF (POutPersist)- \\ 
+Utilise  (SwSegDataBlock$<$T$>$ avec 
+un data-swapper PPF (classe PPFDataSwapper$<$T$>$ ) 
+
+DataTable et SwPPFDataTable respecte +/- les conventions SOPHYA , 
+constructeur de copie avec partage ou copie de donnees, operateur = 
+Datatable : partage et copie , = : fait une copie
+SwPPFDataTable : C'est toujours partage (presque par definition)
+Autre point, compte tenu de la structure des streams PPF , 
+les SwPPFDataTable fonctionne en ecriture OU en lecture, mais
+pas les deux a la fois. 
+
+Classe de gestion de persistence commune : \\
+{\bf ObjFileIO$<$BaseDataTable$>$ }
+
+Lit et ecrit les DataTable et SwPPFDataTable
+Actuellement, on ne peut les relires que dans le meme type,
+cad on ne peut relire avec un SwPPFDataTable un objet 
+ecrit comme DataTable - mais cette possibilite pourra 
+peut-etre codee ulterieurement (d'ou l'interet en particulier 
+d'un gestionnaire commun ObjFileIO$<$BaseDataTable$>$
+
+(les operateurs habituel $<<$ et $>>$ sur PIn/OutPersist sont definies)
+
+
+Les merges et copie sont prevues, 
+on doit en principe pouvoir ecrire par exemple:
+\begin{verbatim}
+SwPPFDataTable swdt;
+PInPersist pis("swdt.ppf");
+pis >> swdt;
+DataTable dt;
+dt = swdt;  // Pour tout charger en memoire 
+\end{verbatim}
+
+{\it On pourra aussi ajouter des methodes d'acces aux variables 
+membres pour enrichier l'interface. }
+
+
+{\bf DataTable cote PIAPP :} \\ 
+Cote piapp, les DataTable et SwPPFDataTable  sont pris en charge par 
+{\tt NOMAdapter\_DataTable} (qui prend en charge tous les 'BaseDataTable' )
+Il faudrait peut-etre rajouter deux commandes : \\
+newdt ou newdatatable 
+newdt ncol col1 [col2 .... ]  \\
+avec possibilite de specifier coli sous fome de X:colname ou X = D,F,S,I,L ...
+et puis dtfromascii  ...
+
+Voir Tests/tnt.cc pour exemple d'utilisation :
+\begin{verbatim}
+DataTable dt(64);
+dt.AddIntegerColumn("line");
+dt.AddDoubleColumn("x");
+dt.AddFloatColumn("f_sin");
+MuTyV rec[10];
+for(int k = 0; k<1000; k++) {
+  rec[0] = k;
+  double x = M_PI*k/100.;
+  double fx = sin(x)*cos(x);
+  rec[1] = x;
+  rec[2] = sin(x);
+}
+ POutPersist po("dtable.ppf");
+ po << dt;
+\end{verbatim}
+
+Pour SwPPFDataTable, il faut juste creer un stream PPF avant, qui doit rester
+ouvert tant que le SwPPFDataTable est actif: \\
+\begin{verbatim}
+ POutPersist po("swdtable.ppf");
+ SwPPFDataTable dt(po, 64);
+\end{verbatim}
+
+
+
+\titre{SkyMap} 
+%%%
+\begin{itemize}
+\item[\rond] Juin 2006: Prise en charge du rangement mmoire {\bf NESTED} dans 
+les SphereHEALPix , + I/O PPF et FITS
+\item[\rond] Juin 2006:  Nettoyage et amliorations diverses dans les classes 
+Vector3d, UnitVector, LongLat \ldots et les cartes sphriques, en particulier : 
+\begin{enumerate}
+\item Nettoyage/uniformation mthodes  {\tt Print()}  des cartes, et 
+ ajout de la mthode {\tt Show()} dans PixelMap 
+ \item Ajout mthodes {\tt HasSymThetaSlice() , GetSymThetaSliceIndex() }
+ dans les cartes sphriques (SphericalMap) 
+ \item Ajout methode {\tt ResolToSizeIndex() SizeIndexToResol() } 
+ ds SphereThetaPhi , SphereHEALPix et SphereECP
+ \item Petites optimisations dans {\tt GetThetaSlice()} + methode {\tt GetThetaSliceDataPtr() }
+ \end{enumerate}
+\item[\rond] Juin 2006: Introduction de la classe {\bf Angle}  - pour conversion d'angle. 
+\begin{verbatim}
+   // Example to convert 0.035 radians to arcsec
+   double vr = 0.035;
+   cout << "Angle rad= " << vr << " ->arcsec= " << Angle(vr).ToArcSec() << endl;
+   // Example to convert 2.3 arcmin to radian - we use the conversion operator
+   double vam = 2.3;
+   cout << "Angle arcmin= " << vam << " ->rad= " 
+        << (double)Angle(vam, Angle::ArcMin) << endl;
+\end{verbatim} 
+%
+
+
+\item[\rond]  {\bf SphereECP} - Septembre 2004 \\
+Extrait du message du 7 Septembre 2004 
+\begin{verbatim}
+ J'ai mis dans la base (module SkyMap) le code de la classe
+SphereECP<T> (pixelisation avec projection cylindrique) - carte partielle et complete,
++ gestionnaire PPersist + modifs adaptateur NomSkyMapAdaptor (PIext/ spiapp)
+
+Programme test (avec appel a transforme en Alm) ds Test/tsphereecp.cc
+Attention, mettre le parametere de pixelisation a -1 lors de l'appel a Generate pour eviter
+le Resize de la sphereECP
+ylmserver.GenerateFromCl(map, -1,  clin, 0.);
+
+Dans piapp, c'est visualise par defaut en projection Molleweide
+On peut ajouter dans les options d'affichage :
+ecparray : affichage direct du tableau TArray des pixels (X:Phi, Y:Theta)
+Si option ecparray, on peut preciser en plus
+     - ecpscaledeg: echelle des axes en degres au lieu de pixels
+     - ecpscalerad: echelle des axes en radians au lieu de pixels
+Exemple:
+Cmd> disp mapecp 'ecparray ecpscaledeg zoomx2 stdaxes'
+\end{verbatim} 
+
+\item[\rond]  Bug non corrig ds classe Circle 
+\begin{verbatim}
+From: Laurence Perotto <perotto@cdf.in2p3.fr>
+Date: Mon Jan 5, 2004  4:59:12 PM Europe/Paris
+To: Reza Ansari <ansari@lal.in2p3.fr>, Christophe Magneville <cmv@hep.saclay.cea.fr>
+Subject: un bug dans sophya...
+
+    Bonjour et bonne annee a tous les deux...
+
+    Je viens de trouver un ptit bug dans la fonction TanOnCircle de la classe Circle: Il
+s'agit d'un melange entre les coordonnees (beta, lambda) de Benoit et les (theta, phi)
+utilises dans Sophya. Lors du passage de l'un a l'autre, une transfo sin->cos a ete
+oubliee...
+    Voila...
+    Bonne journee.
+
+    Laurence.
+\end{verbatim} 
+\end{itemize}
+
+\titre{Samba }
+
+\begin{itemize}
+\item[\rond] {\bf Juin 2006:} correction bug de calcul $a_{lm} \rightarrow$ SphereHEALPix 
+(zones polar cap): le problme venant du choix de taille lors du calcul de la transform
+de Fourier complex $\rightarrow$ rel (n/2 - 1 ou n/2 -2) .
+Correction dans {\tt RfourierSynthesisFromB } et utilisation de cette mthode
+pour tout type de carte.
+On gagne un peu encore en temps de calcul - sur asc (OSF1-cxx) , avec 
+SphereThetaPhi(m=400), $l_{max} = 511$ \\[2mm]
+\begin{tabular}{|l|c|c|}
+\hline
+Opration & TCPU Avant & TCPU Aprs OPT \\
+\hline
+map $\rightarrow a_{lm}$ & 10 s & 3.6 s. \\
+$a_{lm} \rightarrow$ map & 26 & 10.5 s. \\
+\hline
+\end{tabular}  \\[1mm]
+%
+\item[\rond] {\bf Mai 2006:}  Optimisation calcul transform en harmoniques sphriques 
+{\bf SphericalTransformServer}. \\
+Au lieu de calculer un tableau de $\lambda_{lm}$ dans LambdaLMBuilder 
+et utiliser ensuite ce tableau, on calcule les sommes ncessaires au vol,
+dans des mthodes spcifiques de la classe LambdaLMBuilder qui 
+sont utilises dans SphericalTransformServer (pour les transforms
+scalaire/temprature) - PAS fait pour la polarisation pour le moment.
+On peut encore gagner un facteur 2 en utilisant la symtrie 
+en $\theta <> \pi-\theta$. \\ 
+Extrait de cvs log :
+\begin{verbatim}
+revision 1.8
+date: 2006/06/01 11:34:50;  author: ansari;  state: Exp;  lines: +147 -12
+1/ passage en sa_size_t (au lieu de int) dans Alm<T> et Bm<T>
+2/ Ajout des methodes optimisees (statiques) pour calcul transforme Ylm
+ds LambdaLMBuilder et utilisation ds SphericalTransformServer
+                             Reza , 1/06/2006
+\end{verbatim}
+
+\item[\rond] {\bf Fin 2004} : Tests et vrifications des polynomes de Legendre.
+La classe LambdaLMBuilder donne les bons r\'esultats mais calcule les Plm
+pour tous les $l,m$.
+Introduction d'une routine (C-like) ``HarmSph\_array\_teta'' qui calcule
+les Plm pour $m$ fix\'e et $l\in [0,l_{max}]$ comme ce qui est fait
+dans la GSL... (la routine GSL ne marche pas corectement).
+\end{itemize}
+
+%%%%%%%%%%%
+\titre{SysTools} 
+{\bf Mai-Juin 2006 } classe ZThread - petites modifs/amliorations lies
+ la gestion des signaux et mthodes kill 
+
+\soustitre{Classe SOPHYA::Commander (module SysTools) }
+Mai-Juin 2006:
+Debug (?) de gestion/controle des threads dans la classe Commander - 
+Extrait de cvs log : 
+\begin{verbatim}
+date: 2006/05/29 17:27:35;  author: ansari;  state: Exp;  lines: +62 -11
+Ajout gestionnaire signal ds ZThread et correction/adaptation gestion des thread
+s (killthr) dans Commander - Reza 29 mai 2006
+----------------------------
+revision 1.7
+date: 2006/04/26 15:22:09;  author: ansari;  state: Exp;  lines: +13 -0
+ajout methode ZThread::kill() pour envoi de signal a un thread + remplacement Ca
+ncelThread par StopThread (par kill/SIGUSR1) dans Commander (commander.cc) + ame
+----------------------------
+revision 1.22
+date: 2006/05/31 12:30:13;  author: ansari;  state: Exp;  lines: +20 -11
+correction gestion & pour ThrExec ds Commander - Reza 31/05/2006
+----------------------------
+revision 1.21
+date: 2006/05/29 17:27:35;  author: ansari;  state: Exp;  lines: +37 -16
+Ajout gestionnaire signal ds ZThread et correction/adaptation gestion des thread
+s (killthr) dans Commander - Reza 29 mai 2006
+----------------------------
+revision 1.20
+date: 2006/04/26 15:22:08;  author: ansari;  state: Exp;  lines: +55 -15
+ajout methode ZThread::kill() pour envoi de signal a un thread + remplacement Ca
+ncelThread par StopThread (par kill/SIGUSR1) dans Commander (commander.cc) + ame
+lioration documentation , Reza 26/4/2006
+
+\end{verbatim}
+
+Mars-Avril 2004 : 
+Classe d'interprteur de ligne de commande inspire de C-Shell,
+destine a etre incluee dans des applications C/C++. \\
+( Programme test Test/tcmd.cc )  \\
+Avril 2005 : Introduction de la possibilite d'execution de commandes
+en multithreads \\
+Avril 2005 : Controle strict sur les noms de variables, limites
+aux caracteres alphanumeriques + underscore - Adaptation
+de l'algorithme de substitution en consequence.
+
+{\bf Mini guide de l'interpreteur - Message du 19 Mars 2004 }   \
+
+\begin{itemize}
+
+\item[\rond] {\bf Gestion des variables } \\
+ - Les variables sont non typees toutes traitees comme des chaines 
+de caracteres. 
+ - Acces aux variables d'environnement - 
+ - Un niveau variable d'environnement application est aussi prevu
+ - Toutes les variables de l'interpreteur  sont traitees comme des vecteurs.
+extensibles automatiquement (difference avec le C-Shell) 
+
+\item[\rond] {\bf Creation / initialisation de variables }  \\
+\begin{verbatim}
+Cmd> set sv StringValue
+# Suppression d'une variable : unset ou clearvar 
+Cmd> unset sv 
+
+# Initialisation de type vecteur - Espace avant/apres ')' et avant ')' obligatoire
+Cmd> set vecv ( mot1 mot2 mot3 mot4 mot5 )
+#Calcul numerique : expression de type C  - Espace avant/apres '=' obligatoire
+Cmd> a = 2+3*sqrt(4)
+# Le signe egal peut etre utilise pour attribuer une chaine de caracteres
+Cmd> a = 'Bonjour Madame'
+# Un element de tableau peut etre specifie avant le signe egal 
+Cmd> vecv[2] = 'coucou'
+# Ou bien 
+Cmd> i = 3
+Cmd> vecv[i] = 'Ooohhh' 
+\end{verbatim}
+
+A droite du signe egal (membre de droite), les variables doivent etre
+adressees a l'aide du signe \$.  
+
+Une chaine peut etre cassee en mots a l'aide de la commande var2words
+\begin{verbatim}
+Cmd> var2words varname wordvarname [separateur]
+\end{verbatim}
+
+\item[\rond] {\bf Acces aux variables } \\
+L'acces aux variables s'effectue par le signe \$  {\tt \$varname} .
+Les {\tt \$xxx} sont remplaces par le contenu de la variable xxx. 
+Cette substitution ne s'effectue pas entre simple quotes {\tt ' ... \$xxx '},
+mais se fait entre double quotes {\tt " ... \$xxx ... "} . Les formes
+{\tt \${vname} } ou {\tt \$(vname)} peuvent etre utilisees.
+
+\begin{verbatim}
+Cmd> x = 'Hello'
+Cmd> echo $x
+# Taille d'une variable de type vecteur $#vname
+Cmd> set vx ( 111 2222 3333 444444 )
+Cmd> echo $#vx 
+# Acces aux elements de tableau
+Cmd> echo $vx[0] $vx[1] 
+#  ou bien indexe par une variable 
+Cmd> i = 2
+Cmd> echo $vx[i] 
+# Une syntaxe particuliere: $[vname] retourne le contenu de
+# la variable dont le nom est ds vname 
+Cmd> zzz = 'Commander'
+Cmd> xxx = 'zzz'
+Cmd> echo '$[xxx]= '  $[xxx]
+$[xxx]= Commander
+\end{verbatim}
+
+Variables d'environnement: L'acces aux variables d'environnement 
+se fait simplement par{\tt \$varenvname}. Attention, les variables locales
+de l'interpreteur sont prioritaires.
+
+\item[\rond] {\bf Variables particulieres: } \\
+{\tt \$retval} ou {\tt \$retstr}  :  chaine specifee sur la derniere commande return 
+{\tt \$status} : code de retour de la derniere commande executee.
+(variable existe et est rempli - mais il faudra se donner une regle 
+plus claire ...)
+Arguments des fichiers .pic appeles par la commande exec 
+{\tt \$\# } : nombre d'arguments, a part \$0 
+{\tt \$0} nom du fichier ou du script 
+{\tt \$1 \$2 \$3} .... les arguments  (pour les scripts et les .pic (exec))
+
+ 
+\item[\rond] {\bf Structures de controle  } \\
+\begin{verbatim}
+foreach f ( w1 w2 w3 ... )
+  ...
+  echo $f
+end
+\end{verbatim}
+
+Espace avant/apres '(' et avant ')' obligatoire.
+
+\begin{verbatim}
+foreach v vecname 
+  ...
+  echo $v
+end
+\end{verbatim}
+
+Boucle de type integer:
+\begin{verbatim}
+for i  startInt:endInt[:stepInt]
+  ....
+  echo $i 
+end
+\end{verbatim}
+
+Boucle de type float
+\begin{verbatim}
+for f  startFloat:endFloat[:stepFloat]
+  ....
+  echo $f
+end
+\end{verbatim}
+
+Boucle sur les lignes d'un fichier:
+\begin{verbatim}
+forinfile line FileName
+  ...
+  echo $line
+end
+\end{verbatim}
+
+Instruction {\tt break} pour casser une boucle
+
+\item[\rond] {\bf Les tests  }
+\begin{verbatim}
+if ( test ) then 
+endif
+
+if ( test ) then
+ ....
+else
+ .... 
+endif
+\end{verbatim}
+
+Espace avant/apres '(' et avant ')' obligatoire.
+
+test de type {\tt a == b} OU {\tt a != b} OU {\tt a < b}  OU {\tt a > b} 
+OU {\tt a <= b} OU {\tt a >= b}
+les espaces avant l'operateur de comparaison sont obligatoires.
+{\tt ==} et {\tt !=}  effectue une comparaison de chaines de caracteres.
+{\tt < , > , <= , >=}une comparaison apres conversion en valeur flottante.
+
+\item[\rond] {\bf Definition de script } \\
+\begin{verbatim}
+defscript scriptname  [description ]
+   ....
+endscript 
+\end{verbatim}
+
+L'appel a un script se fait simplement a l'aide
+du nom de script (contrairement aux fichiers
+de commande qui sont executes a l'aide de la 
+commande {\tt exec} )
+\begin{verbatim}
+Cmd> scriptname arg1 arg2 arg3 ....
+\end{verbatim}
+
+L'instruction {\tt return} provoque l'arret (et le retour) d'execution d'un
+script ou d'un fichier de commandes.
+Commandes {\bf listscript }et {\bf clearscript scriptname} 
+ permettet d'avoir la liste des scripts 
+ definis / supprimer la definition d'un script 
+
+\item[\rond] {\bf Autres commandes}
+\begin{itemize}
+\item Instruction {\bf echo } pour ecrire sur cout/stdout
+\item Instruction {\bf echo2file} pour ecrire a la fin d'un fichier
+\item Instruction {\bf sleep nsec} (attente de nsec seconds )
+\item Instructions {\bf timingon , timingoff , traceon , traceoff } \\
+%
+\item Commande {\bf exec commandfilename [arg1 arg2 ... ] }
+\item Commandes {\bf help et help keyword/commandname }
+\item Commandes {\bf listvars , listcommands }
+\item  Defintion et liste d'alias : {\bf alias aliasname 'string ' } et {\bf  listalias} 
+\end{itemize} 
+
+\item[\rond] {\bf Threads d'execution de commandes (Avril 2005)} \\
+Possibilite de lancer des commandes (autre que les commandes
+  de l'interpreteur lui-meme) en thread separe (il suffit de mettre un \& 
+  a la fin de la commande) \\ 
+  Commandes des gestion des threads : \\
+  {\bf thrlist  ;  cleanthrlist  ;  cancelthr ThId ;   waitthr  } \\
+  Attention, la possibilite de lancer des commandes en threads separes ne fonctionne que
+pour des commandes "thread-safe".
+La plupart de nos commandes de piapp sont  \\
+   - soit trop rapide,  \\
+   - soit non "thread-safe"   \\
+
+  \item[\rond] controle d'execution : \\
+Possibilite d'arreter l'execution de l'interpreteur (dans une boucle
+   ou dans dans un fichier .pic ... 
+   Utiliser la commande {\bf stop} ou {\tt <Cntrl C>} dans PIConsole
+
+\end{itemize} 
+
+\soustitre{Classes CExpressionEvaluator et RPNExpressionEvaluator }
+\begin{itemize}
+\item[\rond]  Ajout des classes RPNExpressionEvaluator et CExpressionEvaluator 
+d'valuation d'expressions numriques en notation polonaise inverse
+et avec la syntaxe C . Utilise dans la classe Commander.  
+\item[\rond]   Programme test Test/tcmd.cc 
+\item[\rond]  extrait de {\tt cvs log cexpre.cc }
+{\small \begin{verbatim} 
+----------------------------
+revision 1.3
+date: 2004/03/18 18:15:19;  author: ansari;  state: Exp;  lines: +10 -6
+Suite (presque finie) des modifications de l'interpreteur - gestion des variables en particulier - Reste au moins un bug ds CExpressionEvaluator - Reza 18/03/2004
+----------------------------
+revision 1.2
+date: 2004/03/16 08:47:48;  author: ansari;  state: Exp;  lines: +5 -6
+suppression variables inutilisees ds cexpr.cc - Reza 16 Mars 2004
+----------------------------
+revision 1.1
+date: 2004/03/15 22:19:43;  author: ansari;  state: Exp;
+Ajout fichiers des classes RPNExpressionEvaluator et CExpressionEvaluator (expression arithmetiques) et MAJ du fichier Makefile et objlist.list - Reza 15 Mars 2003
+\end{verbatim} }
+
+\item[\rond] Extrait du message du 3 Mars 2004 
+\begin{verbatim}
+Le code est base sur une hierarchie de classe d'expression :
+ Expr --------  NumberExp
+      --------- BinExp ------ AddExp
+                       ------ MulExp
+                       ------ SubExp
+                       ------ DivExp
+    ---------  FuncExp
+    ---------  CExpressionEvaluator
+
+NumberExp  : expression elementaire de nombre, sait actuellement traduire Pi et E
+                          tres facile d'ajouter d'autres constantes
+BinExp: Classe d'operations binaires (deux operandes) a+b a-b a*b a/b
+               avec gestion de niveau de priorite des operateurs
+               On peut facilement ajouter d'autres operateurs binaires (par exemple
+               puissance ^ a^b ) - et les priorites relatives seront gerees en principe.
+FuncExp: classe d'expression fonctionnelle, avec n arguments f(x1,x2,...x3)
+                  actuellemenent, n=0 a n=3 arguments et quelques fonctions
+                  usuelles sont decodes ds cette classe (sin,cos,tan, asin, acos, atan, exp, log,
+                  atan2, pow ) - voir ds le code
+
+CExpressionEvaluator : C'est la classe de haut niveau a utiliser -
+                                            la fonction de decodage de la chaine ASCII (qui utilise
+                                            les fonctionalites des differentes classes est la dedans
+                                            et ce n'est pas tres long.
+(+ une classe d'exception specifique).
+\end{verbatim}
+
+\end{itemize}
+
+
+%%%%%%%%
+\titre{FitsIOServer}
+%%%
+\begin{itemize}
+\item[\rond] Aout 2006 : Ecriture/Lecture des classes Histo,HProf,HistoErr,Histo2D dans fichier FITS.
+Les Histo2D et leurs projections 1D associ\'ees sont lus et \'ecrits
+sur plusieurs HDU cons\'ecutifs.
+\item[\rond]  Juin 2006 : Ajout verification/correction noms de colonne lors de lecture FITS / DataTable, 
+et remplacement throw par un warning lors de lecture fits-healpix avec $nbcols > 1$ \\[1mm]
+\item[\rond]  { \large Sep 2005-Jan 2006 : Refondation totale du module }
+\begin{itemize}
+\item[\rond] Amelioration du programme PrgUtil/scanppf - 
+(scanfits -V1 -lh -rd -header filename) 
+\item[\rond] La classe FitsFile (et donc FitsInFile FitsOutFile) heritent de FitsInOutFile.
+(Jan 2006) 
+\item[\rond] Fonctionalites classe {\bf FitsManager } etendues - en particulier ScanFile() 
+\item[\rond] Les FitsIOHandler (ancien) heritent de FitsHandlerInterface - 
+Tous les handlers sont pris en charge et enregistre par FitsManager (Jan 2006) 
+\item[\rond] Ajout classe d'initialisation du module {\bf FitsIOServerInitiator },
+fichiers fiosinit.h .cc (Dec 2005) 
+\item[\rond]  Classe { \bf SwFitsDataTable } (DataTable avec swap sur FITS) ajoute 
+ + classe FitsHandler<BaseDataTable> modifie pour prise 
+en charge de SwFitsDataTable (Dec 2005 - Jan 2006) 
+\item[\rond] Classes {\bf FITSDataSwapper$<$T$>$} modifies (Dec 2005) 
+\item[\rond]  Prise en charge de types TSTRING et TCOMPLEX et TDBLCOMPLEX 
+lors de lecture/ecriture de colonnes FITS. 
+\item[\rond]  Prise en charge de l'ensemble des types de colonnes pour le handler de Fits
+de DataTable
+\item[\rond]  Classe {\bf  FitsInOutFile } comme wrapper des fonctions de la librairie cfitsio +
+classe d'exception spcifique {\bf FitsIOException} , et la classe des types FITS {\bf FitsTypes}.
+\item[\rond]  Classe template {\bf FitsBlockRW$<$T$>$} pour lecture/criture (tableaux de donnes)
+sur IMGHDU et Tables.
+\item[\rond] Classes gestionnaires I/O Fits pour les objets {\bf FitsHandler$<$T$>$} et {\bf FitsManager}
+\item[\rond] Classes gestionnaire pour les tableaux : {\bf FitsArrayHandler$<$T$>$} 
+\item[\rond] Classes gestionnaire pour les DataTable {\bf FitsHandler$<$BaseDataTable$>$}
+\item[\rond] Mai 2005 : Classe {\bf FITSDataSwapper$<$T$>$} pour la gestion des 
+SwSegDataBlock sur fichiers FITS
+\end{itemize}
+\end{itemize}
+
+\titre{LinAlg} 
+Extension des fonctionalits de la classe {\tt LapackServer<T>} : 
+(Juillet 2004 / cmv , Fvrier 2005 / Reza)
+\begin{itemize}
+\item[\rond] Ajout lancement d'exception sur renvoi de code d'erreur par lapack 
+(desactivable par flag au niveau du constructeur de la classe serveur) 
+\item[\rond] Introduction de l'interface Lapack d'inversion des matrices symetriques (21/7/2004)
+\item[\rond]  Introduction de l'interface Lapack de recherche de valeurs et vecteurs propres
+  (cas general, symetrique et hermitique) (21/7/2004)
+\item[\rond] Introduction d'un fonction d'interface pour le calculateur de workspace
+  (ilaenv\_) (21/7/2004)
+\item[\rond] Ajout prog test Tests/tsttminv.cc + Commentaires sur les diverses methodes et sur les matrices FORTRAN (21/7/2004)
+\item[\rond] Ajout SVD decomp by Divide and Conquer SVD\_DC (23/7/2004)
+\item[\rond] Ajout  Least Square with SVD DC
+\item[\rond] Ajout methode calcul de la matrice inverse par Lapack en utilisant la 
+resolution de systemes (07/02/2005) 
+\end{itemize}
+
+\titre{IFFTW}
+\noindent 
+- Juillet 2007 : Passage a FFTW 3 \\
+- Nov 2005 : Correction du bug dans le cas de FFT-1D Backward(complex -> reel) 
+in(1).imag() pouvait etre ecrase.
+
+\titre{PI,PIext,piapp} 
+\soustitre{PI: Classes modifiees - ameliorees}
+\begin{itemize}
+\item[\rond] {\bf  PIImageNavigator } \\
+Ajout de la classe {\tt PIImageNavigator } permettant de visualiser une image 
+avec ses propres widget zoom / global view et colormap. (Fevrier 2005) \\
+Commande {\tt imagnav} ajoute ds piapp/baseexcute.cc . \\
+\item[\rond] Avril 2005 - Amelioration de la classe {\bf PIConsole} \\
+1/Envoi Message PIMSG\_Cancel lors de {\tt <Cntl C>} \\ 
+ 2/ Correction positionnement curseur lors de rappel de commande,
+  Si possible en fin de commande - mais toujours avec le 
+  debut de commande visible.  \\
+3/ Correction (probable) du petit bug sur les derniers caracteres lors de copier/coller
+  ds PIConsole
+\item[\rond] Codage Options graphiques en text (string) pour PIGraphicAtt  (Nov-Dec 2005) 
+\item[\rond] Corrections diverses trace d'axes  etc ... (Dec 2005) 
+\item[\rond] PIext rendu indpendant de FITS (Avril 2006) - commandes spcifiques dans 
+ProgPI/fitsbtadapter.cc 
+\item[\rond] BUG A corriger, DrawOpaqueString ds PIGraphPS (sortie postscript)
+\end{itemize}
+%%%% 
+\soustitre{ Codage texte des options graphiques (11 Mars 2004)}
+\begin{verbatim}
+//   Methode retournant un vecteur de string a partir des options
+virtual int        PIDrawer::OptionToString(vector<string> & opt) const
+qui vient completer les deux methodes
+virtual int        PIDrawer:: DecodeOptionString(vector<string> & opt, bool ...) et
+virtual void       PIDrawer:: GetOptionsHelpInfo(string& info);
+Ces methodes s'occupent de decoder les options graphiques (et l'aide
+associe). La methode ajoutee permet de faire l'operation inverse, fabriquer
+une serie de chaine de caracteres a partir des options graphiques.
+Il y a aussi la methode
+virtual int            PIWdgGen::OptionToString(vector<string> & opt) const
+que j'ai ajoute (rien a faire pour le moment) - ainsi que
+int PIGraphicAtt::AttToStrings(vector<string> & att) const.
+
+Peux-tu remplir la methode PIGraphicAtt::AttToStrings(vector<string> & att) const.
+L'implementation par defaut de PIDrawer::OptionToString(vector<string> & opt) const
+appelle PIGraphicAtt::AttToStrings() -  a laisser donc tel quel.
+
+par contre, pour les autres drawer (PIYfXDrawer, PIFuncDrawer, PIElDrawer,
+PISurfaceDrawer, PIHisto, PIHisto2D, PINTuple ...) - lorsque
+DecodeOptionString(vector<string> & opt, bool ...) est modifie,
+rajouter la methode OptionToString(vector<string> & opt) et verifier le help.
+Attention, il ne faut pas mettre l'argument opt a zero, mais ajouter des chaines
+derriere (push_back()) afin de pouvoir cumuler les options de base  + options
+specifiques.
+
+Comment tester ?
+Pour tester, tu peux utiliser  la fenetre des options texte ou j'ai ajoute le bouton
+[GetOption] . Tu peux acceder a cette fenetre a partir de la fenetre des options
+graphiques <Alt>O , ou directement sur un objet de gestionnaire 2D - par
+<Alt>T - <Shift>Button-1 permet de selectionner le drawer actif
+\end{verbatim}
+
+\soustitre{ Trace des axes (11 Mars 2004)}
+    Ajouter la possibilite de specifier l'origine (le point de croisement des axes)
+lorsque les axes ne sont pas de type 'box' - classes PIAxes et PIElDrawer.  FAIT
+
+\soustitre{ Selection graphique (souris) du drawer actif (11 Mars 2004)}
+\begin{verbatim}
+J'ai ajoute la methode PIDrawer::GetDistanceToPoint(double x, double y)
+// Renvoie une distance au point x,y
+// 0: au(x) point(s) le(s) plus proche(s) ... 1  au bord xmin/xmax , ymin/ymax
+// La methode par defaut calcule la distance normalisee au point ((xmin+xmax)/2,
+(ymin+ymax)/2)
+  virtual double     PIDrawer::GetDistanceToPoint(double x, double y);
+
+ainsi que ce qu'il faut ds PIBaseWdgGen et ds PIDrawer pour exploiter cette
+methode + code permettant le test ds PIScDrawWdg.
+(virtual  void      PIDrawer::WdgCoord2DrwCoord(int x, int y, double& xu ...
+ virtual int PIBaseWdgGen:;FindNearestDrawerId(int x, int y) ...)
+Tu as a t'aoccuper de la methode  PIDrawer::GetDistanceToPoint(double x, double y)
+qui doit etre redefinie si possible pour chaque drawer, afin de fournir une
+distance raisonnable au point (x,y) en argument.
+J'ai juste mis une implementation par defaut (ds PIDrawer) et une implementation
+partielle pour PIElDrawer (qui trace les axes en particulier) - qu'il faut
+completer.
+
+Comment tester ?
+J'ai mis ce qu'il faut ds le gestionnaire 2D (PIScDrawWdg) -
+<Shift>Button-1 choisit le drawer le plus proche (base sur la
+valeur de retour de  PIDrawer::GetDistanceToPoint(double x, double y)
+comme drawer actif. Ce drawer est passe en 'highlight' pendant que
+le bouton est appuye.
+\end{verbatim}
+
+\soustitre{ Manipulation interactive des drawers (3 Juin 2004) }
+La manipulation interactive des drawers ( l'aide d'un menu) a
+t finalise pour les PIImage PIScDrawWdg PI3DWdg .
+
+\begin{verbatim}
+   o <Alt>D affiche le menu avec les differentes option
+   o Move/Resize: Affichage du rectangle + rectangle milieu
+   (deplacement) + coin bas-droite (deplacement) - 
+   clicker ailleurs pour finir
+   o Mouse Select : Le mouse select des drawers est gere
+   maintenant par un PIEventHandler (comme pour Move/ReSize)
+   Drawer actif affiche par le rectangle muni d'un petit coin 
+   (petit carre + rond dedans, en bas a droite). 
+   Click souris change eventuellement le drawer actif. 
+   On termine en clickant ds le petit [carre+rond] 
+\end{verbatim}
+
+\soustitre{ Traceur de bar-graph (classe PIBarGraph) (3 Juin 2004) } 
+Ajout du traceur de bar-graph (classe {\bf PIBarGraph}) ds module PI/
+et commande {\tt bargraph}  ds PIext/basexecut.cc .
+La commande bargraph ne gere pas encore toutes les possibilites
+de la classe PIBarGraph. \\
+Exemple d'utilisation:
+\begin{verbatim}
+Cmd> bargraph ' ' -10. 15. 22. 8. 33. 7 -4. 
+Cmd> bargraph 'blue ' -10. 15. 22. 8. 33. 7 -4. 
+Cmd> bargraph 'blue horizontalbars' -10. 15. 22. 8. 33. 7 -4. 
+Cmd> bargraph 'blue horizontalbars barvaluelabel ' -10. 15. 22. 8. 33. 7 -4. 
+Cmd> bargraph 'blue verticalbars nofill barvaluelabel ' -10. 15. 22. 8. 33. 7 -4. 
+Cmd> bargraph 'font=times,bold,16 blue verticalbars nofill barvaluelabel ' \
+     -10. 15. 2 2. 8. 33. 7 -4. 
+Cmd> bargraph 'font=times,bold,16 blue verticalbars fill barvaluelabel packfrac=0.8' \
+     -10. 15. 22. 8. 33. 7 -4. 
+\end{verbatim}
+
+\soustitre{ Traceur de lignes de texte (classe PITextDrawer)  (3 Juin 2004) } 
+
+Ajout d'une classe de traceur de lignes de texte (classe {\bf PITextDrawer}) et commande 
+{\tt textdrawe}r ds PIext/basexecut.cc . Mais le traceur (et sa commande) 
+doivent etre completes. \\
+Exemple d'utilisation:
+\begin{verbatim}
+# On affiche qque chose
+Cmd> openppf demo.ppf
+Cmd> disp h1d
+Cmd> textdrawer 'frame line=solid,2 font=times,bold,16 red inset'  \
+     ' Christophe ' ' Reza Ansari' ' SOPHYA ' 
+\end{verbatim}
+
+\soustitre{ Gestion de re-scale-ing des  axes en 3D  (3 Juin 2004)  }
+
+Mise en place complete (?) de la gestion de re-scale-ing des  axes en 3D 
+avec gestion des options graphiques (texte) - Il est possible en particulier d'imposer
+les limites de la boites 3D.
+cela a ete une grosse prise de tete de tout un apres-midi.
+J'ai eu ensuite mal a la tete une partie de la soiree !  \\
+Exemple d'utilisation:
+
+\begin{verbatim}
+
+# On ouvre le fichier demo.ppf
+Cmd> openppf demo.ppf
+Cmd> surf mtx1 'colbr32'
+Cmd> surf mtx1 'colbr32 noautoscale'
+Cmd> surf mtx1 'colbr32 lim3dbox=-10,60,-10,60,-3,15 autoscale3dbox'
+#  Affichage avec superposition
+Cmd> nt3d nt32 x y z - - - - - 'marker=circle,7 red'
+Cmd> nt3d nt32 x y z - - - - - 'same marker=cross,5 blue '
+#  Ou bien : 
+Cmd> nt3d nt32 x y z - - - - - 'marker=circle,7 red noautoscale'
+Cmd> nt3d nt32 x y z - - - - - 'same marker=cross,5 blue '
+
+\end{verbatim}
+\soustitre{piapp (PIext/ProgPI) }
+\begin{itemize}
+%%%%
+\item[\rond] Juillet 2006 : Ameliorations et ajouts divers : \\
+- Ajout commande {\bf plot3dw} ({\tt Services2NObjMgr::DisplayPoints3DW() }) \\
+- Ajout possibilite d'acces aux caracteristiques des objets par {\tt \$\{objname.att\} }  \\
+{\tt (PIACmd::GetVarApp()) } et amelioration verification du nom des objets 
+(methode {\tt NamedObjMgr::CheckName()}) \\
+- Operations sur objets: commande {\bf objaoper} ({\tt NObjMgrAdapter::PerformOperation()}) 
+
+\begin{verbatim}
+#  Extracting row / column from matrix
+Cmd> objaoper matrixname row 23
+Cmd> objaoper matrixname col 148
+#  Extracting plane from 3D array (slicexy slicexz sliceyz)
+Cmd> objaoper arr3dname slicexy 14
+\end{verbatim} 
+%%%%
+\item[\rond] Avril 2006: Ajout possibilite de lecture des commandes sur le terminal (stdin) 
+et flag en argument de commande {\tt -small} \\
+Extrait de cvs log :
+\begin{verbatim}
+revision 1.16
+date: 2006/04/26 15:53:18;  author: ansari;  state: Exp;  lines: +20 -11
+1/ Ajout classe de lecture sur stdin (terminal) avec thread separe pour
+piapp - incluant la possibilite d'utilisation de la librairie GNU readline
+(fichiers piacmdrdr.cc piacmdrdr.h + fichier makfile specifique makefile_wgrdl
+ pour compil+link avec GNU readline)
+2/ MAJ Makefile et modif programme principal piapp.cc avec flag -small
+et activation thread de lecture sur terminal
+                           Reza , 26/04/2006
+
+----------------------------
+\end{verbatim}
+
+\item[\rond] Jan 2006 : commandes readfits writefits scanfits ont ete ajoutees 
+dans ProgPI/fitsbtadapter.cc en utilisant le nouveau FITS - 
+Le menu OpenFits de PIStdImgApp utilise desormais ces commandes
+\item {\bf BUG } a corriger pour {\tt imagvav}: 
+La destruction de l'objet et/ou widget pascorrectement geres - 
+provoque des plantages lors de la sortie de l'application.
+\end{itemize}
+\soustitre{piapp multi-thread }
+\begin{itemize}
+\item[\rond] Avril 2005: Possibilit d'execution de commandes en threads separes, en
+ajoutant {\bf \&} en fin de ligne de commande.
+\item[\rond] Janvier 2004: Le multithreading a t mis en oeuvre dans piapp . 
+
+\item[\rond] Extrait de {\tt cvs log pistdimgapp.cc } : 
+\begin{verbatim}
+revision 1.77
+date: 2005/04/27 11:55:00;  author: ansari;  state: Exp;  lines: +26 -10
+1/ Prise en charge de DataTable et SwPPFDataTable pour piapp (NObjMgrAdapter) :
+nomhistadapter.cc et piiinit.cc
+2/ Lecture de tous les objets ds un fichier PPF par NamedObjMgr::ReadAll() pour
+fichier PPF sans nametag.
+3/ Ajout bloc try/catch ds PIStdImgApp::Run() (boucle d'evenements)
+                                           Reza , 27 Avril 2005
+----------------------------
+revision 1.76
+date: 2005/04/19 09:13:49;  author: ansari;  state: Exp;  lines: +3 -1
+Ajout de l option nodisp ds les affichages des NamedObjMgr, prise en compte de 
+<Cntrl C> (Msg_Cancel) pour arreter l'execution de l'interpreteur ds PIStdImgApp 
+et remplacement commande breakexe par stop ds PIACmd - Reza 19/4/2005
+----------------------------
+revision 1.75
+date: 2005/04/19 06:56:52;  author: ansari;  state: Exp;  lines: +5 -4
+Remis en marche la possibilite d'execution d'un .pic au lancement de piapp - 
+Reza 19/4/2005
+----------------------------
+revision 1.74
+date: 2005/02/18 14:09:47;  author: ansari;  state: Exp;  lines: +62 -37
+Modifications pour l'utilisation viewer PIImageNavigator (ajout commande imagnav
+) - Reza 18 Fev 2005
+----------------------------
+revision 1.73
+date: 2004/11/19 17:41:07;  author: ansari;  state: Exp;  lines: +26 -0
+Ajout commandes addoval addfoval pour trace d'ellipse - Reza 19/11/2004
+----------------------------
+revision 1.71
+date: 2004/09/07 07:10:18;  author: ansari;  state: Exp;  lines: +35 -0
+Ajout bloc try/catch ds piacmd.cc (thread execution commandes) et ds pistdimgapp.cc (
+methode process, thread boucle d'evts) - Reza 07/09/2004
+----------------------------
+revision 1.70
+date: 2004/01/06 18:44:56;  author: ansari;  state: Exp;  lines: +11 -1
+ Suite debugging gestion lock entre threads ds piapp - A l'air de
+marcher sur OSF1 et Linux ...   Reza 06/01/2004
+----------------------------
+revision 1.69
+date: 2004/01/06 17:05:25;  author: ansari;  state: Exp;  lines: +33 -7
+Suite debug piapp multithread : on ne peut pas utiliser ZSync() ds un if (destructeur
+ appele de suite) - Reza 06/01/2004
+----------------------------
+revision 1.68
+date: 2004/01/04 19:02:43;  author: ansari;  state: Exp;  lines: +43 -13
+Suite des modifs pour piapp multi-threads
+1) Ajout Mutex de synchronisation ds ls classe NamedObjMgr
+2) Suite controle de gestion d'appel aux methodes de PIStdImgApp depuis
+la classe elle-meme, a travers le NamedObjMgr
+3) Modification de la boucle d'evenements, avec un thread de reveil
+periodique
+                                    Reza, 4 Janvier 2004
+\end{verbatim}
+\item[\rond] Extrait de {\tt cvs log pistdimgapp.cc } : 
+\begin{verbatim}
+----------------------------
+revision 1.62
+date: 2003/11/27 10:51:58;  author: ansari;  state: Exp;  lines: +45 -20
+Suite modification/adaptations a la classe PIACmd qui herite maintenent de SOPHYA::Co
+mmander - Reza 27/11/2003
+----------------------------
+revision 1.61
+date: 2003/11/26 23:01:55;  author: ansari;  state: Exp;  lines: +20 -1755
+Modification du code de PIACmd : La classe PIACmd herite maintenant de la classe Comm
+ander (de SysTools) - Reza 26/11/2003
+----------------------------
+revision 1.60
+date: 2003/07/21 21:13:10;  author: cmv;  state: Exp;  lines: +3 -3
+- introduction notion de numero de ligne dans expression ntuple
+  modif prototype PlotExprFunc NTLoopExprFunc (add _nl _nstart _nend)
+  modif int_4 -> int_8_exprf (long long) pour _nl (DecodeLoopParameters,
+     PrepareNTExpressionCFile, LinkExprFunc,...)
+- doc pour _nl _nstart _nend et arragement repartition RegisterHelp/RegisterCommand
+             (rz + cmv 21/7/2003)
+----------------------------
+\end{verbatim}
+\end{itemize}
+
+\titre{Documentation (Manual/) } 
+%%%%
+Documentation des classes de SysTools. \\
+Extrait message du 12 Aout 2004 : \\
+\begin{verbatim} 
+---> Au sujet de la doc (Manual/)
+       J'ai installe doxygen sur le Mac, version 1.3.8 -
+       Il faut updater le fichier de config de depart (dox_sophya.conf)
+       Pour ma part, j'ai du modifier mkmf (en version privee) -
+      En effet, il n'y avait pas le program doxysearch - Je ne sais pas si c'est general
+      ou specifique Mac.
+
+      J'ai aussi modifie certaines options de doxygen (en version privee)
+     EXTRACT_LOCAL_CLASSES  --> NO   (au lieu de YES)
+     DETAILS_AT_TOP  ---> YES     (au lieu de No)
+     SORT_MEMBER_DOCS  ---> NO    (au lieu de YES)
+
+      Si on est d'accord, on peut modifier ces options ds le fichier dox_sophya.conf et
+      utiliser la fonction update de doxygen (doxygen -u)
+\end{verbatim}
+
+\titre{Mgr} 
+\begin{itemize}
+\item Avril-Mai 2005 : Basculement vers la nouvelle version de scripts 
+de gestion du code (module {\bf BuildMgr/ } ) 
+On n'a plus a se preoccuper des indications de cette section 
+
+\item 
+Septembre 2003 (17/9/2003) :  Changement DPCDEVREP, DPCBASEREP
+en SOPHYADEVREP , SOPHYABASEREP , EROSCXX en SOPHYACXX 
+\end{itemize}
+
+
+
+\titre{Plan de modifs pour SOPHYA V 2.x PI/piapp V 4.x }
+
+{\bf Sep 2006} : La grande majorit\'e des modifs pr\'evues en 2003 ont \'et\'e
+effectu\'ees. Reste \`a faire , si besoin :
+\begin{itemize}
+\item SophyaLib::TArray/ 
+\begin{verbatim}
+  - Ajouter une classe de base abstraite GenericMatrix<T>
+    avec methode d'acces aux elements, nb de lignes, nb de colonnes,
+  - Introduire les TinyMatrix  (TinyMatrix<T, int L, int C>)
+    avec passage de/vers TMatrix<T> (et TinyVector<T, int N>) ?
+  - Introduire des matrices creuses simples SpareMatrix<T>
+  - Introduire les DiagonalMatrix<T>
+Remarque: Les TMatrix TinyMatrix et  SparseMatrix heritent de GenericMatrix
+\end{verbatim}
+
+\item PI/ piapp 
+\begin{verbatim}
+o Ajouter un traceur de  ApplePie (BarChart fait )
+o Ajouter un traceur de Lego-Plot
+o (?) Une fonction pour faire facilement une fenetre d'alerte ou d'info (?)
+o Voir comment on pourrait "joindre" deux objets ayant l'interface NTupleInterface
+  pour pouvoir plotter des objets, l'un vs l'autre
+o (???) Introduire quelque chose du style
+  AddDialogue("Cmd", "dialogue-description)
+  qui pourrait fabriquer automatiquement une fenetre avec des champs a remplir
+  pour les commandes usuelles (???)
+\end{verbatim}
+\end{itemize}
+
+
+\end{document}
Index: /tags/V_Nov2007/SophyaLib/Manual/modulessophya_depend.txt
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/modulessophya_depend.txt	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/modulessophya_depend.txt	(revision 3445)
@@ -0,0 +1,64 @@
+
+
+Base CVS Sophya:  
+/exp/eros/CVSPlanck/ 
+                   /SophyaLib/  
+                   /SophyaExt/   (modules avec dependences en lib-externes)
+                   /SophyaProg/  (Modules avec programmes executables)
+
+                   /SophyaPI/    (librairie GUI PI et contexte piapp)
+ 
+
+Le module Mgr/ (ds SophyaLib/) contient un fichier README, les scripts
+de management de code, et les fichiers Makefile.h .slb, ...
+
+Le module de base pour le code Sophya est actuellement :
+                                    /SophyaLib/BaseTools
+
+On devrait le decouper en trois :
+       /ComDefs/  (fichiers machdefs.h pexceptions.h sophyainit.h 
+                   anydataobj.h datatype.h)
+
+       /BaseTools/ (les classes de persistence, NDataBolock<T> 
+                    MuTyV et DVList ...)
+                    
+
+       /RandGen/   (generateurs aleatoire)
+
+
+Nom de Module      |   Dependances
+-----------------------------------------------------------------
+Comdefs/           |       -        (module ComDefs n'existe pas encore)
+BaseTools/         |   Comdefs/     (       "           "        "     )
+RandGen/           |   Comdefs/     (       "           "        "     )
+                   |
+SUtils/            |   Comdefs/     (actuellement BaseTools/)
+TArray/            |   BaseTools/
+SkyMap/            |   TArray/
+HiStats/           |   TArray/   + NTools/   (1)
+SkyT/              |   TArray/  NTools/
+Samba/             |   SkyMap/  NTools/
+
+NTools/            |   TArray/ + HiStats/ (?)        (2)
+
+SysTools/          |   Comdefs/     (actuellement BaseTools/)
+SysSpec/           |   Comdefs/     (3)
+
+(1) HiStats semble dependre de NTools - Je pense qu'il faut faire 
+quelque chose pour rendre HiStats independant de NTools/
+(2) NTools/ Dependences a eclaircir
+
+(3) SysSpec/ definit les fonctions manquant sur certains systemes
+(utilises actuellement sur MacOS-X / Darwin)
+
+Nom de Module      |   Dependences
+----------------------------------------------------------------------
+FitsIOServer/      |   TArray/ + SkyMap/ + HiStats/  + libcfitsio  (4)
+LinAlg/            |   TArray/  + liblapack
+IFFTW/             |   TArray/ + NTools/ + libfftw
+XAstroPack/        |   XephemAstroLib/   
+
+(4) si on a un systeme plus simple de gestion de dependances plus simple,
+FitsIOServer/ peut etre decoupe en 4 :
+FitsIOServer/ = FitsIOServer/ + FitsTArray/ + FitsSkyMap/ + FitsHiStats/
+
Index: /tags/V_Nov2007/SophyaLib/Manual/perfmachine.txt
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/perfmachine.txt	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/perfmachine.txt	(revision 3445)
@@ -0,0 +1,702 @@
+-------------------------------------------------------------------------------------
+ Comparaison performance de differentes machines en compilation / execution (calcul)
+                                   -----------------------
+    Mesures effectuees en Janvier 2007 ,       R. Ansari / C. Magneville
+-------------------------------------------------------------------------------------
+
+(a) eros3 : Bipro-bicoeur Xeon@2.4 GHz Linux (xeon-lx-2.4GHz)  , gcc 3.2
+(b) ccali : Bipro-bicoeur Xeon@2.8 GHz Linux (xeon-lx-2.8GHz)  , icc 8.0 ou 9.0
+     Flags de compilation avec [-O -g]      
+(bb) grid49 : Bipro-bicoeur nouveau Xeon 5140 @ 2.33 GHz
+(bb4) grid50 : Bipro-quadri-coeur nouveau Xeon E5345 @ 2.33 GHz --> 8 coeurs
+(c) sgsda: AMD Bipro AMD opteron 248 @ 2.2 GHz (amd-lx-
+     Flags de compilation avec [-O -g]      
+(cc) grid-saclay: AMD opteron 275 Bipro-bicoeur  @ 2.2 GHz (amd275-lx)
+     Flags de compilation avec [-O -g]      
+
+(d) asc: bipro alpha (@ ~1 GHz) server DS20 OSF (osf1)  , cxx 6.5 (osf-asc)
+(nouveau asc 420 MFLOPS, moins puissante que l'ancien asc 800 MFLOPS)
+(e) xp1000-dapnia: alpha xp1000 @ ~ 600 MHz ? OSF1 , cxx ? (osf-xp1000)
+(e') cool: alpha xp1000 @ ~ 667 MHz ? OSF1 5.1 , cxx 6.3 
+(f) superosf-dapnia: multi-proc alphaServer ES80 6 procs EV7 @ 1 GHz (super-osf)
+
+(g) ccsvx01: XServe G5 bipro @~1.8-2GHz (Darwin/OSX) (G5-osx-2GHz) , gcc 3.3
+(h) PowerBook-Reza : Apple G4 @ 1.25 GHz (G4-osx-1.25GHz) , gcc 3.3
+(i) MacBook-Reza: Apple/ Core double-coeur Intel @ 1.83 GHz (core-osx-1.83GHz) gcc 4
+(j) MacPro-Grosdidier : Apple / Xeon 2 double-coeur @ 3 GHz gcc 4.0.1 , compil SOPHYA -O2 -g
+
+(p) IBM-AIX regatta , xlC , IBM eServer pSeries 655 , 8 proc power4 @ 1.1 GHz
+(q) IBM-AIX meso , AIX 5.3, xlC V8 , IBM Power5 , 8 proc bi-coeur P575 @ 1.9 GHz 
+
+(s) SGI-IRIX64 magique, CC 
+
+NOTES : 
+- Sur les machines Xeon, il y a une interaction entre process / threads par rapport a 
+l'occupation des CPU's. On perd un facteur 3 en performance multi-threads/multi-taches.
+La machine MacPro avec OSX se debrouille quand meme mieux.
+- Effet du systeme ou carte mere ??? 
+
+Flag de compilation 
+- Flag de compilation par defaut [-O -g] en general
+- Sur eros3 (xeon-linux gcc 3.3) [-O -g] OU [-O3 -g]
+- Sur Darwin [-g] ou [-O2 -g] (ou [-tune G5] sur XServe G5)
+   Sur les mac (en particulier G4/G5), grande difference entre -g et -Ox -g
+   mais peu de difference entre -O -O2 -O3  
+- Sur machine aix-meso [-O -g] ou [-O3 -g]
+
+X/ Performances brutes cpupower et donnees SPEC ((http//www.spec.org) 
+----------------------------------------------------------------------
+
+(1) MFLOPS  -> cpupower 2   (x/y : -O -g / -O3) 
+SPECint2000 (3) / SPECfp2000 (2) (http//www.spec.org) 
+
+X.1/ Performances en calcul double
+csh> cpupower 0 3000000  5 
+     3 10^6 operations doubles - sur memoire 3x3 10^6 doubles (~50 MO)
+      ===> ~ 24 MO / MFLOPS
+csh> cpupower 2
+     1.6 10^9 operations doubles - sur 3x20000 doubles (~0.5 MO)
+
+
+Compilation avec -O  (optimisation)
+  (1) cpupower 0 : debit memoire en MO/s
+  (2) cpupower 0  , MFLOPS   
+  (5) cpupower 2 ,  MFLOPS 
+
+Compilation avec -g (debug / sans optimisation)
+  (3) cpupower 0  , MFLOPS  
+  (6) cpupower 2  , MFLOPS 
+
+Compilation avec -O3 ou -fast ...( optimisation poussee) 
+  (4) cpupower 0  , MFLOPS  
+  (7) cpupower 2  , MFLOPS 
+
+
+----------------------------------------------------------------------------------------------
+        MFLOPS       |(1) MO/s|   (2)     (3)      (4)   |    (5)       (6)       (7)      
+----------------------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz    | 1290   |   53      53       55    |    338       340       320
+(b)xeon-lx-2.8GHzicc | 2040   |   85      80       83    |    914       409       914
+(bb)n-xeon-grid49    | 3000   |   125     85       130   |    660       500       660
+(bb)n-xeon4c-grid50  | 2568   |   107     103      109   |    655       500       655
+(c)amd-lx            | 1560   |   65      77       68    |    666       314       686 
+(cc)amd2-lx          |        |
+
+(e')osf-cool         |  768   |   32      15       32    |    630       150       660     
+(f)superosf               
+
+(g)G5-osx-1 GHz      | 2100   |   88      68       88    |   1000       255      1073
+(f)G4-osx-1.25GHz    |  600   |   25      16       25    |    417        93       430 
+(i)core-osx-1.83GHz  | 2500   |  107      75      107    |    855       309       884
+(j)xeon-osx            
+
+(p)ibm-aix-regatta   | 3100   |  130      55      133    |    730       115      1750  (32 bits)
+(p)ibm-aix-meso      | 5700   |  240      70      320    |   1500       220      3400  (32 bits)
+
+(s)sgi-magique       |  336   |  14       7       15     |    340        40       460  (32 bits)  
+----------------------------------------------------------------------------------------------
+
+X.2/  Comparaison performances int, float double 
+  cpupower compile avec -O 
+
+(1) float , cpupowerF 0 3000000 5 / cpupowerF 2
+    -> MFLOPS (puissance de calcul sur float)
+(2) double, cpupowerD 0 3000000 5 / cpupowerF 2  (idem tableau X.1)
+    -> MDBLOPS (puissance de calcul sur float)
+(3) int, cpupowerI 0 3000000 5 / cpupowerI 2
+    -> MINTOPS  (puissance de calcul sur int=4 bytes)
+(4) long (ou long long (*)) cpupowerL 0 3000000 5 / cpupowerL 2
+    -> MLONOPS  (puissance de calcul sur long=8 bytes)
+----------------------------------------------------------------------------------------------
+        MFLOPS       |   (1)MFLOPS       (2)MDBLOPS       (3)MINTOPS       (4)MLONOPS 
+----------------------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz    | 
+(b)xeon-lx-2.8GHzicc |    166/905         90/900           166/1500         88/522    (*)
+(bb)nxeon-grid49     |    250/1030        125/660          250/2500         125/2280
+(bb4)xeon-4c-grid50  |    207/1019        110/660          207/2460         107/2285
+(c)amd-lx            |    125/695         65/675           125/1570         65/1045
+(cc)amd2-lx          | 
+
+(e')osf-cool         |    60/635          32/631            62/640          31/630
+(f)superosf               
+
+(g)G5-osx-1 GHz      |    180/1260        90/1150           165/940         81/280    (*)
+(f)G4-osx-1.25GHz    |    45/430          25/410            45/710          24/190    (*)
+(i)core-osx-1.83GHz  |    185/919         105/855           187/935         62/246    (*)
+(j)xeon-osx            
+
+(p)ibm-aix-regatta   | 
+(p)ibm-aix-meso      |    250/1150        250/1500          250/1200        50/200     (32 bits)
+                     |    280/1500        250/1600          250/1100        210/1000   (64 bits -q64)
+
+(s)sgi-magique       |  
+----------------------------------------------------------------------------------------------
+
+X.3/  Comparaison avec SPEC 
+csh>  cpupower 0 / cpupower 2 
+----------------------------------------------------------------------
+                         MFLOPS(1)      SPECfp      SPECint 
+----------------------------------------------------------------------
+(b)xeon-lx-2.8GHz         166/900        1400        1400
+(c)amd-lx                 125/690        1600        1300
+(cc)amd2-lx               675            1600        1300
+
+(e)osf-xp1000             32/650         500         400
+(f)superosf               842            1100        700
+
+(i)core-osx-1.83GHz       110/850        1400        1500    
+(j)xeon-osx               2600           2900          -
+
+(p)ibm-aix-regatta        130/700        1050        700     
+----------------------------------------------------------------------
+
+
+A/ Compilation tout SOPHYA 
+----------------------------
+csh> time make all   (1)
+ou 
+csh> time make -j 2 all  (2)
+  Temps CPU 
+  Indice de performance 100*(1000/TCPU) 
+  Temps elapsed (vrai)
+  Temps vrai / TCPU
+
+
+----------------------------------------------------------------------
+                         CPU(s)  IndPerf   TElapsed , TCPU/Elapsed %
+----------------------------------------------------------------------
+(a)xeon-lx-2.4GHz (2)    615 s      162       410 s        150%  
+      avec -O3 -g (2)   1300 s       77       760 s        172%  
+(b)xeon-lx-2.8GHz (2)    755 s      132       540 s        140%
+(c)amd-lx         (2)    336 s      297       175 s        192%
+
+(d)osf-asc (1)          1920 s       52      2340 s        83%   (??)
+(e)osf-xp1000 (1)        533 s      187       660 s        80%
+(f)superosf (1)          895 s      112       910 s        98%
+
+(g)G5-osx-2GHz (2)       453 s      221       250 s        182%
+    -tune=G5            1100 s       90
+    -g -O                740 s                380 s        195%
+(h)G4-osx-1.25GHz (1)    660 s      151       710 s        93%   [-g]
+                        1500 s                             94%   [-O2 -g]
+(i)core-osx-1.83GHz (2)  209 s      478       116 s        180%
+              -O2   (1)  367 s      272       381          96%    
+(j)xeon-osx
+
+(p)ibm-aix
+----------------------------------------------------------------------
+
+Taille shared libs : 
+(a)
+(c) 33 MO   
+(f) = (e) = 57 MO 
+(g) 80 MO
+(i) 83 MO
+
+B/ Calcul brut (Tableaux de SOPHYA) avec / sans threads
+--------------------------------------------------------
+B.1.a/   Calcul sur vecteur 10 * V2 ~= DLO4 (V1) 
+         ~ 10 x 10 x 9. 10^6 operations double sur 2 x  9 10^6 double    
+         900 M.Ops r_8 / ~ 1500 MO 
+
+(1) time cpupower 0     # compile avec -O  (/ -O -g)
+(2) time zthr arrdl 1 3000   1 thread
+(3) time zthr arrdl 2 3000   2 thread
+(4) time zthr arrdl 4 3000   4 thread
+(5) time zthr arrdl 6 3000   6 thread
+(6) time zthr arrdl 8 3000   8 thread
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS  (2)CPU/Elap/%   (3)CPU/Elap/%   (4)CPU/Elap/%
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz      53        
+(b)xeon-lx-2.8GHz      85       2.6/2.6/100%    5.3/2.9/180%   14.3/4.86/310% 
+                                   (5) 23/7.4/314%
+(bb)nxeon-grid49       125      2/2/99%         4/2/186%       8/2.45/326%
+                                   (5) 12/3.6/330%   (6) 16/4.7/340%
+(bb4)xeon-4c-grid50    110      2.2/2.2/99%     4.2/2.3/185%   8/2.5/321%
+                                   (5) 13/3.1/470%   (6) 21/3.8/544%
+(c)amd-lx              95        
+                                 
+                                  
+(e')osf-cool           32       5.7/5.8/98%     11.1/11.3/98%   22.3/22.5/98% 
+(f)superosf                    
+
+(g)G5-osx-2GHz         88       2.5/2.6/99%     5.9/3.38/184%    11/6.45/173%    [-O2 -g]
+(h)G4-osx-1.25GHz      25       6.6/7/95%       13.4/13.8/97%                    [-O2 -g]
+(i)core-osx-1.83GHz   107       2.1/2.1/98%     4.3/2.9/150%     8.3/30/31%      [-O2 -g]
+(j)xeon-osx           
+
+(p)ibm-aix-regatta    130        
+(q)ibm-aix-meso       150       0.7/1/70%       1.2/2./60%       3.2/2/150%   [-O3]
+                                  (5) 5.4/3/180%    (6) 6.4/3/210% 
+
+(s)sgi-magique          7       78/78/99%       167/95/175%      339/96/352%     [-O -g: NON-OPT]
+                       14       16.4/16.5/99%   33.8/22.4/150%   79/32/250%      [-O -g2 OPT]
+ -----------------------------------------------------------------------------------
+
+B.1.b/   Calcul sur vecteur V2 = Sin(V1) + Cos(V1) 
+         ~ 50 x 9. 10^6 operations double sur 2 x  9 10^6 double, mem ~ 150 MO 
+         ~500 M.Ops r_8 / ~ 600 MO I/O
+
+(1) time cpupower 0     # compile avec -O  (/ -O -g)
+(2) time zthr arrmf 1 3000   1 thread
+(3) time zthr arrmf 2 3000   2 thread
+(4) time zthr arrmf 4 3000   4 thread
+(5) time zthr arrmf 6 3000   6 thread
+(6) time zthr arrmf 8 3000   8 thread
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS  (2)CPU/Elap/%   (3)CPU/Elap/%   (4)CPU/Elap/%
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz      53        
+(b)xeon-lx-2.8GHz      85       1.7/1.7/100%    3.5/2.1/173%     9.8/3.6/275%
+                                   (5) 12/3.6/330%    (6) 16/4.7/340%
+(bb)nxeon-grid49       125      1.6/1.6/100%    3.2/1.7/183%     6.7/2.1/314% 
+                                   (5) 10.1/3.2/320%  (6) 14.4/4.05/330%
+(c)amd-lx              95        
+                                 
+(e')osf-cool           32       4.2/4.3/98%     8.2/8.4/98%      16.1/16.2/98%
+(f)superosf                    
+
+(g)G5-osx-2GHz         88       2.3/2.3/100%      5/3/165%        9.6/5.8/167%  [-O2 -g]
+(h)G4-osx-1.25GHz      25       4.5/4.8/95%       10.9/14.6/72%        [-O2 -g]
+(i)core-osx-1.83GHz   107       2.3/2.3/98%       4.8/3.1/158%                [-O2 -g]
+(j)xeon-osx           
+
+(p)ibm-aix-regatta    130        
+(q)ibm-aix-meso       150       1./2/50%         2.8/3/86%       5.4/4/130%   [-O3]
+                                     (5) 10/4/250%    (6) 11.2/5/220%% 
+
+(s)sgi-magique         7       11.5/11.7/99%     24/17/140%      51.5/18.4/280%  [-O -g NON-OPT]
+                      14       6.5/6.6/99%       13.3/12/110%    34.5/17.3/200%  [-O -g3 OPT]
+ -----------------------------------------------------------------------------------
+
+
+B.1.c/ Version corrige de zthr.cc (apres 23/05/07) 
+         arr = (c1*a1) + (c2*a2) 
+         ~ 3 x 4. 10^6 operations int_4 sur 3 x 4 10^6 int_4    
+         12 M.Ops int_4 / ~ 50 MO 
+
+(1) time cpupower 0     # compile avec -O  (/ -O -g)
+(2) time zthr arr 1 2000   1 thread
+(3) time zthr arr 2 2000   2 thread
+(4) time zthr arr 4 2000   4 thread
+(5) time zthr arr 6 2000   6 thread
+(6) time zthr arr 8 2000   8 thread
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS  (2)CPU/Elap/%   (3)CPU/Elap/%   (4)CPU/Elap/%
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz      53        0.5/1/43%      1/1.1/88%      2.8/1/262%
+                                    (5) 4.5/1.8/246%      (6) 6.1/2.1/310% 
+                                  
+        
+(b)xeon-lx-2.8GHz      65        
+                                  
+(c)amd-lx              95        0.23/1/22%     0.44/1/51%       1/1/102%     [-O -g]
+                                     (5) 1.6/1/106%   (6) 2.2/1.2/100% 
+
+
+                                  
+(e')osf-cool           32        0.43/1.2/35%   0.6/1.33/44%     1.1/1.3/82%      [-O -g]
+                                     (5) 1.45/1.7/85%   (6) 1.83/2.16/84%         
+(f)superosf                    
+
+(g)G5-osx-2GHz         88       1.5/1.5/100%    3.2/1.7/185%      6.6/3.5/188%    [-O -g]
+(g)G5-osx-2GHz         88       0.4/1/40%       0.9/1.0/90%       2/1.2/169%      [-tune=G5 -g]
+                                     (5) 3.3/2/164%    (6) 4.3/2.6/165%
+(h)G4-osx-1.25GHz      25       3/3/95%                                           [-O2 -g]
+                                  
+(i)core-osx-1.83GHz               [-O2 -g]
+
+(j)xeon-osx           
+
+
+(p)ibm-aix-regatta   130        
+
+(q)ibm-aix-meso      150        0.6/1/58%       1/1/91%           1.7/1.2/132%    [-O3]
+                                     (5) 2.4/1.2/193%   (6) 4.25/1.6/265%      
+
+ -----------------------------------------------------------------------------------
+
+B.1.x/ ancienne version de zthr (avant 23/05/07) 
+         On faisait 2 multiplications par ctye suivi d'un produit matriciel !
+         arr = c1*a1*c2*a2   ( ~ 3 10^6 op. double)
+(1) time cpupower 2     # compile avec -O3  (/ -O -g)
+(2) time zthr arr 1 1000   1 thread
+(3) time zthr arr 2 1000   2 thread
+(4) time zthr arr 4 1000   4 thread
+(5) time zthr arr 6 1000   6 thread
+(6) time zthr arr 8 1000   8 thread
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS  (2)CPU/Elap/% (2)IndPerf  (3)CPU/Elap/% (3)IndPerf
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz     1167        5.15/5.2/99%              11.4/5.8/196%
+                                           (4)36.6/9.28/394%
+        -O3 -g                    4.9/5./99%
+(b)xeon-lx-2.8GHz      920        2.3/2.3/100%              6.2/3.1/198%
+                                           (4)26/6.6/396%
+(c)amd-lx              690        3.6/3.6/99%               6.8/4/171%
+                                           (4)13.5/7/193%
+                                           (5)20.3/10.23/198%
+(cc)amd2-lx            675        2/2/99%                   4.15/2.1/197%
+                                           (4)8.25/4.15/198%
+                                           (5)13.6/4.6/292%
+                                           (6)19.8/6.5/300%
+
+(d)osf-asc             420        6.3s/6.5s/99%            16.9/8.8/192%   
+                                           (4)29.9/15.7/191%
+(e)osf-xp1000          648        5.1/5.3/96.6%            11.4/11.4/99%       
+                                           (4)25.2/25.5/99%
+(f)superosf            842        2.87/2.88/99.6%          6.25/4.1/153%
+                                           (4)11.6/3.06/379%          
+
+(h)G4-osx-1.25GHz       92        44s/48s/91%              86.7/99.8/92%  [-g]
+                       380        12.2/12.9/95%            24/25.3/95%    [-O2 -g]                   
+(g)G5-osx-2GHz        1151        20s/20s/99%              40s/23s/170%
+                                           (4) 80.8/45/180%
+   -O -g                          4.5/4.9/91%              9.3/4.7/197%
+                                           (4) 18.3/9.4/197%
+   -tune=G5                       3.35/3.8/88%             7.1/3.6/196%
+(h)G4-osx-1.25GHz       92        44s/48s/91%              86.7/99.8/92%  [-g]
+                       380        12.2/12.9/95%            24/25.3/95%    [-O2 -g]                   
+                                           (4) 14/7.5/187%
+(i)core-osx-1.83GHz    855        11.5/11.5/100%           23/11.6/192%   [-g]
+                                           (4) 46/23/199%
+              -O2                 3.85/3.89/99%            7.7/3.9/198%   [-O2 -g]
+                                           (4) 15.4/7.77/198%
+
+(j)xeon-osx           2600        2.5/2.5/100%             5.1/2.6/199%
+                                           (4) 11.5/3.2/362%
+                                           (5) 17.4/4.77/365%
+
+(p)ibm-aix-regatta  1750/730      6.8/6.9/98%              13.1/6.75/195%
+                                           (4) 26.3/11.7/225%
+(q)ibm-aix-meso     3600/1250     3.6/3.75/96%             7.35/3.7/197%
+                                           (4) 12.46/4.2/298%
+                                           (5) 219/6.7/280%
+                                           (6) 24/4.5/530%
+
+
+(s)sgi-magique         460        60/60/99%       
+ -----------------------------------------------------------------------------------
+
+
+B.2/ Multiplication de matrices mtx = mtx1 * mtx2 
+     ~ 2  10^9 op. double / thread
+(1) time cpupower 2  (-O3 / -O -g)
+(2) time zthr mtx 1 1000   1 thread
+(3) time zthr mtx 2 1000   2 thread
+(4) time zthr mtx 4 1000   4 thread
+(5) time zthr mtx 6 1000   6 thread
+(6) time zthr mtx 8 1000   8 thread
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS  (2)CPU/Elap/% (2)IndPerf  (3)CPU/Elap/% (3)IndPerf
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz     1167        6.5/6.5/100%               17.4/8.8/198%
+                                           (4) 80.5/20.3/397%
+                                           (5) 114.5/29.6/387%
+                                           (6) 160/40.3/387%
+                                           
+(b)xeon-lx-2.8GHz      920        3.4/3.4/100%               12/6.1/199%
+                                           (4) 55.8/14/400%
+                                           (5) 79.5/20.3/392%
+                                           (6) 102/25.8/396%
+(bb)nxeon-grid49       660        4.3/4.3/100%               9.3/4.7/200%
+                                           (4) 28.8/7.3/390%
+                                           (5) 41/10.4/393%
+                                           (6) 57.5/14.45/397%
+(bb4)xeon-4c-grid50    660        4.7/4.7/100%               10.7/5.15/199%
+                                           (4) 27.8/7.1/391%
+                                           (5) 57.4/10.6/540%
+                                           (6) 129/16.8/776%
+(c)amd-lx              690        6.98/6.98/100%             14.1/8.15/173%
+                                           (4) 27.7/14.23/194%
+                                           (5) 41.4/21.07/196%
+                                           (6) 55.4/27.9/198.7%  
+(cc)amd2-lx            675        4.1/4.1/100%               9.55/4.8/198%
+                                           (4) 20/10.27/195%
+                                           (5) 32.8/11.16/294%
+                                           (6) 42.75/13.8/309%
+
+
+(d)osf-asc             420        13.5s/13.7s/98%            32/16.5/194%   
+                                           (4) 67.5/34.4/196%
+(e)osf-xp1000          648        13/14.1/92%                27.1/27.4/99%
+                                           (4) 54/54.7/99.6%
+                                           (5) 80.6/81/99.6%
+                                           (6) 107.8/108.3/99.5%
+(e')osf-cool                      13/13.22/98%               26/26.1/99%
+                                           (4) 51.8/51.9/99%
+(f)superosf            842        6.1/7.24/84%               12.35/6.29/196%
+                                           (4) 24.3/6.31/385%
+                                           (5) 36.5/10.9/335%
+                                           (6) 50.1/18.15/276%
+
+(g)G5-osx-2GHz        1151        23/23.7/97%                46.5/27.5/170%
+                                           (4) 93.4/49.4/189%
+  -O -g                           6.2/6.2/100%                14.2/7.2/197%
+                                           (4) 28.3/14.36/197%
+  -tune=G5                        5.7/5.8/98%                13.3/6.8/197%
+                                           (4) 26.8/13.56/197%
+                                           (6) 53.8/27.25/197%
+(h)G4-osx-1.25GHz      333        23.5/24.5/96%                              [-O2]
+(i)core-osx-1.83GHz    855        12.6/12.7/100%             25.8/13.4/194% 
+                                           (4) 51.6/26/199%
+            -O2                   4.25/4.5/94%               10.6/5.36/198%
+                                           (4) 20.87/10.68/198%
+      -O2 2 jobs //           2 x 5/5.4/92%
+(j)xeon-osx           2600        2.8/2.8/99%                9.3/4.66/199%
+                                           (4) 31.4/8.6/364%
+                                           (5) 47.1/12.96/364%
+                                           (6) 62.8/17.38/362%
+
+(p)ibm-aix-regatta  1750/730      9.5/9.7/98%                18.3/16.0/114%
+                                           (4) 38.3/24.7/155%
+(p)ibm-aix-meso     3600/1250     2.3/2.3/99%                5.1/2.64/194%   (compil avec -O3)
+                                           (4) 11.4/4.16/272%
+                                           (5) 20.2/5.85/344%
+                                           (6) 29.9/6.74/442%
+
+(s)sgi-magique         400        44/44.3/99%                96.5/55/176%
+
+ -----------------------------------------------------------------------------------
+
+
+B.4/ Operations sur tableaux doubles- mesures avec spar 
+  csh> time spar 2 1 2000 2000
+  (1) cpupower 2  MFLOPS
+  (2) MFLOPS (double) spar 
+  (3) time spar 2 5 1000 2000 CPU/Elap/% 
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS      (2)CPU / %         (3)CPU/Elap/%
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz      53       ~ 20-35 MFLOPS , 90%     20/20.2/99%       [-g -O] 
+                                  
+        
+(b)xeon-lx-2.8GHz      65        
+                                  
+(c)amd-lx              95       ~ 20-40 MFLOPS , 99%     17.2/17.2/100%    [-g -O] 
+
+
+(d)osf-asc                     
+                                  
+(e)osf-xp1000          32       ~ 15-25 MFLOPS , 90%     37.6/41.2/91%      [-g -O]  
+(f)superosf                    
+
+(g)G5-osx-2GHz         88       ~ 10-25 MFLOPS , 99%     45/45/100%         [-g -O] ou [-g -O2]
+(h)G4-osx-1.25GHz      25       ~ 8-16  MFLOPS , 92%     45.5/52/90%        [-g -O2]
+                                  
+(i)core-osx-1.83GHz             
+
+(j)xeon-osx           
+
+
+(p)ibm-aix-regatta   130        
+
+(q)ibm-aix-meso      150        ~ 80-100 MFLOPS , 90%   5./23/22%     [-O3]    
+
+
+
+(s)sgi-magique         460        
+ -----------------------------------------------------------------------------------
+
+B.5/  Calcul/comparaison avec JET/tjet 
+csh> time tjet 10 2000 2000   OU tjet 10 2000 1000
+ (1) TCPU EltAccess C/pointeurs 
+ (2) TCPU m1*c1+m2*c2+m3*c3 C/pointeurs 
+ (3) TCPU EltAccess  SOPHYA
+ (4) TCPU m1*c1+m2*c2+m3*c3 SOPHYA  / Methodes (MultCst, AddArr ...)
+ (5) TCPU m1*c1+m2*c2+m3*c3 SOPHYA JET
+
+ -----------------------------------------------------------------------------------
+                            (1)        (2)         (3)         (4)           (5)             
+ -----------------------------------------------------------------------------------
+(b)xeon-lx-2.8GHz-icc       0.87       0.63        1.55      2.7/1.6         0.57
+(c)amd-lx                   0.94       0.79        1.85      3.4/2.1         0.76
+
+(e')osf-cool                2.85       2.45        3.1       6.5/5.5         4.1 
+
+(g)G5-osx-2GHz              1.5        0.61        2.1       4.1/1.6         0.6   (-g -O2)
+    -tune=G5 -fast          1.1        0.62        1.3       4.1/1.6         0.58  
+(h)G4-osx-1.25GHz           3.86       2.2         5         9.4/6.2         3     (-g -O2)
+(i)core-osx-1.83GHz         1.1        0.49        1.6       2.8/1.7         0.68
+
+(q)ibm-aix-meso             0.43       0.27        0.52      1.12/0.75       0.35  
+
+(s)sgi-magique              2.45       1.9         5.65      7.45/6.3        2.8  (-O -g3)
+-----------------------------------------------------------------------------------
+
+
+C/ Calcul fft (FFTW , FFTPack )
+-------------------------------
+
+(1) time cpupower 2 
+(2) time tfft 2000000 W d 0 0 (avec FFTW)
+(3) time tfft 2000000 P d 0 0 (avec FFTPack_Sophya)
+
+IndPerf=1000/TCPU  
+
+
+-----------------------------------------------------------------------------------
+                     (1)MFLOPS     (2)CPU/Elap/%   (2)IndPerf   (3)CPU/Elap/%  (3)IndPerf
+-----------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz     1167        5.5/5.6/97%        180         7.4/7.4/100%     135    
+       -O3 -g                                                    6.8/7.1/96%      147    
+
+(b)xeon-lx-2.8GHz      920        3.6/3.7/98%                    3.7/3.8/99%
+                                                          ~2x    6.5/8.8/73%
+                                                          ~4x    8/14/55%   (15 sec elapsed)
+(bb)nxeon-grid49       660                                       3.3/3.3/99% 
+                                                          ~2x    3.3/3.4/100%  (4 sec elapsed)
+                                                          ~4x    4.6/4.6/99%   (5 sec elapsed)
+                                                          ~8x    4.5/4.5/50%   (9 sec elapsed)
+(bb4)xeon-4c-grid50    660                                       3.6/3.6/99% 
+                                                          ~2x    3.6/3.6/100%  (4 sec elapsed)
+                                                          ~4x    4.4/4.4/99%   (5 sec elapsed)
+                                                          ~8x    7.1/7.1/99%   (7  sec elapsed)
+                                                          ~16x   7.1/14.4/50%   (15 sec elapsed)
+         
+(c)amd-lx              690        3.2/3.75/86%                   4.2/4.2/100%     238
+                                                            ~2x  4.7/4.7/99%
+(cc)amd2-lx            675        2.8/2.8/99%                    3.56/3.58/99%
+
+(d)osf-asc             420        13.3/13.9/95.7%     75        12.2/17.6/70%     82
+(e)osf-xp1000          648        9.9/10.2/97%       101        9.3/9.46/98.5%    107     
+(e')cool                          9.2/10.1/91%                  9.1/9.3/98%
+(f)superosf            842        6./6.22/96.7%      166        5.1/5.18/97.4%    196     
+
+(g)G5-osx-2GHz        1151        8.5/8.7/97.5%      120        11.5/11.6/99%     87
+    -O -g                         5.1/5.2/98%        190        5.4/5.5/99%       180
+    -tune=G5                      5/5.1/98%          200        5.5/5.6/97%       180
+(h)G4-osx-1.25GHz       92        15.2/15.9/96%       66        23.8/34.1/70%     42    [-g]
+                       380        8.8/10.3/86%                  14.7/20.9/65%           [-O2 -g]
+(i)core-osx-1.83GHz    855        4.6/4.75/97%       217        7/7.08/99%        142
+         -O2                      3.2/3.2/99%        312        3.6/3.6/99%       277
+   -O2 2 jobs //              2 x 3.9/4.3/90%                 2x  4.7/5/91%       200     
+(j)xeon-osx           2600                                      2.6/2.6/98%       384
+       2 jobs //                                           ~2x  3.6/4.1/87%       250
+       4 jobs //                                           
+
+(p)ibm-aix-regatta 1750/730       6.25/18.9/33%      160        5.25/15.7/33%     190
+(q)ibm-aix-meso    3600/1250      3.95/4.3/91%       250        3.82/4./94%       260
+       2 jobs //                                           ~2x  3.88/4.2/92%      250
+                                  2.8/4.76/59%                  2.1/4.45/47%     [-O3]
+                                                          ~2x   2.5/4.7/54%
+                                                          ~4x   2.5/4.8/55% 
+
+
+(s)sgi-magique         460        22/22/98%           42         24.5/25/99%       40           
+ -----------------------------------------------------------------------------------
+
+
+D/ Calcul inversion par lapack
+-------------------------------
+
+lpk inverse 1000,1000 0 
+---> temps de calcul inversion par lapack 
+-------------------------------------------------------------------------------------------
+             CPU/Elap/%       (1)         
+-------------------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz          5.6/~100%    
+(b)xeon-lx-2.8GHz          5.34/~90%
+(c)amd-lx                  5.5/5.5/99%      
+
+(d)osf-asc 
+(e')cool                   2.8/2.9/95% 
+(f)superosf           
+
+(f)G4-osx-1.25GHz          2.3/~100%   [-O2 -g]
+(h)G5-osx-2GHz             0.8/~100%
+    -O -g                  0.86/~100%            
+(i)core-osx-1.83GHz        1.93/~100%
+              -O2   
+(p)ibm-aix-regatta        
+(q)ibm-aix-meso            0.55/~100%
+
+(s)sgi-magique             5.3/~90%
+--------------------------------------------------------------------------------------------
+
+
+K/ Efficacite de gestion de lock (mutex) avec les threads et tableaux 
+----------------------------------------------------------------------
+(32 threads - operant sur 2000 vecteurs ~ 64000 lock/unlock/wait/broadcast)
+
+(1) time zthr syncp 32 2000 4 
+(2) time zthr sync 32 2000 4 
+(1) time zthr syncp 4 15000 130 
+(2) time zthr sync  4 15000 130 
+-------------------------------------------------------------------------------------------
+             CPU/Elap/%       (1)             (2)              (3)              (4) 
+-------------------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz         23.5/14/168%    4.3/1.2/365%     7.9/5.5/142%      4/2.15/190%
+      Avant ThSafeOp      17/178%
+      avec -O3 -g 
+(b)xeon-lx-2.8GHz (2)     
+(bb4)xeon-4c-grid50       1/1/96%         1.6/1.2/133%     4.9/4.05/120%     6/5/122%
+(c)amd-lx                 0.6/1/63%        0.6/1/60%       3.5/3.5/102%      2.6/2.7/98% 
+
+(d)osf-asc               4.5/3.4/132%     3.35/2/170%     15.8/10.5/150%     13/8/163%
+     5.4/100%(NoThSafe)
+(e')cool                 1.3/1.37/95%     1.35/1.5/89%     5.3/5.3/99%       5.2/5.2/99%    
+(e)superosf (1)          
+
+
+(g)G5-osx-2GHz (2)     2.6/130% (NoThSafe)                   
+    -O -g                2.6/1.7/150%      6.8/3.7/187%    4/2.75/142%       4.7/3/155%
+(h)G4-osx-1.25GHz (1)    40.5/42.6/95%    42.2/43.5/97%      [-g]
+                          3.9/4.3/89%      3.5/4/89%       3.8/4/95%         4.3/4.6/93%
+
+(i)core-osx-1.83GHz      7.7/7.1/108%     7.8/6.7/116%    30.2/29.6/102%    30.3/29.2/104%   [-g]
+              -O2        2.7/1.8/152%     6/3.16/190%     3.4/2.4/142%      3.2/2.5/164%     [-O2 -g]
+(j)xeon-osx               
+      Avant ThSafeOp      2.55/143%
+
+(p)ibm-aix-regatta        4.7/111%
+(q)ibm-aix-meso           7.5/2.8/300%     17/3.8/450%    8.2/3.05/270%      4.85/2.43/200%    
+
+--------------------------------------------------------------------------------------------
+
+
+
+L/ I/O et PPF 
+-----------------
+Ecriture/lecture de n=10^7 lignes de int+6double, Total ~ 500 MO 
+(1) time tstdtable w xx.ppf swap 10000000 1024 0
+(2) time tstdtable r xx.ppf swap 10000000 1024 0
+(3) time tstdtable w xx.ppf swap 50000000 1024 0
+(4) time tstdtable r xx.ppf swap 50000000 1024 0
+
+-------------------------------------------------------------------------------------------
+             CPU/Elap/%       (1)              (2)              (3)                (4)
+-------------------------------------------------------------------------------------------
+(a)xeon-lx-2.4GHz          17/26/63%       5.5/5.6/94%        
+
+(b)xeon-lx-2.8GHz          7/18.5/40%      2.7/2.8/100%                                   7000000
+
+(c)amd-lx                  5.9/6./97%      3.4/3.4/100%      30/32/93%      24/165/13% ?
+
+(d)osf-asc 
+(e')cool                   15/30/50%       13/13/99%
+(f)superosf           
+
+(g)G5-osx-2GHz             14/14.2/98%     6/6.14/99% 
+
+(h)G4-osx-1.25GHz          26/29.7/87%     15.7/38.6/41%               [-O2 -g]
+(i)core-osx-1.83GHz        37/37.8/98%     22/48.4/45%                                 [-g]
+              -O2          10.5/17.4/55%   11.2/41.2/27%                               [-O2 -g]
+(p)ibm-aix-regatta        
+(q)ibm-aix-meso           5.5/16.8/38%    5.7/13.2/43%      32.7/85/39%    29/60/49%
+                          6/11/55%        4/9/44%
+                          6.3/10.6/60%    4/6/64%
+   2 lecture //                    ~2x  4/6/60% Elapsed 7 sec
+   1 write + 2 read //    6.3/10.4/60%  ~2 3.8/6.4/59%  Elapsed < 11 sec                
+   1 write + 3 read //                                 19 sec
+   4 read //                                           6 sec
+--------------------------------------------------------------------------------------------
+
+
+
Index: /tags/V_Nov2007/SophyaLib/Manual/piahelp.tex
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/piahelp.tex	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/piahelp.tex	(revision 3445)
@@ -0,0 +1,2277 @@
+% ----- Liste des groupes de Help ----- 
+List of {\bf piapp} on-line Help groups: 
+\begin{itemize} 
+\item {\bf Commander }  (p. \pageref{Commander}) 
+\item {\bf CxxExecutorCmd }  (p. \pageref{CxxExecutorCmd}) 
+\item {\bf Expr. Arithmetic }  (p. \pageref{ExprZZArithmetic}) 
+\item {\bf Expr. Plotting }  (p. \pageref{ExprZZPlotting}) 
+\item {\bf External Modules }  (p. \pageref{ExternalZModules}) 
+\item {\bf FFT }  (p. \pageref{FFT}) 
+\item {\bf FileIO }  (p. \pageref{FileIO}) 
+\item {\bf Fitting }  (p. \pageref{Fitting}) 
+\item {\bf Func Plot }  (p. \pageref{FuncZPlot}) 
+\item {\bf Graphic-Elts }  (p. \pageref{GraphicZElts}) 
+\item {\bf Graphics }  (p. \pageref{Graphics}) 
+\item {\bf Obj. Display }  (p. \pageref{ObjZZDisplay}) 
+\item {\bf Object Management }  (p. \pageref{ObjectZManagement}) 
+\item {\bf Objects }  (p. \pageref{Objects}) 
+\item {\bf PIACmd }  (p. \pageref{PIACmd}) 
+\item {\bf SkyMapCmd }  (p. \pageref{SkyMapCmd}) 
+\item {\bf SophyaCmd }  (p. \pageref{SophyaCmd}) 
+\item {\bf pawCmd }  (p. \pageref{pawCmd}) 
+\end{itemize} 
+\vspace*{10mm} 
+% ----- Liste de toutes les commandes et help item ----- 
+\vspace{5mm} 
+\begin{center} 
+ \rule{2cm}{1mm} List of {\bf piapp} Help items \rule{2cm}{1mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll}  
+CExpEvaluator & p. \pageref{CExpEvaluator}  & Commander & p. \pageref{Commander}  & ObjectExpressions & p. \pageref{ObjectExpressions}  \\  
+PIConsole & p. \pageref{PIConsole}  & PIDraw3DWdg & p. \pageref{PIDraw3DWdg}  & PIImage & p. \pageref{PIImage}  \\  
+PIScDrawWdg & p. \pageref{PIScDrawWdg}  & RPNEvaluator & p. \pageref{RPNEvaluator}  & Windows & p. \pageref{Windows}  \\  
+autoiniranf & p. \pageref{autoiniranf}  & exitpiapp & p. \pageref{exitpiapp}  & helpfit & p. \pageref{helpfit}  \\  
+helpwindow & p. \pageref{helpwindow}  & shell execute & p. \pageref{shellZexecute}  & stop & p. \pageref{stop}  \\  
+\end{tabular} 
+\end{center} 
+\newpage  
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Commander } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+CExpEvaluator & p. \pageref{CExpEvaluator}  & Commander & p. \pageref{Commander}  & RPNEvaluator & p. \pageref{RPNEvaluator}  \\  
+autoiniranf & p. \pageref{autoiniranf}  & shell execute & p. \pageref{shellZexecute}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf CxxExecutorCmd } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+c++args & p. \pageref{cZZargs}  & c++compile & p. \pageref{cZZcompile}  & c++compileopt & p. \pageref{cZZcompileopt}  \\  
+c++create & p. \pageref{cZZcreate}  & c++createfrf & p. \pageref{cZZcreatefrf}  & c++declareomgvar & p. \pageref{cZZdeclareomgvar}  \\  
+c++exec & p. \pageref{cZZexec}  & c++execfrf & p. \pageref{cZZexecfrf}  & c++import & p. \pageref{cZZimport}  \\  
+c++include & p. \pageref{cZZinclude}  & c++link & p. \pageref{cZZlink}  & c++linkopt & p. \pageref{cZZlinkopt}  \\  
+c++mylibs & p. \pageref{cZZmylibs}  & c++prtlevel & p. \pageref{cZZprtlevel}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Expr. Arithmetic } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+eval & p. \pageref{eval}  &   &  &  &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Expr. Plotting } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+ObjectExpressions & p. \pageref{ObjectExpressions}  & expmeansig & p. \pageref{expmeansig}  & exptovec & p. \pageref{exptovec}  \\  
+fillgd1 & p. \pageref{fillgd1}  & fillgd2 & p. \pageref{fillgd2}  & fillmtx & p. \pageref{fillmtx}  \\  
+fillnt & p. \pageref{fillnt}  & fillvec & p. \pageref{fillvec}  & gdfrvec & p. \pageref{gdfrvec}  \\  
+ntexpcfile & p. \pageref{ntexpcfile}  & ntloop & p. \pageref{ntloop}  & plot2d & p. \pageref{plot2d}  \\  
+plot2dc & p. \pageref{plot2dc}  & plot2de & p. \pageref{plot2de}  & plot2dvec & p. \pageref{plot2dvec}  \\  
+plot2dw & p. \pageref{plot2dw}  & plot3d & p. \pageref{plot3d}  & plot3dw & p. \pageref{plot3dw}  \\  
+projh1d & p. \pageref{projh1d}  & projh2d & p. \pageref{projh2d}  & projprof & p. \pageref{projprof}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf External Modules } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+call & p. \pageref{call}  & link & p. \pageref{link}  & linkff2 & p. \pageref{linkff2}  \\  
+loadmodule & p. \pageref{loadmodule}  &   &  &  &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf FFT } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+fftback & p. \pageref{fftback}  & fftfilter & p. \pageref{fftfilter}  & fftforw & p. \pageref{fftforw}  \\  
+fftfuncfilter & p. \pageref{fftfuncfilter}  &   &  &  &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf FileIO } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+arrtoascii & p. \pageref{arrtoascii}  & fitsadapt & p. \pageref{fitsadapt}  & mtxfrascii & p. \pageref{mtxfrascii}  \\  
+ntfrascii & p. \pageref{ntfrascii}  & openfits & p. \pageref{openfits}  & openppf & p. \pageref{openppf}  \\  
+print & p. \pageref{print}  & readfits & p. \pageref{readfits}  & saveall & p. \pageref{saveall}  \\  
+savefits & p. \pageref{savefits}  & savelist & p. \pageref{savelist}  & saveobjs & p. \pageref{saveobjs}  \\  
+saveppf & p. \pageref{saveppf}  & scanfits & p. \pageref{scanfits}  & swfitstable & p. \pageref{swfitstable}  \\  
+vecfrascii & p. \pageref{vecfrascii}  & writefits & p. \pageref{writefits}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Fitting } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+helpfit & p. \pageref{helpfit}  & crfitfil & p. \pageref{crfitfil}  & crfitfun & p. \pageref{crfitfun}  \\  
+fit & p. \pageref{fit}  & fitlin & p. \pageref{fitlin}  & fitw & p. \pageref{fitw}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Func Plot } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+func & p. \pageref{func}  & func2d & p. \pageref{func2d}  & func2dff & p. \pageref{func2dff}  \\  
+funcff & p. \pageref{funcff}  &   &  &  &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Graphic-Elts } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+addarc & p. \pageref{addarc}  & addarca & p. \pageref{addarca}  & addarrow & p. \pageref{addarrow}  \\  
+addcirc & p. \pageref{addcirc}  & addctext & p. \pageref{addctext}  & addfarc & p. \pageref{addfarc}  \\  
+addfarca & p. \pageref{addfarca}  & addfcirc & p. \pageref{addfcirc}  & addfoval & p. \pageref{addfoval}  \\  
+addfpoly & p. \pageref{addfpoly}  & addfrect & p. \pageref{addfrect}  & addline & p. \pageref{addline}  \\  
+addmarker & p. \pageref{addmarker}  & addoval & p. \pageref{addoval}  & addpoly & p. \pageref{addpoly}  \\  
+addrect & p. \pageref{addrect}  & addtext & p. \pageref{addtext}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Graphics } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+PIConsole & p. \pageref{PIConsole}  & PIDraw3DWdg & p. \pageref{PIDraw3DWdg}  & PIImage & p. \pageref{PIImage}  \\  
+PIScDrawWdg & p. \pageref{PIScDrawWdg}  & Windows & p. \pageref{Windows}  & addaxelabels & p. \pageref{addaxelabels}  \\  
+addtitle & p. \pageref{addtitle}  & drpanel & p. \pageref{drpanel}  & graphicatt & p. \pageref{graphicatt}  \\  
+imagcmap2eps & p. \pageref{imagcmap2eps}  & imagcmap2ps & p. \pageref{imagcmap2ps}  & newwin & p. \pageref{newwin}  \\  
+psclosefile & p. \pageref{psclosefile}  & psgetfilename & p. \pageref{psgetfilename}  & pssetfilename & p. \pageref{pssetfilename}  \\  
+setaxelabels & p. \pageref{setaxelabels}  & setaxesatt & p. \pageref{setaxesatt}  & setinsetlimits & p. \pageref{setinsetlimits}  \\  
+settitle & p. \pageref{settitle}  & stacknext & p. \pageref{stacknext}  & w2eps & p. \pageref{w2eps}  \\  
+w2ps & p. \pageref{w2ps}  & zone & p. \pageref{zone}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Obj. Display } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+bargraph & p. \pageref{bargraph}  & contour & p. \pageref{contour}  & disp & p. \pageref{disp}  \\  
+gfd2d & p. \pageref{gfd2d}  & gfd3d & p. \pageref{gfd3d}  & imag & p. \pageref{imag}  \\  
+imagnav & p. \pageref{imagnav}  & nt2d & p. \pageref{nt2d}  & nt2dci & p. \pageref{nt2dci}  \\  
+nt2dcn & p. \pageref{nt2dcn}  & nt2dvec & p. \pageref{nt2dvec}  & nt3d & p. \pageref{nt3d}  \\  
+ntcont & p. \pageref{ntcont}  & surf & p. \pageref{surf}  & textdrawer & p. \pageref{textdrawer}  \\  
+vecplot & p. \pageref{vecplot}  &   &  &  &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Object Management } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+cd & p. \pageref{cd}  & copy & p. \pageref{copy}  & cp & p. \pageref{cp}  \\  
+del & p. \pageref{del}  & delobjs & p. \pageref{delobjs}  & listdirs & p. \pageref{listdirs}  \\  
+listobjs & p. \pageref{listobjs}  & ls & p. \pageref{ls}  & mkdir & p. \pageref{mkdir}  \\  
+mv & p. \pageref{mv}  & pwd & p. \pageref{pwd}  & rename & p. \pageref{rename}  \\  
+rm & p. \pageref{rm}  & rmdir & p. \pageref{rmdir}  & setdiratt & p. \pageref{setdiratt}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf Objects } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+line2nt & p. \pageref{line2nt}  & line2vec & p. \pageref{line2vec}  & newdt & p. \pageref{newdt}  \\  
+newgfd & p. \pageref{newgfd}  & newh1d & p. \pageref{newh1d}  & newh2d & p. \pageref{newh2d}  \\  
+newmtx & p. \pageref{newmtx}  & newnt & p. \pageref{newnt}  & newprof & p. \pageref{newprof}  \\  
+newprofe & p. \pageref{newprofe}  & newvec & p. \pageref{newvec}  & ntcol2var & p. \pageref{ntcol2var}  \\  
+ntline2var & p. \pageref{ntline2var}  & objaoper & p. \pageref{objaoper}  & vec2var & p. \pageref{vec2var}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf PIACmd } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+exitpiapp & p. \pageref{exitpiapp}  & helpwindow & p. \pageref{helpwindow}  & stop & p. \pageref{stop}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf SkyMapCmd } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+alm2cl & p. \pageref{alm2cl}  & alm2map & p. \pageref{alm2map}  & cl2llcl & p. \pageref{cl2llcl}  \\  
+cl2map & p. \pageref{cl2map}  & clmean & p. \pageref{clmean}  & clmult & p. \pageref{clmult}  \\  
+clop & p. \pageref{clop}  & clrebin & p. \pageref{clrebin}  & crmapmask & p. \pageref{crmapmask}  \\  
+crmaskfrmap & p. \pageref{crmaskfrmap}  & map2alm & p. \pageref{map2alm}  & map2cl & p. \pageref{map2cl}  \\  
+map2double & p. \pageref{map2double}  & map2float & p. \pageref{map2float}  & map2local & p. \pageref{map2local}  \\  
+map2map & p. \pageref{map2map}  & mapcover & p. \pageref{mapcover}  & mapmult & p. \pageref{mapmult}  \\  
+mapop & p. \pageref{mapop}  & maproj & p. \pageref{maproj}  & mapstat & p. \pageref{mapstat}  \\  
+maskmap & p. \pageref{maskmap}  & resol2szidx & p. \pageref{resol2szidx}  & settypemap & p. \pageref{settypemap}  \\  
+szidx2resol & p. \pageref{szidx2resol}  & typemap & p. \pageref{typemap}  &   &   \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf SophyaCmd } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+errorellipse & p. \pageref{errorellipse}  & mollgrid & p. \pageref{mollgrid}  & setprjmoldefval & p. \pageref{setprjmoldefval}  \\  
+\end{tabular} 
+\end{center} 
+\vspace{6mm} 
+\begin{center} 
+ \rule{2cm}{0.5mm} \makebox[60mm]{{ \bf pawCmd } help group} \rule{2cm}{0.5mm} \\ 
+\vspace{3mm} 
+\begin{tabular}{llllll} 
+h/2d/geth & p. \pageref{hZ2dZgeth}  & h/cadd & p. \pageref{hZcadd}  & h/cmult & p. \pageref{hZcmult}  \\  
+h/copy & p. \pageref{hZcopy}  & h/deriv & p. \pageref{hZderiv}  & h/err & p. \pageref{hZerr}  \\  
+h/get\_vec & p. \pageref{hZgetZvec}  & h/integ & p. \pageref{hZinteg}  & h/oper & p. \pageref{hZoper}  \\  
+h/plot/2d & p. \pageref{hZplotZ2d}  & h/put\_vec & p. \pageref{hZputZvec}  & h/rebin & p. \pageref{hZrebin}  \\  
+h/set/cont & p. \pageref{hZsetZcont}  & h/set/err & p. \pageref{hZsetZerr}  & herr/mean & p. \pageref{herrZmean}  \\  
+herr/variance & p. \pageref{herrZvariance}  & n/assoc/col & p. \pageref{nZassocZcol}  & n/copy & p. \pageref{nZcopy}  \\  
+n/merge & p. \pageref{nZmerge}  & n/merge/col & p. \pageref{nZmergeZcol}  & n/pl & p. \pageref{nZpl}  \\  
+n/plot & p. \pageref{nZplot}  & n/proj & p. \pageref{nZproj}  & n/read & p. \pageref{nZread}  \\  
+n/scan & p. \pageref{nZscan}  & reset & p. \pageref{reset}  & v/deriv & p. \pageref{vZderiv}  \\  
+v/integ & p. \pageref{vZinteg}  & v/sort & p. \pageref{vZsort}  &   &   \\  
+\end{tabular} 
+\end{center} 
+% ----- Liste des commandes dans chaque groupe ----- 
+\newpage 
+\subsection{Commander} \label{Commander} 
+Basic (generic) interpreter (class SOPHYA::Commander) builtin commands 
+ \\[2mm]  \noindent 
+\piahelpitem{CExpEvaluator} \label{CExpEvaluator} 
+\begin{verbatim} 
+> Evaluation of C-like expression (used in V = C-like-Expression) 
+   >>> Arithmetic operators, parenthesis ( + - * / ) 
+   >>> Functions : sqrt fabs floor hypot 
+   ...  exp log log10 pow  ; sinh cosh tanh 
+   ...  sin cos tan asin acos atan atan2  
+   ...  rand01()  randpm1() gaurand() 
+   >>> Constants : Pi = M_PI E = M_E 
+   Example: x = 5.*(2.+sin(0.3*Pi))
+\end{verbatim} 
+\piahelpitem{Commander} \label{Commander} 
+\begin{verbatim} 
+>>> (Commander) Interpreter's keywords : 
+  > set varname string     # To set a variable, $varname 
+  > unset varname          # clear variable definition 
+  > rpneval varname RPNExpression  # Reverse Polish Notation evaluation 
+  > varname = ArithmeticExpression # C-like Expression evaluation   
+  > varname = 'String'     # Set variable vname  
+  > var2words varname wordvarname [sep]    # to break varname into words  
+  > echo string            # output string 
+  > echo2file filename string # Append the string to the specified file 
+  > alias name string      # define a command alias 
+  > foreach varname ( string-list ) # Loop 
+  > for varname i1:i2[:di]      # Integer loop  
+  > for varname f1:f2[:df]      # Float loop  
+  > forinfile varname FileName  # Loop over lines in file 
+  > end                         # end loops 
+  > if ( test ) then  # Conditional test : a == != < > <= >= b 
+  > else          # Conditional  
+  > endif         # End of conditional if bloc 
+  > break         # Delete (clears) all test and loop blocs 
+  > return        # Stops command execution from a file 
+  > defscript endscript # Command script definition 
+  > listvars      # List of variable names and values 
+  > listalias     # List of alias names and values 
+  > listcommands  # List of all known commands 
+  > listscripts   # List of all known scripts 
+  > clearcript    # Clear a script definition 
+  > thrlist       # List of command execution threads (& as the last character) 
+  > clearthrlist  # Removes finished threads from the list  
+  > killthr Id    # Try to stop a given thread (ThrId=id) by sending SIGUSR1 
+  > cancelthr Id  # Try to cancel a given thread (ThrId=id)  
+  > waitthr       # Waits until all active threads have finished (join()) 
+  > exec filename # Execute commands from file 
+  > help <command_name>  # <command_name> usage info 
+  > sleep nsec  # sleep nsec seconds 
+  > readstdin varname      # reads a line from stdin into $varname 
+  > timingon  timingoff traceon  traceoff 
+
+\end{verbatim} 
+\piahelpitem{RPNEvaluator} \label{RPNEvaluator} 
+\begin{verbatim} 
+ Reverse Polish Notation (HP calculator like) expression evaluation 
+  >> Stack: 
+     ... (4) (3) z=(2) y=(1) x=(0)=Stack.Top() 
+  >> Examples:  
+  - sin(PI/6): pi 6 / sin 
+  - 1*2*...*5: 1 2 3 4 5 product 
+  - x=x+y: x = $x $y * 
+  >>> Stack operations : 
+      print x<>y pop push (duplicate x) 
+  >>> Constants (Cst pushed to stack): 
+      pi e 
+  >>> Arithmetic operators (x,y) --> x@y 
+      + - * / % ( (int)y % (int)x )
+  >>> F(X): x --> F(x) 
+      chs sqrt sq log log10 exp  
+      fabs  floor ceil 
+      cos sin tan acos asin atan deg2rad rad2deg 
+  >>> F(X,Y): (x,y) --> F(x,y) 
+      pow atan2 
+  >>> F(): random number generators 
+      rand (flat 0..1) norand (normal/gaussian) 
+  >>> Stack sum/product/mean/sigma/sigma^2 
+      sum product mean sigma sigma2 sigmean (y->sigma x->mean) 
+
+\end{verbatim} 
+\piahelpitem{autoiniranf} \label{autoiniranf} 
+\begin{verbatim} 
+> Automatic random number generator initialisation
+   by Auto_Ini_Ranf(int lp) 
+   Usage: autoiniranf
+\end{verbatim} 
+\piahelpitem{shell execute} \label{shellZexecute} 
+\begin{verbatim} 
+> shell  command_string  # Execute  shell command
+> cshell command_string  # Execute cshell command
+---Examples:
+  > shell ls
+  > cshell echo '$LD_LIBRARY_PATH'; map2cl -h; ls
+  > shell myfile.csh [arg1] [arg2] [...]
+    (where the first line of "myfile.csh" is "#!/bin/csh")
+
+\end{verbatim} 
+\subsection{CxxExecutorCmd} \label{CxxExecutorCmd} 
+\noindent 
+\piacommand{c++args} \label{cZZargs} 
+\begin{verbatim} 
+c++args: Define user function arguments for c++exec and c++execfrf
+Usage: c++args arg1 arg2 arg3 ...
+       c++args -? : give current arguments
+       c++args    : reset current arguments
+\end{verbatim} 
+\piacommand{c++compile} \label{cZZcompile} 
+\begin{verbatim} 
+c++compile: compile a file (file.cc -> file.so)
+Usage: c++compile file
+Warning: give "file" or "file.so" to create "file.so" from "file.cc"
+       : to be used before c++link
+\end{verbatim} 
+\piacommand{c++compileopt} \label{cZZcompileopt} 
+\begin{verbatim} 
+c++compileopt: add personnal compile options
+Usage: c++compileopt -g -O5 -IMy_Inc_Dir ...
+       c++compileopt -? : list current additionnal compile options
+       c++compileopt    : reset to no additionnal compile options
+Warning: to be used before c++create c++compile c++exec ...
+\end{verbatim} 
+\piacommand{c++create} \label{cZZcreate} 
+\begin{verbatim} 
+c++create: create a file "file.cc" to be used by spiapp
+Usage: c++create file.cc func c++ user code...
+
+\end{verbatim} 
+\piacommand{c++createfrf} \label{cZZcreatefrf} 
+\begin{verbatim} 
+c++createfrf: create a file "file.cc" to be used by spiapp
+        with a user file code "fileuser.cc"
+        and an optional user function code "fileuserfct.cc"
+Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]
+
+\end{verbatim} 
+\piacommand{c++declareomgvar} \label{cZZdeclareomgvar} 
+\begin{verbatim} 
+c++declareomgvar: Activate/Deactivate ObjectManager variables declaration 
+Usage: c++declareomgvar [false/true] 
+   if true, the ObjectManager variables are declared as $varname 
+   no arguments: display the current status of the flag (default=false
+
+\end{verbatim} 
+\piacommand{c++exec} \label{cZZexec} 
+\begin{verbatim} 
+c++exec: Execute the following c++ user code
+Usage: c++exec c++ user code
+Warning: c++ user code can be found in "TmpDir/cxx_spiapp.h"
+         total generated code can be found in "TmpDir/cxx_spiapp.cc"
+\end{verbatim} 
+\piacommand{c++execfrf} \label{cZZexecfrf} 
+\begin{verbatim} 
+c++execfrf: Execute c++ user_code [user_function_code]
+Usage: c++execfrf fileuser.cc [fileuserfct.cc]
+Warning: total generated code can be found in "TmpDir/cxx_spiapp.cc"
+\end{verbatim} 
+\piacommand{c++import} \label{cZZimport} 
+\begin{verbatim} 
+c++import: Sophya additionnal modules to be use in C++ executor
+Usage: c++import module1 ... : set list of modules to be used by executor
+       c++import all : set all modules known by executor
+       c++import     : reset to no additionnal module
+       c++import -?  : list modules currently used in executor
+       c++import -?? : list of available modules for executor
+Warning: to be used before c++create c++compile c++exec ...
+\end{verbatim} 
+\piacommand{c++include} \label{cZZinclude} 
+\begin{verbatim} 
+c++include: add personnal includes to be used by executor
+Usage: c++include myinc1.h myinc2.h ...
+       c++include -? : list current additionnal include files
+       c++include    : reset to no additionnal include files
+Warning: to be used before c++create c++compile c++exec...
+\end{verbatim} 
+\piacommand{c++link} \label{cZZlink} 
+\begin{verbatim} 
+c++link: link function "func" in file.so to spiapp
+Usage: c++link file.so func
+\end{verbatim} 
+\piacommand{c++linkopt} \label{cZZlinkopt} 
+\begin{verbatim} 
+c++linkopt: add personnal link options
+Usage: c++linkopt -g -O5 ...
+       c++linkopt -? : list current additionnal link options
+       c++linkopt    : reset to no additionnal link options
+Warning: to be used before c++create c++compile c++exec ...
+\end{verbatim} 
+\piacommand{c++mylibs} \label{cZZmylibs} 
+\begin{verbatim} 
+c++mylibs: add personnal libraries
+Usage: c++mylibs -LMy_Lib_Dir -lmylib1 -lmylib2 ...
+       c++mylibs -? : list current additionnal libraries
+       c++mylibs    : reset to no additionnal libraries
+Warning: to be used before c++create c++compile c++exec ...
+\end{verbatim} 
+\piacommand{c++prtlevel} \label{cZZprtlevel} 
+\begin{verbatim} 
+c++prtlevel: Print level
+Usage: c++prtlevel prtlevel
+       prtlevel=0 : minimum printing
+       prtlevel=1 : + compiler/linker output
+       prtlevel=2 : + full infos (default)
+\end{verbatim} 
+\subsection{Expr. Arithmetic} \label{ExprZZArithmetic} 
+\noindent 
+\piacommand{eval} \label{eval} 
+\begin{verbatim} 
+Compute arithmetic expression
+
+ Usage: eval resultvarname arithmetic expression....
+  resultvarname: store result in variable resultvarname
+    - If first character is not alphabetic, just print result
+  arithmetic expression:
+      ex: x + sqrt(y)+z +3.14    (x,y,z are variables)
+      ex: $x + sqrt($y)+$z +3.14 (x,y,z are variables)
+      ex: 360 * M_PI / 180.
+\end{verbatim} 
+\subsection{Expr. Plotting} \label{ExprZZPlotting} 
+\noindent 
+\piahelpitem{ObjectExpressions} \label{ObjectExpressions} 
+\begin{verbatim} 
+Any mathematical expression (math.h) with object variables can be used
+  ------ Object Variable names (double) -------- 
+  (_nl is the table line number or the sequential index)
+- NTuple: ntuple variable names,_nl
+- Histo1D/HProf: i,x,val,err,nb,_nl
+- Histo2D: i,j,x,y,val,err,_nl
+- HistoErr: i,x,val,err2,nb,_nl
+- Histo2DErr: i,j,x,y,val,err2,nb,_nl
+- Vector/Matrix/Image: n,r,c,val,real,imag,mod,phas,_nl
+- TArray: n,x,y,z,t,u,val,real,imag,mod,phas,_nl
+- GeneralFitData: x0,ex0 x1,ex1 ...  xn,exn   y,ey   ok  ,_nl
+- SphereThetaPhi/SphereHEALPix/SphereECP/LocalMap: 
+-         i,k,val,real,imag,mod,phas,teta,phi,_nl
+- FITS Binary/ASCII table: fits column names,_nl
+  ------ Other parameters -------- 
+Loop parameters can be specified as I1[:I2[:DI]] for(int i=I1; i<I2; i+=DI)
+The default Cut() expression in true (=1) for all
+
+ Related commands: plot2d plot2de plot2dw plot3d plot3dw
+         projh1d projh2d  projprof fillvec fillmtx 
+         fillnt fillgd1 fillgd2 ntloop exptovec ... 
+\end{verbatim} 
+\piacommand{expmeansig} \label{expmeansig} 
+\begin{verbatim} 
+Computes Mean/Sigma (+Min/Max) for an expression X=f(Object)
+ Usage: expmeansig nameobj f_X() [Cut() loop_param]
+  Related commands: exptovec ntloop fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{exptovec} \label{exptovec} 
+\begin{verbatim} 
+Creates and Fills a Vector with X=f(Object)
+ Usage: exptovec namevec nameobj f_X() [Cut() graphic_attributes loop_param]
+  Related commands: ntloop fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{fillgd1} \label{fillgd1} 
+\begin{verbatim} 
+Creates and Fills a GeneralFitData with (X=f(Object), Y=g(...), ErrY=h(...))
+ Usage: fillgd1 namegfd nameobj f_X() g_Y() h_ErrY() [Cut() loop_param]
+  Related commands: ntloop fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{fillgd2} \label{fillgd2} 
+\begin{verbatim} 
+Creates and Fills a GeneralFitData with 
+            (X=f(Object), Y=g(...), Z=h(...)) ErrZ=k(...)
+ Usage: fillgd2 namegfd nameobj f_X() g_Y() h_Z() k_ErrZ() 
+                                [Cut() loop_param]
+  Related commands: ntloop fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{fillmtx} \label{fillmtx} 
+\begin{verbatim} 
+Fills a Matrix M(Line=g_Y(Object)+0.5, Col=f_X(Object)+0.5)) =  h_V(Object) 
+ Usage: fillmtx namevec nameobj f_X() g_Y() h_V() 
+                [Cut() graphic_attributes loop_param]
+  Related commands: fillvec fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{fillnt} \label{fillnt} 
+\begin{verbatim} 
+Creates and Fills an NTuple(x,y,z,t) with 
+            (X=f(Object),Y=g(...),Z=h(...),T=k(...))
+ Usage: fillnt nameobj f_X() g_Y() h_Z() k_T() [Cut() nameNt loop_param]
+  Related commands: ntloop plot2d projh1d projh2d projprof 
+  Related commands: fillvec fillmtx ntloop exptovec fillgd1 
+                    fillgd2 ObjectExpressions ...
+\end{verbatim} 
+\piacommand{fillvec} \label{fillvec} 
+\begin{verbatim} 
+Fills a Vector V((int)(f_X(Object)+0.5)) =  h_V(Object) 
+ Usage: fillvec namevec nameobj f_X() h_V() [Cut() graphic_attributes loop_param]
+  Related commands: fillmtx fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{gdfrvec} \label{gdfrvec} 
+\begin{verbatim} 
+Fills a GeneralFitData with vectors X,Y,Z,EZ
+ Usage: gdfrvec namegfd X Y
+ Usage: gdfrvec namegfd X Y ! EY
+ Usage: gdfrvec namegfd X Y Z
+ Usage: gdfrvec namegfd X Y Z EZ
+  Related commands: fillgd1 fillgd2 ...
+\end{verbatim} 
+\piacommand{ntexpcfile} \label{ntexpcfile} 
+\begin{verbatim} 
+Creates a C-File with declarations suitable to be used for ntloop
+ Usage: ntexpcfile nameobj CFileName FuncName 
+  Related commands: ntloop
+\end{verbatim} 
+\piacommand{ntloop} \label{ntloop} 
+\begin{verbatim} 
+Loops over an Object NTupleInterface calling a function from a C-file 
+and optionaly fills an NTuple(x,y,z,t) with 
+     (X=f(Object),Y=g(...),Z=h(...),T=k(...))
+ Usage: ntloop nameobj CFileName FuncName [NtupleName loop_param]
+  Related commands: fillvec fillmtx fillnt fillgd1 fillgd2 
+  Related commands: exptovec ntexpcfile fillnt ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot2d} \label{plot2d} 
+\begin{verbatim} 
+Plots (2D) Y=g(Object) vs. X=f(Object) --- Object Variable names (double) :
+ Usage: plot2d nameobj f_X() g_Y() [f_Cut() graphic_attributes loop_param]
+  Related commands: plot2de plot2dw plot3d plot3dw ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot2dc} \label{plot2dc} 
+\begin{verbatim} 
+Plots (2D) Y=g(Object) vs. X=f(Object) with Color ColIndex=h(Object) 
+ Usage: plot2dc nameobj f_X() g_Y() h_Col() [Cut() graphic_attributes loop_param]
+  Related commands: plot2d plot2dw plot3d ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot2de} \label{plot2de} 
+\begin{verbatim} 
+Plots (2D) Y=g(Object) vs. X=f(Object) with error bars eX/Y=f_ErrX/Y(Object) 
+ Usage: plot2de nameobj f_X() g_Y() f_ErrX() f_ErrY() [f_Cut() 
+                graphic_attributes loop_param]
+  Related commands: plot2d plot2dw plot3d ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot2dvec} \label{plot2dvec} 
+\begin{verbatim} 
+Creates and displays a flow chart from ntuple expressions 
+ Usage: plot2dvec ntuple expx expy expvx expvy [cut graphic_att loop_par]
+\end{verbatim} 
+\piacommand{plot2dw} \label{plot2dw} 
+\begin{verbatim} 
+Plots (2D) Y=g(Object) vs. X=f(Object) with Weight W=h(Object) 
+ Usage: plot2dw nameobj f_X() g_Y() h_Wt() [Cut() graphic_attributes loop_param]
+  Related commands: plot2d plot2dc plot3d ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot3d} \label{plot3d} 
+\begin{verbatim} 
+Plots (3D) Z=h(Object) vs. Y=g(Object) vs. X=f(Object)
+ Usage: plot3d nameobj f_X() g_Y() h_Z() [Cut() graphic_attributes loop_param]
+  Related commands: plot2d plot2de plot3dw ObjectExpressions ...
+\end{verbatim} 
+\piacommand{plot3dw} \label{plot3dw} 
+\begin{verbatim} 
+Plots (3D) Z=h(Object) vs. Y=g(Object) vs. X=f(Object) with Weight W=k(Object)  
+ Usage: plot3d nameobj f_X() g_Y() h_Z() k_Wt() [Cut() graphic_attributes loop_param]
+  Related commands: plot2d plot2dw plot3d ObjectExpressions ...
+\end{verbatim} 
+\piacommand{projh1d} \label{projh1d} 
+\begin{verbatim} 
+Projects X=f(Object) with weight WT=h(Object) into a 1D histogram 
+ Usage: projh1d nameh1d nameobj f_X() [h_WT()=1. Cut() graphic_attributes loop_param]
+   Histo1D nameh1d is created if necessary 
+  Related commands: projh2d projprof ObjectExpressions ...
+\end{verbatim} 
+\piacommand{projh2d} \label{projh2d} 
+\begin{verbatim} 
+Projects (X=f(Object),Y=g(Object)) with weight WT=h(Object) into a 2D histogram 
+ Usage: projh2d nameh2d nameobj f_X() g_Y() [h_WT()=1. Cut() 
+                graphic_attributes loop_param]
+   Histo2D nameh2d is created if necessary 
+  Related commands: projh1d projprof ObjectExpressions ...
+\end{verbatim} 
+\piacommand{projprof} \label{projprof} 
+\begin{verbatim} 
+Projects (X=f(Object),Y=g(Object)) with weight WT=h(Object) into a profile histogram 
+ Usage: projprof nameprof nameobj f_X() g_Y() [h_WT()=1. Cut() 
+                 graphic_attributes loop_param]
+   HProf nameprof is created if necessary 
+  Related commands: projh1d projh2d ObjectExpressions ...
+\end{verbatim} 
+\subsection{External Modules} \label{ExternalZModules} 
+Dynamic load (shared object modules) management command group 
+ \\[2mm]  \noindent 
+\piacommand{call} \label{call} 
+\begin{verbatim} 
+Dynamically linked user function call 
+ Usage: call userf [arg1 arg2 ...]
+  User function : f(vector<string>& args)
+  Related commands: link
+\end{verbatim} 
+\piacommand{link} \label{link} 
+\begin{verbatim} 
+Dynamic linking of compiled user functions 
+  Usage: link fnameso f1 [f2 f3]
+  fnameso: Shared-object file name, f1,f2,f3 : User function names 
+  Related commands: call loadmodule linkff2
+\end{verbatim} 
+\piacommand{linkff2} \label{linkff2} 
+\begin{verbatim} 
+Dynamic linking of compiled user functions (Set 2)
+  Usage: linkff2 fnameso f1 [f2 f3]
+  fnameso: Shared-object file name, f1,f2,f3 : User function names 
+  Related commands: call link loadmodule
+\end{verbatim} 
+\piacommand{loadmodule} \label{loadmodule} 
+\begin{verbatim} 
+To load and initialize modules 
+  Usage: loadmodule fnameso modulename
+  Related commands: link
+\end{verbatim} 
+\subsection{FFT} \label{FFT} 
+\noindent 
+\piacommand{fftback} \label{fftback} 
+\begin{verbatim} 
+FFT on a vector -> computes backward Fourier transform 
+ Usage: fftback vecSpec vecSig [graphic_att] [C/Z] 
+ vecSig = FFTBackward(vecSpec) 
+ vecSpec: Input data vector of type complex<r_8> 
+ vecSig:  Output Data vector of type r_8 (default) 
+    or complex<r_8> if C/Z specified or 
+    vecSpec computed by fftforw on a complex vector
+ See also : fftforw fftfilter fftfuncfilter 
+\end{verbatim} 
+\piacommand{fftfilter} \label{fftfilter} 
+\begin{verbatim} 
+Filter (multiply) vecSpec (vector complex<r_8>) by Filter (vector<r_8>)
+ Usage: fftfilter vecSpec FilterVec vecFiltSpec [graphic_att] 
+   vecFiltSpec(i) = vecSpec(i) * complex(FilterVec(i),0) 
+ See also : fftforw fftbackw fftfuncfilter 
+\end{verbatim} 
+\piacommand{fftforw} \label{fftforw} 
+\begin{verbatim} 
+FFT on a vector -> computes forward Fourier transform
+ Usage: fftforw vecSig vecSpec [graphic_att] 
+ vecSpec = FFTForward(vecSig) 
+ vecSig: Input data vector of type r_8 or complex<r_8> 
+ vecSpec: Output data vector of type complex<r_8> 
+ See also : fftback fftfilter fftfuncfilter 
+\end{verbatim} 
+\piacommand{fftfuncfilter} \label{fftfuncfilter} 
+\begin{verbatim} 
+Filter (multiply) vecSpec (vector complex<r_8>) by FilterFunc(i) 
+ Usage: fftfilter vecSpec FilterFunc vecFiltSpec [graphic_att] 
+   vecFiltSpec(i) = vecSpec(i) * complex(FilterFunc(i),0) 
+ See also : fftforw fftbackw fftfilter 
+\end{verbatim} 
+\subsection{FileIO} \label{FileIO} 
+\noindent 
+\piacommand{arrtoascii} \label{arrtoascii} 
+\begin{verbatim} 
+Writes an array (TArray<T>) to an ASCII file 
+ Usage: arrtoascii array_name file_name
+  Related commands:  mtxfrascii vecfrascii ntfrascii 
+\end{verbatim} 
+\piacommand{fitsadapt} \label{fitsadapt} 
+\begin{verbatim} 
+fitsadapt: NTuple adaptor for Binary and ASCII Fits table
+Usage: fitsadapt fitsfile [nomobj hdu buflen[,bufsens,lp]]
+ fitsfile : Fits file name
+ nomobj : Object name (needed if file name misleading as C++ variable)
+ hdu : Fits HDU (if <=0 take first binary/ascii table)
+ buflen[,bufsens,lp] : buffer length (sens) for fits reading (default is 100,1,0)
+ See also  scanfits writefits readfits 
+\end{verbatim} 
+\piacommand{mtxfrascii} \label{mtxfrascii} 
+\begin{verbatim} 
+Reads a matrix from an ASCII file (TMatrix<r_8>)
+ Usage: mtxfrascii mtx_name file_name [CommChar Separator]
+  Related commands: arrtoascii vecfrascii ntfrascii 
+\end{verbatim} 
+\piacommand{ntfrascii} \label{ntfrascii} 
+\begin{verbatim} 
+Fills an existing NTuple or DataTable from ASCII table file
+ Usage: ntfrascii nt_name file_name [def_init_val]
+  Related commands: ntloop fillnt 
+\end{verbatim} 
+\piacommand{openfits} \label{openfits} 
+\begin{verbatim} 
+openfits: alias for readfits 
+
+\end{verbatim} 
+\piacommand{openppf} \label{openppf} 
+\begin{verbatim} 
+Reads all or some objects from a PPF file
+  Usage: (1) openppf filename 
+     Or  (2) openppf -s filename (2)
+     Or  (3) openppf filename objname1 [ objname2 ...]
+  The first form reads all objects at NameTags,
+    or all objects if the file has no NameTags.
+  The third reads only the objects with the specified nametags
+  Related commands: saveppf saveall savelist
+\end{verbatim} 
+\piacommand{print} \label{print} 
+\begin{verbatim} 
+Prints an object 
+ Usage: print nameobj [prtlev]
+ prtlev = 0,1,2...  default: prtlev=0
+\end{verbatim} 
+\piacommand{readfits} \label{readfits} 
+\begin{verbatim} 
+readfits: Read one or all HDU's of a fits file 
+Usage: readfits FileName [num_hdu] 
+ num_hdu=1,..,NbHDU (uses FitsManager) 
+See also  scanfits writefits fitsadapt swfitstable 
+\end{verbatim} 
+\piacommand{saveall} \label{saveall} 
+\begin{verbatim} 
+Saves all objects into a PPF file 
+ Usage: saveall filename
+  Related commands: saveobj savelist openppf
+\end{verbatim} 
+\piacommand{savefits} \label{savefits} 
+\begin{verbatim} 
+savefits: alias for writefits 
+
+\end{verbatim} 
+\piacommand{savelist} \label{savelist} 
+\begin{verbatim} 
+
+ Usage: savelist objname1 [objname2 ...] filename
+  Related commands: saveobj openppf
+\end{verbatim} 
+\piacommand{saveobjs} \label{saveobjs} 
+\begin{verbatim} 
+Saves objects with names matching a pattern into a
+  PPF file (pattern: x?y*) - Alias saveppf
+Usage: saveobjs nameobjpattern filename
+  Related commands: saveppf savelist saveall openppf 
+\end{verbatim} 
+\piacommand{saveppf} \label{saveppf} 
+\begin{verbatim} 
+Saves objects with names matching a pattern into a
+  PPF file (pattern: x?y*) - Alias saveppf
+Usage: saveppf nameobjpattern filename
+  Related commands: saveobjs savelist saveall openppf
+\end{verbatim} 
+\piacommand{scanfits} \label{scanfits} 
+\begin{verbatim} 
+scanfits: scan fits files and print information on each HDU
+Usage: scanfits FileName [slev=0...3]
+slev=1,3: header keywords , slev=2,3: try to read each HDU
+See also: readfits writefits fitsadapt 
+\end{verbatim} 
+\piacommand{swfitstable} \label{swfitstable} 
+\begin{verbatim} 
+swfitstable: Creates/read an SwFitsDataTable from a fits file
+   SwFitsDataTable is a table which uses the BINARY-TBL
+   of the fits file as swap space - useful for large tables
+Usage: swfitstable FileName [num_hdu=2] [segsize=512]
+See also: readfits scanfits
+\end{verbatim} 
+\piacommand{vecfrascii} \label{vecfrascii} 
+\begin{verbatim} 
+Reads a vector from an ASCII file (TVector<r_8>)
+ Usage: vecfrascii vec_name file_name
+  Related commands: arrtoascii mtxfrascii ntfrascii [CommChar Separator]
+\end{verbatim} 
+\piacommand{writefits} \label{writefits} 
+\begin{verbatim} 
+writefits: Write objects to a fits file 
+Usage: writefits nameobj/pattern FileName 
+See also: scanfits readfits fitsadapt 
+\end{verbatim} 
+\subsection{Fitting} \label{Fitting} 
+\noindent 
+\piahelpitem{helpfit} \label{helpfit} 
+\begin{verbatim} 
+
+//////////////////////////////////////////////////////////////////////    
+| --------------- 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    
+|    
+//////////////////////////////////////////////////////////////////////    
+\end{verbatim} 
+\piacommand{crfitfil} \label{crfitfil} 
+\begin{verbatim} 
+Creation de fichier C pour function utilisateur du fit
+ Usage: crfitfil file func nvar npar
+  Related commands: fit fitw fitlin crfitfun
+\end{verbatim} 
+\piacommand{crfitfun} \label{crfitfun} 
+\begin{verbatim} 
+Creation et link de function utilisateur pour le fit
+ Usage: crfitfun file func nvar npar
+  Related commands: fit fitw fitlin crfitfil
+\end{verbatim} 
+\piacommand{fit} \label{fit} 
+\begin{verbatim} 
+Fitting function to DataObjects (Histo, Histo2D, Vector, ...)
+ Usage: fit nomobj func [Options]
+ [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]
+  Related commands: fitw fitlin crfitfun crfitfil
+\end{verbatim} 
+\piacommand{fitlin} \label{fitlin} 
+\begin{verbatim} 
+Linear Fitting of Polynoms to DataObjects
+ Usage: fitlin nomobj func [o:... o:...]
+  Related commands: fit fitw crfitfun crfitfil
+\end{verbatim} 
+\piacommand{fitw} \label{fitw} 
+\begin{verbatim} 
+Fitting function to DataObjects with Interactive Window Help
+ Usage: fitw nomobj func [Options]
+ [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]
+  Related commands: fit fitlin crfitfun crfitfil
+\end{verbatim} 
+\subsection{Func Plot} \label{FuncZPlot} 
+\noindent 
+\piacommand{func} \label{func} 
+\begin{verbatim} 
+Displays a function y=f(x) (Fills a vector with function values)
+ Usage: func f(x) xmin xmax [npt graphic_attributes]
+  Related commands: funcff func2d func2dff 
+\end{verbatim} 
+\piacommand{func2d} \label{func2d} 
+\begin{verbatim} 
+Displays a function z=f(x,y) (Fills a matrix with function values)
+ Usage: func2d f(x,y) xmin xmax nptx ymin ymax npty [graphic_attributes]
+  Related commands: func
+\end{verbatim} 
+\piacommand{func2dff} \label{func2dff} 
+\begin{verbatim} 
+Displays a function z=f(x,y) from a C-file (Fills a matrix with function values)
+ Usage: func2dff C-FileName FunctionName xmin xmax nptx ymin ymax npty [gr_att]
+Related commands: func funcff func2d 
+\end{verbatim} 
+\piacommand{funcff} \label{funcff} 
+\begin{verbatim} 
+Displays a function y=f(x) from a C-file (Fills a vector with function values)
+ Usage: funcff C-FileName FunctionName xmin xmax [npt graphic_attributes]
+  Related commands: func func2d func2dff 
+\end{verbatim} 
+\subsection{Graphic-Elts} \label{GraphicZElts} 
+\noindent 
+\piacommand{addarc} \label{addarc} 
+\begin{verbatim} 
+Adds an arc to the current graphic object
+ defined by 3 points (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added arcs
+ Alt<E> to remove the added element
+  Usage: addarc x1 y1 x2 y2 x3 y3 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addfcirc addfarc addarca addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addarca} \label{addarca} 
+\begin{verbatim} 
+Adds an arc to the current graphic object
+ defined by the circle (center+radius), start angle and angular extension
+ Angles are specified in degrees
+  Usage: addarca xc yc r a0deg dadeg [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addfarca addarc ...
+\end{verbatim} 
+\piacommand{addarrow} \label{addarrow} 
+\begin{verbatim} 
+Adds an arrow to the current graphic object
+ at the specified position (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added lines
+ Alt<E> to remove the added element
+  Usage: addarrow x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addline addtext addrect addfrect 
+       addmarker addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addcirc} \label{addcirc} 
+\begin{verbatim} 
+Adds a circle to the current graphic object
+ with the specified center and radius (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added circles
+ Alt<E> to remove added element
+  Usage: addcirc xcenter ycenter radius [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addctext} \label{addctext} 
+\begin{verbatim} 
+Adds a composite text string with superscript and subscripts 
+ at the specified position (+ color/font/pos/dir attributes) 
+  Usage: addctext x y Text sUp sDown [ColFontPosAtt] [UpDownFontAtt] [fgnc]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addrect ...
+      (See command addtext and graphicatt for more details)
+\end{verbatim} 
+\piacommand{addfarc} \label{addfarc} 
+\begin{verbatim} 
+Adds a filled arc to the current graphic object
+ defined by 3 points (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added arcs
+ Alt<E> to remove added element
+  Usage: addarc x1 y1 x2 y2 x3 y3 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addfcirc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addfarca} \label{addfarca} 
+\begin{verbatim} 
+Adds a filled arc to the current graphic object
+ defined by the circle (center+radius), start angle and angular extension
+ Angles are specified in degrees
+  Usage: addfarca xc yc r a0deg dadeg [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarca addarc ...
+\end{verbatim} 
+\piacommand{addfcirc} \label{addfcirc} 
+\begin{verbatim} 
+Adds a filled circle to the current graphic object
+ with the specified center and radius (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added circles
+ Alt<E> to remove added element
+  Usage: addcirc xcenter ycenter radius [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addfoval} \label{addfoval} 
+\begin{verbatim} 
+Adds a filled oval (ellipse) to the current graphic object
+ centered on xc,yc - semi-axis ds,dy (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added rectangle
+ Alt<E> to remove added element
+  Usage: addfoval xc yc dx dy [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addoval addline addarrow addfrect addcirc addfcirc
+       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addfpoly} \label{addfpoly} 
+\begin{verbatim} 
+Adds a filled polygon to the current graphic object
+  Usage: addploy 'x1,y1 x2,y2 x3,y3 ...' [GraphicAtt] [fgnc=false/true]
+  Coordinates specified as pairs x,y in a single word (use simple or double quotes
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addfcirc addfarc  graphicatt
+\end{verbatim} 
+\piacommand{addfrect} \label{addfrect} 
+\begin{verbatim} 
+Adds a filled rectangle to the current graphic object
+ between the specified positions (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added rectangle
+ Alt<E> to remove added element
+  Usage: addfrect x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addrect
+       addcirc addfcirc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addline} \label{addline} 
+\begin{verbatim} 
+Adds a line to the current graphic object
+ at the specified position (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added lines
+ Alt<E> to remove the added element
+  Usage: addline x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addarrow addtext addrect addfrect 
+       addmarker addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addmarker} \label{addmarker} 
+\begin{verbatim} 
+Adds a marker to the current graphic object
+ at the specified position (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added circles
+ Alt<E> to remove added element
+  Usage: addmarker xpos ypos [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addoval} \label{addoval} 
+\begin{verbatim} 
+Adds an oval (ellipse) to the current graphic object
+ centered on xc,yc - semi-axis ds,dy (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added rectangle
+ Alt<E> to remove added element
+  Usage: addoval xc yc dx dy [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addfoval addline addarrow addfrect addcirc addfcirc
+       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addpoly} \label{addpoly} 
+\begin{verbatim} 
+Adds a polyline/polygon to the current graphic object
+  Usage: addploy 'x1,y1 x2,y2 x3,y3 ...' [GraphicAtt] [fgnc=false/true]
+  Coordinates specified as pairs x,y in a single word (use simple or double quotes
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect addfrect
+       addcirc addfcirc addfarc  graphicatt
+\end{verbatim} 
+\piacommand{addrect} \label{addrect} 
+\begin{verbatim} 
+Adds a rectangle to the current graphic object
+ between the specified positions (+ graphic attribute)
+ The Base/AxesDrawer is used to handle added rectangle
+ Alt<E> to remove added element
+  Usage: addrect x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+  Related commands: addtext addline addarrow addfrect
+       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt
+\end{verbatim} 
+\piacommand{addtext} \label{addtext} 
+\begin{verbatim} 
+Adds a text string to the current graphic object
+ at the specified position (+ color/font/pos/dir attributes) 
+ The Base/AxesDrawer is used to handle added text strings
+ Alt<E> to remove the added element
+  Usage: addtext x y TextString [ColFontPosAtt] [fgnc=false/true]
+  (use quotes '' for multi word text strings) 
+  if fgnc==true : Normalized 0..1 coordinates specification (def=false)
+ Text position/direction attribute: 
+      horizleft horizcenter horizright
+      vertbottom vertcenter verttop 
+      textdirhoriz textdirvertup textdirvertdown 
+  Related commands: addctext addline addarrow addrect addfrect
+      addcirc addfcirc addarc addfrac addpoly addfpoly settitle graphicatt
+\end{verbatim} 
+\subsection{Graphics} \label{Graphics} 
+Basic graphics and object display commands 
+ \\[2mm]  \noindent 
+\piahelpitem{PIConsole} \label{PIConsole} 
+\begin{verbatim} 
+Text output area and command editing window (console) 
+>>>> Mouse controls : 
+o Button-1: Rectangle selection for copy/paste 
+o Button-2: Paste text in the command editing line 
+o Button-3: activate display option menu 
+>>>> Keyboard controls : 
+o <Alt>O : activate display option menu   
+o <Alt>V : Paste text in the command editing line 
+o <Alt>A : Selection of the whole window for copy 
+o <Alt>L : Command history (List of command history buffer) 
+o <Ctl>A : Command editing -> Goto the beginning of line 
+o <Ctl>E : Command editing -> Goto the end of line 
+o <Ctl>K : Command editing -> Clear to the end of line 
+o <Ctl>C : Stop/break command execution by PIACmd/Commander
+o Cursor left,right : Command editing -> Move cursor 
+o Cursor Up,Down : recall command from history buffer 
+o Backspace,Del : Command editing 
+o <Return>,<Enter> : Execute command 
+
+\end{verbatim} 
+\piahelpitem{PIDraw3DWdg} \label{PIDraw3DWdg} 
+\begin{verbatim} 
+Manages display of 3-D objects (drawers)  
+>>>> Mouse controls : 
+o Button-2: Rotates the observer (camera) around object 
+o Shift-Button-2: Rotates object with camera fixed 
+  The object rotation mode can be assigned to Button-2 with <Alt>S 
+o Button-3: Zoom control (Camera distance And/Or view angle) 
+>>>> Keyboard controls : 
+o <Alt>R : Resets the 3-D view and refreshes the display 
+o <Alt>O : Displays a specific control window (default: PIDrawerTools) 
+           (2-D histograms, contour plot ...) 
+o <Alt>G : Show the PIDrawerTools (Graphic attributes of displayed Drawers) 
+           Drawer 0 manages the axes, as well as the added text 
+o <Alt>D : Shows the drawer manipulation pop-up menu 
+o <Alt>V : Copy/Paste / Text paste at the current position (Drawer 0)
+o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) 
+o <Alt>E : Removes the last added graphic element 
+o <Alt>A : Activate/Deactivate axes drawing 
+o <Alt>S : Activate/Deactivate object rotation mode on Button-2 
+
+\end{verbatim} 
+\piahelpitem{PIImage} \label{PIImage} 
+\begin{verbatim} 
+Manages the display of a 2-D array (P2DArrayAdapter) as an image 
+and controls a zoom widget, as well as a global image view widget 
+>>>> Mouse controls : 
+o Button-1: Display current coordinates and pixel value
+  Position the cursor an refresh the zoom widget
+o Button-2: Defines an image zone and positions the cursor 
+o Button-3: Moves the viewed portion of the array inside the window 
+>>>> Keyboard controls : 
+o <Alt>R : Refresh display 
+o <Alt>O : Shows the PIImageTools (image display parameter controls) 
+o <Alt>G : Show the PIDrawerTools (Graphic attributes of overlayed graphics (Drawers)) 
+o <Alt>D : Shows the drawer manipulation pop-up menu 
+o <Alt>V : Copy/Paste / Text paste at the current cursor position 
+o <Alt>C : Copy/Paste / Copies the selected region content as text 
+                        in the copy/paste buffer 
+o <Alt>X : Show/Hide the Cut Window 
+o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) 
+o <Alt>E : Removes the last added graphic element 
+o <Alt>+ or <Cntl>+ : Zoom in 
+o <Alt>- or <Cntl>- : Zoom out 
+o Cursor keys : Moves the image cursor 
+
+\end{verbatim} 
+\piahelpitem{PIScDrawWdg} \label{PIScDrawWdg} 
+\begin{verbatim} 
+Manages display of 2-D drawers with interactive zoom 
+>>>> Mouse controls : 
+o Button-1: Display current coordinates 
+o Button-2: Defines a rectangle for zoom 
+o Button-3: Defines a rectangle for Text-Info (<Alt>I) 
+>>>> Keyboard controls : 
+o <Alt>R : Refresh display 
+o <Alt>O : Displays a specific control window (default: PIDrawerTools) 
+           (2-D histograms, contour plot ...) 
+o <Alt>G : Show the PIDrawerTools (Graphic attributes of displayed Drawers) 
+           Drawer 0 manages the axes, as well as the added text 
+o <Alt>D : Shows the drawer manipulation pop-up menu 
+o <Alt>V : Copy/Paste / Text paste at the current position 
+o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) 
+o <Alt>E : Removes the last added graphic element 
+o <Alt>I : Shows (or updates) a text info window on the selected rectangle 
+o <Alt>M : Activate/Deactivate a measurement cursor on Button-1
+o <Alt>L : Deactivate DX,DY print (see below)
+>>>> Mouse + Keyboard controls : 
+o Button-1 + <Alt>K : Set (reset) the reference point for DX,DY print 
+
+\end{verbatim} 
+\piahelpitem{Windows} \label{Windows} 
+\begin{verbatim} 
+Objects can be displayed in different windows, or overlayed on the 
+previous display. The graphics attributes next,win,stack,same control 
+the display window. 
+o GraphicWindow : This is the default mode (gr_att=next)
+  Graphic windows can be divided int zones. Object is displayed 
+  in the next available position, removing a previously displayed 
+  widget if necessary 
+o Window : An object is displayed in its own window (gr_att= win) 
+o StackWindow : multpile widgets can be stacked in a StackWindow (gr_att= stack) 
+  A single widget is displayed a any time. Different widgets in a StackWindow 
+  can be displayed using the stacknext command, as well as the StackTools item 
+  in the Tools menu (from Menubar). An automatic cyclic display mode can also 
+  be activated using the StackTools menu (Blink) 
+o Most objects can be also be displayed overlayed 
+  on the last displayed widget (gr_att= same) 
+  or by specifying a widget name samew=Widgetname 
+o The widget/window name can be specified (gr_att wname=Name) 
+o The overlay can be on a selected rectangle of the last 
+  displayed widget (gr_att: inset  or inset=fxmin,fxmax,fymin,fymax) 
+
+  Related commands: newwin zone stacknext graphicatt setinsetlimits
+\end{verbatim} 
+\piacommand{addaxelabels} \label{addaxelabels} 
+\begin{verbatim} 
+Set the X and Y axis labels for the current 2D graphic object   alias for setaxelabels 
+\end{verbatim} 
+\piacommand{addtitle} \label{addtitle} 
+\begin{verbatim} 
+Set the title string (top title / bottom title) 
+   alias for settitle 
+\end{verbatim} 
+\piacommand{drpanel} \label{drpanel} 
+\begin{verbatim} 
+Creates a new 2D drawing zone for addtext, addline 
+ Usage: drpanel xmin xmax ymin ymax [GrAtt] [Name]
+  Related commands: addtext addline addrect addcirc ...
+\end{verbatim} 
+\piacommand{graphicatt} \label{graphicatt} 
+\begin{verbatim} 
+To change default graphic options
+  Usage: graphicatt att_list
+att_list=def back to default values, Example: gratt 'red circlemarker5'
+ ------------------ Graphic attribute list ------------------
+>> Colors: defcol black white grey red blue green yellow
+           magenta cyan turquoise navyblue orange siennared purple
+           limegreen gold violet violetred blueviolet darkviolet
+   or "color=name" "fgcolor=name" "bgcolor=name" ex: "color=red"
+>> Lines: defline normalline thinline thickline dashedline thindashedline
+          thickdashedline dottedline thindottedline thickdottedline
+   or "line=type,width"   ex: "line=dotted,7"
+>> Fonts:
+   > Att: deffontatt normalfont boldfont italicfont bolditalicfont 
+           smallfont smallboldfont smallitalicfont smallbolditalicfont
+           bigfont bigboldfont bigitalicfont bigbolditalicfont
+           hugefont  hugeboldfont hugeitalicfont hugebolditalicfont
+   > Names: deffont courierfont helveticafont timesfont symbolfont 
+   or "font=name,type,size"   ex: "font=courrier,bolditalic,10"
+>> Marker: dotmarker<T>  plusmarker<T>  crossmarker<T> circlemarker<T>
+           fcirclemarker<T> boxmarker<T> fboxmarker<T> trianglemarker<T>
+           ftrianglemarker<T>  starmarker<T>  fstarmarker<T>
+       with <T> = 1 3 5 7 .. 15 , Example fboxmarker5 , plusmarker9 ...
+   or "marker=type,size"   ex: "marker=plus,10"
+>> ArrowMarker: basicarrow<T>  trianglearrow<T>  ftrianglearrow<T>
+                arrowshapedarrow<T> farrowshapedarrow<T>
+       with <T> = 5 7 .. 15 , Example trianglearrow7 ...
+   or "arrow=type,size"   ex: "arrow=arrowshaped,10"
+------ Specific options for image displays:
+>> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32
+                grey128  invgrey128  colrj128  colbr128
+                red32cm  green32cm  blue32cm  yellow32cm
+                orange32cm cyan32cm violet32cm
+                midas_pastel midas_heat midas_rainbow3 midas_bluered
+                midas_bluewhite midas_redwhite
+                multicol16 multicol64
+>> revcmap : reverse colorMap
+>> ZoomFactors :  zoomxN   ex: zoomx1 zoomx2 zoomx3 ...
+                  zoom/N   ex: zoom/2 zoom/3 zoom/4 ...
+>> imagecenter=ix,iy : Position the image in widget
+>> lut=ltyp,min,max : Sets LUT type and min/max
+                   (ltyp=lin/log/sqrt/square)
+>> autolut=alt[,ns[,min,max]] : AutoLut method selection 
+                   (alt=minmax/meansig/hispeak/histail)
+>> invx,invy,exchxy : image axes configuration
+--- General purpose options:
+>> stat,stats / nsta,nstat,nostat,nostats : Toggle statistic display
+>> title,tit / notitle,notit -> Toggle automatic title display
+>> Choose display window: next same win stack inset
+>> for Axes / Axe labels / LogScale / xylimits / defdrrect
+       see setaxesatt command
+
+   Related commands: setaxesatt setinsetlimits 
+\end{verbatim} 
+\piacommand{imagcmap2eps} \label{imagcmap2eps} 
+\begin{verbatim} 
+imagcmap2eps: Current Image+ColorMap To EncapsulatedPostScript 
+Usage: imagcmap2eps EPSFileName
+\end{verbatim} 
+\piacommand{imagcmap2ps} \label{imagcmap2ps} 
+\begin{verbatim} 
+w2ps: Current Image+ColorMap To PostScript 
+Usage: imagcmap2ps 
+\end{verbatim} 
+\piacommand{newwin} \label{newwin} 
+\begin{verbatim} 
+To Create a New Graphic window, with zones 
+  Window size can be specified 
+    Usage: newwin [nx ny [sizeX sizeY]] 
+  Related commands: zone
+\end{verbatim} 
+\piacommand{psclosefile} \label{psclosefile} 
+\begin{verbatim} 
+psclosefile: close current postscript file 
+Usage: w2psclosefile 
+\end{verbatim} 
+\piacommand{psgetfilename} \label{psgetfilename} 
+\begin{verbatim} 
+psgetfilename: Prints current PostScript file name 
+Usage: psgetfilename 
+\end{verbatim} 
+\piacommand{pssetfilename} \label{pssetfilename} 
+\begin{verbatim} 
+pssetfilename: Sets current PostScript file name
+Usage: pssetfilename FileName 
+\end{verbatim} 
+\piacommand{setaxelabels} \label{setaxelabels} 
+\begin{verbatim} 
+Set the X and Y axis labels for the current 2D graphic object 
+
+  Usage: setaxelabels xLabel yLabel [ColorFntAtt]
+  Related commands: settitle addtext graphicatt
+\end{verbatim} 
+\piacommand{setaxesatt} \label{setaxesatt} 
+\begin{verbatim} 
+To set default axes attributes 
+  Usage: setaxesatt att_list 
+Color/Line/Font attributes and axes attributes 
+>> Axes: axesnone stdaxes=defaxes=boxaxes boxaxesgrid 
+         fineaxes fineaxesgrid centeredaxes finecenteredaxes 
+         centeredaxesgrid finecenteredaxesgrid
+         axescenter=x0,y0 (only with centered axes, default "axescenter=")
+         grid nogrid labels nolabels  
+         ticks noticks minorticks nominorticks 
+         extticks intticks extintticks 
+         nbticks=X_NTicks,Y_NTicks  
+         tickslen=MajTickLenFrac,MinTickLenFrac 
+>> Axe labels font size: fixedfontsize/autofontsize=fszf 
+         autofontsize=fsizef: Font size computed automatically 
+         fixedfontsize: Use font size attribute (BaseDrawer) 
+>> Scale type: linx liny logx logy -> Lin/Log Scales for 2D plots 
+>> xylimits=xmin,xmax,ymin,ymax  -> Forces X-Y limits in 2-D plots 
+>> defdrrect=xmin,xmax,ymin,ymax -> Defines drawing rectangle 2-D plots 
+          The rectangle is defined as a fraction of the widget size
+
+\end{verbatim} 
+\piacommand{setinsetlimits} \label{setinsetlimits} 
+\begin{verbatim} 
+Define the display rectangle for drawers added as insets 
+ over existing graphic objects - limits expressed as fraction 
+ graphic object size (0. .. 1.) Xmax at right, YMax top 
+  Usage: setinsetlimits xmin xmax ymin ymax
+  Related commands: graphicatt /inset
+\end{verbatim} 
+\piacommand{settitle} \label{settitle} 
+\begin{verbatim} 
+Set the title string (top title / bottom title) for the current graphic object
+  Usage: settitle TopTitle [BottomTitle] [fontAtt]
+  Related commands: addtext graphicatt
+\end{verbatim} 
+\piacommand{stacknext} \label{stacknext} 
+\begin{verbatim} 
+Displays the next widget on stack window 
+  Usage: stacknext
+\end{verbatim} 
+\piacommand{w2eps} \label{w2eps} 
+\begin{verbatim} 
+w2eps: Current Window To EncapsulatedPostScript 
+Usage: w2eps EPSFileName
+\end{verbatim} 
+\piacommand{w2ps} \label{w2ps} 
+\begin{verbatim} 
+w2ps: Current Window To PostScript 
+Usage: w2ps 
+\end{verbatim} 
+\piacommand{zone} \label{zone} 
+\begin{verbatim} 
+To Divide the Graphic window 
+  Usage: zone [nx=1 ny=1]
+  Related commands: newwin
+\end{verbatim} 
+\subsection{Obj. Display} \label{ObjZZDisplay} 
+\noindent 
+\piacommand{bargraph} \label{bargraph} 
+\begin{verbatim} 
+Bar-Graph view of a sequence of values 
+ Usage: bargraph ValueVarName [gr_opt]  
+    or  bargraph ValueVarName LabelVarName ColPosVarName [gr_opt] 
+  ValueVarName,LabelVarName,ColPosVarName are PIACmd interpreter 
+     variable name (vectors) 
+ - ValueVarName: Sequence of values to be represented
+ - LabelVarName: Corresponding labels
+ - ColPosVarName: Corresponding colors or color,position pairs 
+ Use a dash (-) or ! as placeholder for LabelVarName/ColPosVarName
+ Specific graphic options: fill/nofill packfrac=value 
+    horizontalbars/verticalbars  barvaluelabel/nobarvaluelabel
+ Related commands: disp nt2d vecplot ...
+\end{verbatim} 
+\piacommand{contour} \label{contour} 
+\begin{verbatim} 
+Creates and displays a ContourDrawer 
+ Usage: contour objectName [graphic_att/specific_opt] 
+ Specific Options 
+    ncont=[number of contours (automatic levels) ] 
+    niv/lev=[values for contours, separated by ','] 
+    lstep=[nomber,first_value,increment for contours ] 
+    bspline : use bspline algo for contour 
+    3spl : use cubic spline algo for contour 
+    labon : put labels for contours 
+\end{verbatim} 
+\piacommand{disp} \label{disp} 
+\begin{verbatim} 
+Displays an object 
+ Usage: disp nameobj [graphic_attributes]
+  Related commands: surf nt2d nt3d vecplot
+\end{verbatim} 
+\piacommand{gfd2d} \label{gfd2d} 
+\begin{verbatim} 
+Displays Points (X-Y) with error-bars from a GeneralFit Data 
+ Usage : gfd2d nameobj numvarx erreur=(x y xy) [graphic_attributes]
+  Related commands: gfd3d nt2d nt3d 
+  ----- OBSOLETE: utilisez nt2d -----
+\end{verbatim} 
+\piacommand{gfd3d} \label{gfd3d} 
+\begin{verbatim} 
+Displays 3D-Points (X-Y-Z) with error-bars from a GeneralFit Data 
+ Usage : gfd3d nameobj numvarx numvary erreur=(x y z xy xz yz xyz) [graphic_attributes]
+  Related commands: gfd2d nt2d nt3d 
+  ----- OBSOLETE: utilisez nt3d -----
+\end{verbatim} 
+\piacommand{imag} \label{imag} 
+\begin{verbatim} 
+Displays an object as an image 
+ Usage: imag nameobj [graphic_attributes]
+  Related commands: disp imagnav surf nt2d nt3d vecplot
+\end{verbatim} 
+\piacommand{imagnav} \label{imagnav} 
+\begin{verbatim} 
+Displays an object as an image with the ImageNavigator viewer 
+Usage: imagnav nameobj [graphic_attributes]
+  Related commands: disp imag surf nt2d nt3d vecplot
+\end{verbatim} 
+\piacommand{nt2d} \label{nt2d} 
+\begin{verbatim} 
+Displays Points (X-Y) [with error-bar / Weight / Label ] from an NTuple 
+ Usage : nt2d nameobj varx vary [errx erry wt label graphic_attributes]
+  Related commands: disp surf nt2dcn nt2dci nt3d  gfd2d vecplot
+\end{verbatim} 
+\piacommand{nt2dci} \label{nt2dci} 
+\begin{verbatim} 
+   with colors specified by a column content (as color index) 
+ Usage : nt2dci nameobj color varx vary [errx erry wt label graphic_attributes]
+  Related commands: disp  surf  nt2d nt2dci nt3d  gfd2d vecplot
+\end{verbatim} 
+\piacommand{nt2dcn} \label{nt2dcn} 
+\begin{verbatim} 
+   with colors specified by a column content (as color names) 
+ Usage : nt2dcn nameobj color varx vary [errx erry wt label graphic_attributes]
+  Related commands: disp  surf  nt2d nt2dci nt3d  gfd2d vecplot
+\end{verbatim} 
+\piacommand{nt2dvec} \label{nt2dvec} 
+\begin{verbatim} 
+Creates and displays a flow chart from ntuple variables
+ Usage: nt2dvec x y vx vy [graphic_att] 
+\end{verbatim} 
+\piacommand{nt3d} \label{nt3d} 
+\begin{verbatim} 
+Displays 3D-Points (X-Y-Z) [with error-bars / Weight / Label ] from an NTuple 
+ Usage : nt3d nameobj varx vary varz [errx erry errz wt label graphic_attributes]
+  Related commands: disp  surf  nt2d gfd3d 
+\end{verbatim} 
+\piacommand{ntcont} \label{ntcont} 
+\begin{verbatim} 
+Creates and displays a ContourDrawer (from a NTuple)
+ Usage: ntcont NTupleName varx vary varz [graphic_att/specific_opt] 
+        specific options 
+    ncont=[number of contours (automatic levels) ] 
+    niv/lev=[values for contours, separated by ','] 
+    lstep=[nomber,first_value,increment for contours ] 
+    bspline : use bspline algo for contour 
+    3spl : use cubic spline algo for contour 
+    labon : put labels for contours 
+\end{verbatim} 
+\piacommand{surf} \label{surf} 
+\begin{verbatim} 
+Displays an object as a 3D surface 
+ Usage: surf nameobj [graphic_attributes]
+  Related commands: disp nt2d nt3d vecplot
+\end{verbatim} 
+\piacommand{textdrawer} \label{textdrawer} 
+\begin{verbatim} 
+Multi line text darwer 
+ Usage : textdrawer LinesVarName AttVarName [gr_opt] 
+  LinesVarName,AttVarName are PIACmd interpreter variables
+ - LinesVarName: Lines to be displayed
+ - AttVarName: Corresponding font/marker/color attributes
+ Use a dash (-) or ! as placeholder for AttVarName
+ Specific graphic options: frame/noframe
+ Related commands: disp ... 
+\end{verbatim} 
+\piacommand{vecplot} \label{vecplot} 
+\begin{verbatim} 
+Displays Points (X-Y) with coordinates defined by two vectors 
+ Usage : vecplot nameVecX nameVecY [graphic_attributes]
+  Related commands: disp nt2d 
+\end{verbatim} 
+\subsection{Object Management} \label{ObjectZManagement} 
+\noindent 
+\piacommand{cd} \label{cd} 
+\begin{verbatim} 
+Change current directory
+ Usage: cd [dirname]
+\end{verbatim} 
+\piacommand{copy} \label{copy} 
+\begin{verbatim} 
+Copy objects (Alias cp) 
+  Usage: copy name_from name_to
+  Related commands: cp new...
+\end{verbatim} 
+\piacommand{cp} \label{cp} 
+\begin{verbatim} 
+Copy objects (Alias copy) 
+  Usage: cp name_from name_to
+  Related commands: copy new...
+\end{verbatim} 
+\piacommand{del} \label{del} 
+\begin{verbatim} 
+Deletes an object (Alias: rm) 
+ Usage: del nameobj [nameobj2 ...]
+  Related commands: rm delobjs rename
+\end{verbatim} 
+\piacommand{delobjs} \label{delobjs} 
+\begin{verbatim} 
+Delete a set of objects with names matching a pattern (x?y*)
+ Usage: delobjs nameobjpattern 
+
+  Related commands: del rename
+\end{verbatim} 
+\piacommand{listdirs} \label{listdirs} 
+\begin{verbatim} 
+Prints the list of directories
+ Usage: listdirs [patt=*] 
+ patt : * , ? 
+\end{verbatim} 
+\piacommand{listobjs} \label{listobjs} 
+\begin{verbatim} 
+Prints the list of objects (Alias: ls)
+ Usage: listobjs [patt=*]  
+    Or  listobjs patt VarName 
+   Obj. name pattern patt in the form abc?x* or /*/x?y ... 
+\end{verbatim} 
+\piacommand{ls} \label{ls} 
+\begin{verbatim} 
+ Alias for listobjs 
+ Usage: ls [patt=*] [VarName]
+\end{verbatim} 
+\piacommand{mkdir} \label{mkdir} 
+\begin{verbatim} 
+Create a directory
+ Usage: mkdir dirname [true]
+ if second argument==true, the directory's KeepOld attribute is set to true
+\end{verbatim} 
+\piacommand{mv} \label{mv} 
+\begin{verbatim} 
+Rename an object (Alias: rename) 
+ Usage: mv nameobj namenew
+  Related commands: rename del delobjs
+\end{verbatim} 
+\piacommand{pwd} \label{pwd} 
+\begin{verbatim} 
+Prints current directory
+ Usage: pwd
+\end{verbatim} 
+\piacommand{rename} \label{rename} 
+\begin{verbatim} 
+Rename an object (Alias: mv) 
+ Usage: rename nameobj namenew
+  Related commands: mv del delobjs
+\end{verbatim} 
+\piacommand{rm} \label{rm} 
+\begin{verbatim} 
+Deletes an object (Alias: del) 
+ Usage: rm nameobj [nameobj2 ...]
+  Related commands: del delobjs rename
+\end{verbatim} 
+\piacommand{rmdir} \label{rmdir} 
+\begin{verbatim} 
+Removes an empty directory
+ Usage: remove dirname
+\end{verbatim} 
+\piacommand{setdiratt} \label{setdiratt} 
+\begin{verbatim} 
+Sets directory attributes
+ Usage: setdiratt dirname KeepOldFlag(=true/false)
+   KeepOldFlag=true Object with the same name is moved to old
+   when adding objects
+\end{verbatim} 
+\subsection{Objects} \label{Objects} 
+\noindent 
+\piacommand{line2nt} \label{line2nt} 
+\begin{verbatim} 
+Fills (append) an NTuple from the line content 
+  Usage: line2nt ntname col0 col1 ... 
+  Related commands: newnt line2vec ntline2var ntcol2var
+\end{verbatim} 
+\piacommand{line2vec} \label{line2vec} 
+\begin{verbatim} 
+Creates a vector from the line 
+  Usage: line2vec vecname v0 v1 v2 ... 
+  Related commands: newvec line2nt
+\end{verbatim} 
+\piacommand{newdt} \label{newdt} 
+\begin{verbatim} 
+Creates a datatable 
+ Usage: newdt name v1:t1 v2:t2 v3:t3 .. vn:tn
+        newdt name nvar
+    vi : variable name
+    ti : variable type
+         r8,r4 for 8 and 4 bytes float
+         i8,i4 for 8 and 4 bytes signed integer
+         s for string
+  Related commands: newnt newh1d  newh2d newprof[e] newgfd
+\end{verbatim} 
+\piacommand{newgfd} \label{newgfd} 
+\begin{verbatim} 
+Creates GeneralFit Data object 
+ Usage: newgfd nvar nalloc [errx(0/1)]
+  Related commands: newh1d  newh2d  newprof[e] newdt newnt 
+\end{verbatim} 
+\piacommand{newh1d} \label{newh1d} 
+\begin{verbatim} 
+Creates a 1D histogramm 
+ Usage: newh1d name xmin xmax nbin
+  Related commands: newh2d  newprof[e] newdt newnt  newgfd 
+\end{verbatim} 
+\piacommand{newh2d} \label{newh2d} 
+\begin{verbatim} 
+Creates a 2D histogramm 
+ Usage: newh2d name xmin xmax nbinx ymin ymax nbiny
+  Related commands: newh1d  newprof[e] newdt newnt  newgfd 
+\end{verbatim} 
+\piacommand{newmtx} \label{newmtx} 
+\begin{verbatim} 
+Creates (and optionaly fills) a matrix 
+  Usage: newmtx name sizeX(Col) sizeY(Lines) [f(i,j) [dopt] ] 
+  Related commands: newvec
+\end{verbatim} 
+\piacommand{newnt} \label{newnt} 
+\begin{verbatim} 
+Creates a ntuple 
+ Usage: newnt name v1 v2 v3 .. vn
+        newnt name nvar
+  Related commands: newdt newh1d  newh2d newprof[e] newgfd 
+\end{verbatim} 
+\piacommand{newprof} \label{newprof} 
+\begin{verbatim} 
+Creates a profile histogramm 
+ Usage: newprof name xmin xmax nbin [ymin ymax]
+  Errors represent the data spread in the X bin 
+  Related commands: newh1d  newh2d newprofe newdt newnt newgfd 
+\end{verbatim} 
+\piacommand{newprofe} \label{newprofe} 
+\begin{verbatim} 
+Creates a profile histogramm 
+ Usage: newprofe name xmin xmax nbin [ymin ymax]
+  Errors represent the error on the data mean in the X bin 
+  Related commands: newh1d  newh2d newprof newdt newnt newgfd 
+\end{verbatim} 
+\piacommand{newvec} \label{newvec} 
+\begin{verbatim} 
+Creates (and optionaly fills) a vector 
+ Usage: newvec name size [f(i) [dopt] ] 
+  Related commands: newmtx line2vec
+\end{verbatim} 
+\piacommand{ntcol2var} \label{ntcol2var} 
+\begin{verbatim} 
+Object NTupleInterface column to an interpreter variable 
+  Usage: ntline2var objname column_number varname [LoopParam start:end[:step] ] 
+  Related commands: vec2var ntline2var
+\end{verbatim} 
+\piacommand{ntline2var} \label{ntline2var} 
+\begin{verbatim} 
+Object NTupleInterface line to an interpreter variable 
+  Usage: ntline2var objname line_number varname 
+  Related commands: vec2var ntcol2var
+\end{verbatim} 
+\piacommand{objaoper} \label{objaoper} 
+\begin{verbatim} 
+Perform an operation through the object adapter NObjMgrAdapter::PerformOperation()
+  Usage: objaoper objname operation [arg1 ...] 
+  Examples of defined operations : 
+  Matrices: row indx_row , col indx_col 
+  Arrays: slicexy indx_Z , slicexz indx_Y, sliceyz indxX 
+
+\end{verbatim} 
+\piacommand{vec2var} \label{vec2var} 
+\begin{verbatim} 
+Vector content to an interpreter variable varname = 'v0 v1 v2 ...' 
+  Usage: line2vec vecname varname [LoopParam start:end[:step] ]
+  Related commands: line2vec ntline2var
+\end{verbatim} 
+\subsection{PIACmd} \label{PIACmd} 
+piapp interpreter (class PIACmd) additional builtin commands 
+ \\[2mm]  \noindent 
+\piahelpitem{exitpiapp} \label{exitpiapp} 
+\begin{verbatim} 
+To end the piapp session 
+\end{verbatim} 
+\piahelpitem{helpwindow} \label{helpwindow} 
+\begin{verbatim} 
+To display the Help window 
+\end{verbatim} 
+\piahelpitem{stop} \label{stop} 
+\begin{verbatim} 
+To stop (break) interpreter (PIACmd/Commander) execution
+\end{verbatim} 
+\subsection{SkyMapCmd} \label{SkyMapCmd} 
+4 Pi spherical, local maps manipulation commands 
+and spherical harmonics analysis Ylm. 
+ This is mainly Based on SOPHYA SkyMap and Samba modules.  
+ \\[2mm]  \noindent 
+\piacommand{alm2cl} \label{alm2cl} 
+\begin{verbatim} 
+Project alm to cl
+ Usage: alm2cl alm cl
+\end{verbatim} 
+\piacommand{alm2map} \label{alm2map} 
+\begin{verbatim} 
+Generate SkyMap map(double) from Alm
+ Usage: alm2map almmat map(double) nside
+    (see command settypemap)
+\end{verbatim} 
+\piacommand{cl2llcl} \label{cl2llcl} 
+\begin{verbatim} 
+Project cl to l*(l+1)*cl
+ Usage: cl2llcl cl llcl
+\end{verbatim} 
+\piacommand{cl2map} \label{cl2map} 
+\begin{verbatim} 
+Generate SkyMap map(double) from Cl
+ Usage: cl2map clvec map(double) nside [fwhm]
+    (see command settypemap)
+\end{verbatim} 
+\piacommand{clmean} \label{clmean} 
+\begin{verbatim} 
+Compute mean for a cl vector
+ Usage: clmean cl imin,imax [meanvarname]
+   imin,imax  = compute between these indices
+   meanvarname  = variable name to store mean
+\end{verbatim} 
+\piacommand{clmult} \label{clmult} 
+\begin{verbatim} 
+Multiply a cl by a constant
+ Usage: clmult cl val
+\end{verbatim} 
+\piacommand{clop} \label{clop} 
+\begin{verbatim} 
+operation on a cl
+ Usage: clop cl(double) op1 cl1(double) [op2 cl2(double)] [op2 cl3(double)] [...]
+   Do "cl op1= cl1", "cl op2=cl2", ...
+      where op = +,-,*,/
+\end{verbatim} 
+\piacommand{clrebin} \label{clrebin} 
+\begin{verbatim} 
+rebin a cl into an ntuple
+ Usage: clrebin cl ntuple nbin,bin0
+   nbin: rebin by nbin
+   bin0: begin rebinning at bin bin0 (def=0)
+\end{verbatim} 
+\piacommand{crmapmask} \label{crmapmask} 
+\begin{verbatim} 
+Create a map mask(double) (nside) between latitudes lat1,lat2 longitudes lon1,lon2
+ Usage: crmapmask mapmsk(double) nside lat1,lat2 lon1,lon2 [valmsk,valnomsk]
+    mask pixels between [lat1,lat2] ([-90,90] in degrees)
+                and    [lon1,lon2] ([0,360[ in degrees)
+                (for no mask "!")
+    valmsk=value to be written into masked pixels (def=0)
+    valnomsk=value to be written into unmasked pixels (def=1)
+          (see command settypemap)
+\end{verbatim} 
+\piacommand{crmaskfrmap} \label{crmaskfrmap} 
+\begin{verbatim} 
+Create a map mask(double) (nside) relative to an other map(double) pixels values
+ Usage: crmaskfrmap mapmsk(double) nside map(double) v1,v2 [valmsk,valnomsk]
+    mask if v1<mapmsk(i)<v2
+    valmsk=value to be written into masked pixels (def=0)
+    valnomsk=value to be written into unmasked pixels (def=1)
+\end{verbatim} 
+\piacommand{map2alm} \label{map2alm} 
+\begin{verbatim} 
+SkyMap map(double) to Alm
+ Usage: map2alm map(double) almmat [lmax] [niter]
+   lmax: if <=0 or "!" use default (3*nside-1)
+   niter: number of iterations (<=0 or def=3)
+\end{verbatim} 
+\piacommand{map2cl} \label{map2cl} 
+\begin{verbatim} 
+SkyMap map(double) to Cl
+ Usage: map2cl map(double) clvec [lmax] [niter]
+   lmax: if <=0 or "!" use default (3*nside-1)
+   niter: number of iterations (<=0 or def=3)
+\end{verbatim} 
+\piacommand{map2double} \label{map2double} 
+\begin{verbatim} 
+Convert a float map to a double map
+ Usage: map2double map(float)
+\end{verbatim} 
+\piacommand{map2float} \label{map2float} 
+\begin{verbatim} 
+Convert a double map to a float map
+ Usage: map2float map(double)
+\end{verbatim} 
+\piacommand{map2local} \label{map2local} 
+\begin{verbatim} 
+Project a map(double) into a local map(double)
+ Usage: map2local map(double) localmap(double) nx,ny angleX,angleY phi0,theta0 
+                  [x0,y0] [angle]
+   nx,ny: number of pixels in x(col),y(row) direction
+          X-axis==phi, Y-axis==theta
+   angleX,angleY: total angle aperture in x,y direction (degrees)
+   phi0,theta0: define origin in phi,theta (degrees)
+   x0,y0: map phi0,theta0 to pixel x0,y0 ("!" or def=middle of the localmap)
+   angle: angle (degrees) of rotation between x-axis of  map-coordinate system
+           and the tangent to parallel on the sphere (def: 0.)
+\end{verbatim} 
+\piacommand{map2map} \label{map2map} 
+\begin{verbatim} 
+Convert a map(double) into an other map type
+ Usage: map2map map(double) type [nside]
+   type= H for Healpix
+         T for ThetaPhi
+   if nside <=1 use nside from map
+\end{verbatim} 
+\piacommand{mapcover} \label{mapcover} 
+\begin{verbatim} 
+Print the covering of a map(double)
+ Usage: mapcover map(double) v1,v2 [varname]
+    v1,v2: good pixels have v1<=val<=v2 (def=0.99,1.01)
+          (use default (0.99,1.01): "!")
+    $varname: percent of sky covering
+\end{verbatim} 
+\piacommand{mapmult} \label{mapmult} 
+\begin{verbatim} 
+Multiply a map(double) by a constant
+ Usage: mapmult map(double) cste
+\end{verbatim} 
+\piacommand{mapop} \label{mapop} 
+\begin{verbatim} 
+operation on a map(double)
+ Usage: mapop map(double) op1 map1(double) [op2 map2(double)] [op2 map3(double)] [...]
+   Do "map op1= map1", "map op2=map2", ...
+      where op = +,-,*,/
+\end{verbatim} 
+\piacommand{maproj} \label{maproj} 
+\begin{verbatim} 
+Project a map(double) into an other one
+ Usage: maproj map(double) mapproj(double) [nside]
+   Create mapproj(nside) and project map into mapproj
+   (use "maproj map mapproj" to make a copy)
+\end{verbatim} 
+\piacommand{mapstat} \label{mapstat} 
+\begin{verbatim} 
+Statistics from a map(double)
+ Usage: mapstat map(double) [msk(double)] [meanvarname] [sigmavarname]
+   msk = mask sphere used as weight
+     if msk(i)<=0 do not use that pixel
+     if msk(i)>0  use that pixel with weight msk(i)
+   msk = "!" means no mask sphere
+   meanvarname  = variable name to store mean
+   sigmavarname = variable name to store sigma
+   ("!" means do not store)
+\end{verbatim} 
+\piacommand{maskmap} \label{maskmap} 
+\begin{verbatim} 
+Mask a map(double) with a mask map(double)
+ Usage: maskmap map msk
+    operation is map(i) *= msk(theta,phi)
+\end{verbatim} 
+\piacommand{resol2szidx} \label{resol2szidx} 
+\begin{verbatim} 
+Compute SizeIndex value (=nside for HEALPix) for a
+ given resolution, (resol in arcminutes)
+ Usage: resol2szidx resol
+\end{verbatim} 
+\piacommand{settypemap} \label{settypemap} 
+\begin{verbatim} 
+Set le type de map(double) par default
+ Usage: settypemap type
+   type= H for Healpix (default)
+         T for ThetaPhi
+\end{verbatim} 
+\piacommand{szidx2resol} \label{szidx2resol} 
+\begin{verbatim} 
+Compute resolution for a given SizeIndex (=nside for HEALPix)
+ Usage: szidx2resol szidx_m
+\end{verbatim} 
+\piacommand{typemap} \label{typemap} 
+\begin{verbatim} 
+Imprime le type de map
+ Usage: typemap map
+\end{verbatim} 
+\subsection{SophyaCmd} \label{SophyaCmd} 
+\noindent 
+
+\piacommand{errorellipse} \label{errorellipse} 
+\begin{verbatim} 
+   Adds an error ellipse, specified by its center (xc,yc) 
+  and error matrix (covariance) parameters  SigX^2,SigY^2,Covar 
+  A global scaling parameters scale , graphic attributes and 
+   nomber of points can optionnaly be specified
+  if the -fill flag specified, plots a filled ellipse 
+
+\end{verbatim} 
+\piacommand{mollgrid} \label{mollgrid} 
+\begin{verbatim} 
+Creates a spherical coordinate grid in Molleweide projection 
+ Usage: mollgrid [Nb_Parallel] [Nb_Meridien] [graphic_att] 
+\end{verbatim} 
+\piacommand{setprjmoldefval} \label{setprjmoldefval} 
+\begin{verbatim} 
+Set default value for Molleweide projection of spherical maps (outside maps)
+ Usage: setprjmoldefval OutOfMapValue 
+\end{verbatim} 
+
+\subsection{pawCmd} \label{pawCmd} 
+\noindent 
+\piacommand{h/2d/geth} \label{hZ2dZgeth} 
+\begin{verbatim} 
+Get histo projections, bandes and slices
+ h/2d/geth nameh2d         : infos on 2D histogramme projections
+ h/2d/geth h nameh2d px    : copy X projection into histo h
+ h/2d/geth h nameh2d py    : copy Y projection into histo h
+ h/2d/geth h nameh2d bx n  : copy X band number n into histo h
+ h/2d/geth h nameh2d by n  : copy Y band number n into histo h
+ h/2d/geth h nameh2d sx n  : copy X slice number n into histo h
+ h/2d/geth h nameh2d sy n  : copy Y slice number n into histo h
+  Related commands: h/plot/2d
+\end{verbatim} 
+\piacommand{h/cadd} \label{hZcadd} 
+\begin{verbatim} 
+Add a constant to an histogram, a vector or a matrix
+ h/cadd namehisto val
+  Related commands: h/cmult h/oper
+\end{verbatim} 
+\piacommand{h/cmult} \label{hZcmult} 
+\begin{verbatim} 
+Multiply an histogram, a vector or a matrix by a constant
+ h/cmult namehisto val
+  Related commands: h/cadd h/oper
+\end{verbatim} 
+\piacommand{h/copy} \label{hZcopy} 
+\begin{verbatim} 
+Copy content of object1 into object2
+ 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->)
+ Warning: elements from i1 to i2 included are copied
+ If obj1Dto does not exist, is is created with size i2-i1+1
+    or obj2Dto with size i2-i1+1,j2-j1+1
+ The adressed content of obj?Dfrom is overwritten
+ The non-adressed content of obj?Dfrom is left unchanged
+  Related commands: copy
+\end{verbatim} 
+\piacommand{h/deriv} \label{hZderiv} 
+\begin{verbatim} 
+Derivate a 1D histogram
+ h/deriv nameh1d
+  Related commands: h/integ v/integ v/deriv
+\end{verbatim} 
+\piacommand{h/err} \label{hZerr} 
+\begin{verbatim} 
+Set Histo,Histo2D error to function of bin content value
+ h/err namehisto expr_func
+  Related commands: h/set/err
+\end{verbatim} 
+\piacommand{h/get\_vec} \label{hZgetZvec} 
+\begin{verbatim} 
+Get content of histogram 1D profile or 2D into vector (matrix)
+ h/get_vec nameh1d namevector [cont,err2,absc] [proj]
+ h/get_vec nameh2d namematrix [cont,err2,absc]
+   cont : get histogramme content
+   err2 : get histogramme error^2
+   absc : get histogramme low bin abscissa (1D only)
+     proj :
+            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
+  Related commands: h/put_vec
+\end{verbatim} 
+\piacommand{h/integ} \label{hZinteg} 
+\begin{verbatim} 
+Integrate a 1D histogram
+ h/integ nameh1d [norm]
+ norm<=0 means no normalisation (def norm=1)
+  Related commands: h/deriv v/integ v/deriv
+\end{verbatim} 
+\piacommand{h/oper} \label{hZoper} 
+\begin{verbatim} 
+Operation on histograms vectors or matrices
+ h/oper @ h1 h2 hres
+        hres = h1 @ h2   with @ = (+,-,*,/)
+ For vectors and matrices, operations are elements by elements
+  Related commands: h/cadd h/cmult
+\end{verbatim} 
+\piacommand{h/plot/2d} \label{hZplotZ2d} 
+\begin{verbatim} 
+Specific plot for 2D histogrammes
+ h/plot/2d nameh2d show        : infos on 2D histogramme projections
+ h/plot/2d nameh2d h    [dopt] : plot 2D histogramme
+ h/plot/2d nameh2d px   [dopt] : plot X projection
+ h/plot/2d nameh2d py   [dopt] : plot Y projection
+ h/plot/2d nameh2d bx n [dopt] : plot X band number n
+ h/plot/2d nameh2d by n [dopt] : plot Y band number n
+ h/plot/2d nameh2d sx n [dopt] : plot X slice number n
+ h/plot/2d nameh2d sy n [dopt] : plot Y slice number n
+                      n < 0 means Show Info
+\end{verbatim} 
+\piacommand{h/put\_vec} \label{hZputZvec} 
+\begin{verbatim} 
+Put content of vector (matrix) into content of histogram 1D or 2D
+ h/put_vec nameh1d namevector [cont,err2]
+ h/put_vec nameh2d namematrix [cont,err2]
+     cont : put into histogramme content
+     err2 : put into histogramme error^2
+  Related commands: h/get_vec
+\end{verbatim} 
+\piacommand{h/rebin} \label{hZrebin} 
+\begin{verbatim} 
+Rebin a 1D histogram or profile
+ h/rebin nameh1d nbin
+\end{verbatim} 
+\piacommand{h/set/cont} \label{hZsetZcont} 
+\begin{verbatim} 
+Set Histo,Histo2D content for range of bins or range of values
+ h/set/cont namehisto setvalue i1[:i2]  [j1[:j2]]
+     set content to setvalue for bin range i1:i2  j1:j2
+ h/set/cont namehisto setvalue v v1:v2
+     set content to setvalue for content values range v1:v2
+ h/set/cont namehisto setvalue e e1:e2
+     set content to setvalue for error values range v1:v2
+  Related commands: h/set/err
+\end{verbatim} 
+\piacommand{h/set/err} \label{hZsetZerr} 
+\begin{verbatim} 
+Set Histo,Histo2D errors for range of bins or range of values
+ h/set/err namehisto setvalue i1[:i2]  [j1[:j2]]
+     set error to setvalue for bin range i1:i2  j1:j2
+ h/set/err namehisto setvalue v v1:v2
+     set error to setvalue for content values range v1:v2
+ h/set/err namehisto setvalue e e1:e2
+     set error to setvalue for error values range v1:v2
+  Related commands: h/set/cont
+\end{verbatim} 
+\piacommand{herr/mean} \label{herrZmean} 
+\begin{verbatim} 
+Perform bin mean computation for HistoErr and Histo2DErr
+ herr/mean nameherr todo
+    todo = +1 : compute mean
+         = -1 : cancel computation
+\end{verbatim} 
+\piacommand{herr/variance} \label{herrZvariance} 
+\begin{verbatim} 
+Perform bin mean and variance computation for HistoErr and Histo2DErr
+ herr/variance nameherr todo
+    todo = +1 : compute mean and variance
+         = -1 : cancel computation
+\end{verbatim} 
+\piacommand{n/assoc/col} \label{nZassocZcol} 
+\begin{verbatim} 
+Merge ntuples columns with an association index
+ n/assoc/col ntass[,u/i] nt_1[,ext] nt_2[,ext] nt_assoc[,icass]
+ Merge ntuples nt_1 and nt_2 columns into ntuple ntass
+   with line association number given by ntuple nt_assoc
+ ---
+ icass: association number given by column "icass" of nt_assoc (def=0)
+ ---
+ ext : character string to add at the end of the ntuple variable names
+   if "ext"="!" no extension is added
+   if no "ext" is given, automatic extension "_0" "_1" "_2" ...
+ ---
+ u   : do the union of all the lines of nt_1 and nt_2
+       (all ssociated and un-associated lines of nt_1 and nt_2)
+ i   : do the intersection of all the lines of nt_1 and nt_2
+       (only associated lines of nt_1 and nt_2)
+ def : write all lines of nt_1 with possible associated line of nt_2
+       (number of entries of ntass = number of entries of nt_1)
+\end{verbatim} 
+\piacommand{n/copy} \label{nZcopy} 
+\begin{verbatim} 
+Copy all or some variables of a ntuple into another new ntuple
+ n/merge ntnew nt [vname1 vname2 vname3 ...]
+\end{verbatim} 
+\piacommand{n/merge} \label{nZmerge} 
+\begin{verbatim} 
+Merge ntuples (by adding lines)
+ n/merge nt nt_1 nt_2 ... nt_n
+ Merge ntuples nt_i lines into ntuple nt
+\end{verbatim} 
+\piacommand{n/merge/col} \label{nZmergeZcol} 
+\begin{verbatim} 
+Merge ntuples (by adding columns for each line)
+ n/merge/col nt nt_1[,ext] nt_2[,ext] ... nt_n[,ext]
+ Merge ntuples nt_i columns into ntuple nt
+ ext : character string to add at the end of the ntuple variable names
+   if "ext"="!" no extension is added
+   if no "ext" is given, automatic extension "_0" "_1" "_2" ...
+\end{verbatim} 
+\piacommand{n/pl} \label{nZpl} 
+\begin{verbatim} 
+alias to n/plot (see n/plot)
+\end{verbatim} 
+\piacommand{n/plot} \label{nZplot} 
+\begin{verbatim} 
+Plot NTuple variables "a la paw" (alias n/pl)
+ n/plot nameobj.x_exp [cut] [w_exp] [loop] [gratt]
+ n/plot nameobj.y_exp%x_exp [cut] [loop] [gratt]
+ n/plot nameobj.z_exp%y_exp%x_exp [cut] [loop] [gratt]
+        for default use ! , loop=i1[:i2[:di]]
+ for 1 dimensional (1D) projection:
+   use graphic option "keepbin" to keep previous
+   plot binning for 1D distribution
+  Related commands: plot2dw plot3d
+\end{verbatim} 
+\piacommand{n/proj} \label{nZproj} 
+\begin{verbatim} 
+Project NTuple in histogram (1D or 2D) a la paw
+ n/proj nameproj nameobj.x_exp [cut] [w_exp] [loop] [gratt]
+ n/proj nameproj nameobj.y_exp%x_exp [cut] [w_exp] [loop] [gratt]
+        for default use ! , loop=i1[:i2[:di]]
+ for 1 dimensional (1D) projection:
+   no display is performed if "nameproj" is an existing histogram
+   unless a graphic option "gratt" is given
+  Related commands: projh1d projh2d projprof exptovec
+\end{verbatim} 
+\piacommand{n/read} \label{nZread} 
+\begin{verbatim} 
+Read columns in an ASCII file and fill a NTuple or a DataTable
+ n/read nt fascii [options] var_1,c_1 var_2,c_2 ... var_n,c_n 
+ nt : NTuple or DataTable (see options) name
+ var_i,c_i : variable name, associated column in ASCII file [0,n[
+ where [options] are:
+   "-dt": create a DataTable of double instead of a NTuple
+   "=s": separator character is 's' (could be "	")
+   "-^abcd": do not read lines beginning with string "abcd" 
+   "+^abcd": read only lines beginning with string "abcd" 
+   "-abcd": do not read lines which contain string "abcd" 
+   "+abcd": read only lines which contain string "abcd" 
+ these options may be repeated (ex: "-^abcd" "-^xyz") 
+   - in case of "do not read" options are added with logical AND 
+   - in case of "read only" options are added with logical OR 
+\end{verbatim} 
+\piacommand{n/scan} \label{nZscan} 
+\begin{verbatim} 
+Scan NTuple a la paw
+ n/scan nameobj[.exp1%exp2%exp3] cut loop
+               [-f:filename] [list_of_variables]
+  loop : iev1[:iev2[:diev]] or !
+  cut  : cut expression or 1. or !
+  list_of_variables : default is all variables
+                    : var1 var2 var3 ... varn
+                    : var1 : var2   (from var1 to var2)
+                    :  : var2   (from first variable to var2)
+                    : var1 :    (from var1 to last variable)
+                  ex: "v1 : v3 v7 v4 : v6 v2 v9 :"
+ exp1%exp2%exp3 :
+           if given add exp1,exp2,exp3 to the variable list
+ -f:filename : write into "filename", Default is to stdout
+\end{verbatim} 
+\piacommand{reset} \label{reset} 
+\begin{verbatim} 
+Reset histograms vectors or matrix
+ reset nameobj
+\end{verbatim} 
+\piacommand{v/deriv} \label{vZderiv} 
+\begin{verbatim} 
+Derivate a TVector / vector
+ v/deriv namevec [deriv_option]
+ 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]
+  Related commands: h/integ h/deriv v/integ
+\end{verbatim} 
+\piacommand{v/integ} \label{vZinteg} 
+\begin{verbatim} 
+Integrate a TVector / vector
+ v/integ namevec [norm]
+ norm<=0 means no normalisation (def norm=0)
+  Related commands: h/integ h/deriv v/deriv
+\end{verbatim} 
+\piacommand{v/sort} \label{vZsort} 
+\begin{verbatim} 
+Sort a vector into itself
+ v/sort namevec [+1/-1]
+ "+1" means increasing order, "-1" decreasing order
+\end{verbatim} 
Index: /tags/V_Nov2007/SophyaLib/Manual/piapp.tex
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/piapp.tex	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/piapp.tex	(revision 3445)
@@ -0,0 +1,1888 @@
+\documentclass[twoside,10pt]{article}
+% \usepackage[latin1]{inputenc}
+% \usepackage[T1]{fontenc}
+\usepackage[francais]{babel}
+\usepackage{graphicx}
+
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{latexsym}
+
+\usepackage{palatino}
+
+%  Definition pour Docs Sophya
+\usepackage{defsophya}
+
+\usepackage{makeidx}
+
+\usepackage[ps2pdf,bookmarks,bookmarksnumbered,%
+              urlcolor=blue,citecolor=blue,linkcolor=blue,%
+                pagecolor=blue,%hyperindex,%
+                 colorlinks=true,hyperfigures=true,hyperindex=true
+           ]{hyperref}
+
+\setlength{\textwidth}{15cm}
+\setlength{\textheight}{20.5cm}
+\setlength{\topmargin}{0.cm}
+\setlength{\oddsidemargin}{0.cm}
+\setlength{\evensidemargin}{0.cm}
+\setlength{\unitlength}{1mm}
+
+% \newcommand{\piacommand}[1]{
+%  \framebox{\bf \Large #1 } \index{#1} % (Command) 
+%}
+% \newcommand{\piahelpitem}[1]{
+%  \framebox{\bf \Large #1 } \index{#1} (Help item)
+%}
+
+\newcommand{\rond}{$\bullet \ $}
+\newcommand{\etoile}{$\star \ $}
+\newcommand{\cercle}{$\circ \ $}
+\newcommand{\carre}{$\Box \ $}
+
+%%%% Definition des commandes pour l'aide en ligne
+\newcommand{\piacommand}[1]{
+$\blacksquare$ \hspace{3mm} {\bf \Large #1 } \index{#1} % (Command) 
+}
+\newcommand{\piahelpitem}[1]{
+$\square$ \hspace{3mm} {\bf \Large #1 } \index{#1} (Help item) 
+}
+
+\newcommand{\menubar}[1]{\hspace{1mm} \framebox{\it MenuBar::#1} \hspace{1mm}}
+
+\newcommand{\myppageref}[1]{ (p. \pageref{#1} ) }
+
+\makeindex     %  Constitution d'index
+
+\begin{document}
+\begin{titlepage}
+%  The title page - top of the page with the title of the paper
+\titrehp{piapp \\ An interactive data analysis tool}
+%  Authors list
+\auteurs{
+R. Ansari            &  ansari@lal.in2p3.fr       \\
+E. Aubourg           &  aubourg@hep.saclay.cea.fr \\
+C. Magneville        &  cmv@hep.saclay.cea.fr     \\
+O. Perdereau         &  perderos@lal.in2p3.fr     \\
+}
+% \author{R. Ansari {\tt ansari@lal.in2p3.fr} \\
+% E. Aubourg {\tt aubourg@hep.saclay.cea.fr} \\
+% C. Magneville {\tt cmv@hep.saclay.cea.fr} 
+% }
+\vspace{1cm}
+\begin{center}
+{\bf \Large piapp Version: 4.1 (V\_Nov2007) } 
+\end{center}
+\titrebp{5}
+
+\end{titlepage}
+
+\newpage
+\tableofcontents
+\newpage
+
+\section{Introduction}
+\index{piapp}
+{\bf piapp} (or {\bf spiapp}) is an interactive data analysis 
+and visualization  program. It is based on the {\bf PI} GUI library 
+and the {\bf SOPHYA} \footnote{see http://www.sophya.org}
+(or {\bf PEIDA++} \footnote{PEIDA++ has been used in EROS software. 
+(http://eros.in2p3.fr). It is not maintained anymore.}) 
+C++ data analysis class library. 
+\par 
+{\bf piapp} is a powerful command oriented tool for visualising and analysing data.
+Its main features are summarised below:
+\begin{itemize}
+\item[\rond] Image, multiple 2D and few 3D representations
+\item[\rond] Highly interactive graphics, with postscript as export format
+\item[\rond] Capability to handle large data sets. Data can be imported and 
+exported in different formats: ASCII, PPF and FITS.
+\item[\rond] Interactive analysis: 2D/3D distributions, histograms, FFT \ldots 
+\item[\rond] Flexible c-shell inspired command interpreter. 
+\item[\rond] Possibility to perform more complex operations in C++, on objects
+managed by the application through the on-the-fly compilation and execution
+of c++ code fragments in piapp. 
+\item[\rond] piapp is a multi-threaded program with separate threads for graphics
+and command execution, ensuring interactive response, even while heavy 
+computation is being performed. In addition, thread safe commands can be executed 
+in separate threads, for taking advantage of multi CPU (or CPU-cores) workstations.
+\item[\rond] The application can be easily extended through modules which can be
+loaded at run time.  
+\end{itemize}
+
+\subsection{Acknowlegments}
+Many people have contributed to the development SOPHYA and/or the PI library 
+and (s)piapp interactive analysis tool.
+we are grateful to the following people:
+
+\begin{tabular}{lcl}
+Reza Ansari & \hspace{5mm} & (LAL-Univ.Paris Sud, Orsay) \\
+Eric Aubourg & & (DAPNIA-CEA/APC, Saclay) \\
+Sophie Henrot-Versille & & (LAL-IN2P3/CNRS, Orsay) \\
+Alex Kim & & (LBL, Berkeley) \\
+Guy Le Meur & & (LAL-IN2P3/CNRS, Orsay) \\
+Eric Lesquoy & & (DAPNIA-CEA, Saclay) \\
+Christophe Magneville & & (DAPNIA-CEA, Saclay) \\
+Bruno Mansoux & & (LAL-IN2P3/CNRS, Orsay) \\
+Olivier Perdereau & & (LAL-IN2P3/CNRS, Orsay) \\
+Nicolas Regnault & & (LPNHE-IN2P3/CNRS, Paris) \\
+Benoit Revenu & & (APC/Univ.Paris 7, Paris) \\
+Francois Touze & & (LAL-IN2P3/CNRS, Orsay) \\
+\end{tabular}
+
+We thank also the persons who have helped us by useful suggestions, among others : \\
+S. Bargot, S. Plasczczynski, C. Renault and D. Yvon.
+
+%%%
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=15cm]{piapp_mainwin.eps}
+\caption{piapp main window}
+\label{figmainwin}
+\end{center}
+\end{figure}
+\subsection{starting piapp}
+ {\bf piapp} can simply be started on the command line in a terminal window 
+once the SOPHYA/piapp  environment has been initialised. 
+The environment variables {\tt SOPHYABASE} should contain the directory 
+where SOPHYA/piapp has been installed. the shared library path 
+{\tt LD\_LIBRARY\_PATH} must contain {\tt \$SOPHYABASE /slb} and the 
+current directory {\tt .} and the executable search path {\tt PATH} must
+contain {\tt \$SOPHYABASE /exe}. Refer to the SOPHYA overview manual 
+for more information on SOPHYA directory structure. \\
+\par
+{\tt (s)piapp -h} provides a brief help of the command line 
+arguments. Xtoolkit options can also be specified as command line
+arguments. {\bf spiapp} is the name of SOPHYA/piapp executable, 
+in order to distinguish it from PEIDA/piapp. 
+\begin{verbatim}
+csh> spiapp -h
+ SophyaInitiator::SophyaInitiator() BaseTools Init
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  2.1 Revision 0 (V_Nov2007) -- Nov 24 2007 13:08:58 gcc 3.3 
+20030304 (Apple Computer, Inc. build 1495)
+ piapp: Interactive data analysis and visualisation program 
+ Usage: piapp [-nored] [-doublered] [-termread] [-term] 
+              [-hidezswin] [-small] [-nosig] [-nosigfpe] [-nosigsegv] 
+              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] 
+  -nored : Don't redirect stdout/stderr to piapp console
+  -doublered : Redirect stdout/stderr to piapp console AND the terminal 
+  -termread : Read commands on terminal (stdin)
+  -term : equivalent to -nored -termread -small 
+  -hidezswin : Hide Zoom/Stat/ColMap window 
+  -small : Create small size main piapp window 
+  -nosig : Don't catch SigFPE, SigSEGV 
+  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV 
+  -tmpdir TmpDirectory: defines TMDIR for temporary files 
+  -help2tex: Create a LaTeX help file (piahelp.tex)
+  -exec file [args] : Execute command file (last option)
+\end{verbatim} 
+Once {\bf piapp} is started, the main piapp window appears.
+It contains the menu bar, an upper part with the zoom and colormap 
+widgets for  image displays, memory and CPU usage and a terminal like 
+widget (piapp console, see {\bf PIConsole} \myppageref{PIConsole}) 
+in the lower part. The figure \ref{figmainwin}
+shows an image of the piapp main window.
+{\tt stdout/cout, stderr/cerr} are redirected to the piapp console and 
+commands can be entered in this widget. It is also possible to keep
+the terminal where piapp was started  for {\tt stdout/stderr} (flag {\tt -nored}).
+The flag {\tt -term} activate a command reader on the terminal 
+It is also possible to have a command reader on  the terminal ({\tt stdin}).  \\[1mm]
+
+\par 
+In section 2, we present  a quick tour of {\bf piapp}.  
+a brief overview of piapp graphics, supported data formats, interactive
+analysis possibilities, the command interpreter and c++ execution 
+are presented in the following sections. 
+Section \ref{piappcmdref} contains a brief description of all piapp commands 
+and help items. Various interactive control windows are described in appendix.
+
+\subsection{DemoPIApp and DemoData}
+The directory {\bf DemoPIApp} contains a number of example scripts, such as the 
+{\tt demo.pic} and the associated data file {\tt demo.ppf}. It contains 
+also examples of loadable modules for piapp. The  DemoPIApp/CONTENT 
+file contains a brief description of the different files. \\
+The {\bf DemoData} contains a number of data files, in PPF and FITS format, which are 
+used for the examples in this document.
+
+\subsection{Warnings/Known problems}
+\begin{enumerate} 
+\item It might  be necessary to define the environment variable 
+{\bf PIXKBMOMASK}, used by the libPI.a to map correctly 
+the {\tt <Alt>} key with some X servers (in particular with 
+X11 on MacOS X). \\
+{\tt csh> setenv PIXKBMODMASK 2 }
+However, the default value has been changed in PI/piapp V=4.1 and it should not be
+necessary anymore to define PIXKBMODMASK.
+%%
+\item The output redirection uses unix pipes. On Linux, with commands
+producing long outputs, the application may block because of incorrect management
+of pipes. If this happens, use piapp with  {\tt -nored} flag. This problem has been 
+in principle solved with SOPHYA V=2.1 / piapp V=4.1
+\end{enumerate}
+
+\newpage
+\section{A Tour of piapp}
+\subsection{Interacting with piapp, getting help}
+Users interact with piapp through commands entered in the piapp-console
+(or the unix terminal), and through the different menus. 
+Some of the possibilities of the piapp-console are described
+in {\bf PIConsole} help item, in the command reference section \myppageref{PIConsole}.
+The description
+of the commands in available online using the help command.
+An online help window can be displayed by \menubar{File / Help}.
+Commands and help items are grouped in categories which can be
+selected using the OptionMenu in the Help window.
+\begin{verbatim}
+Cmd> help func 
+Displays a function y=f(x) (Fills a vector with function values)   
+ Usage: func f(x) xmin xmax [npt graphic_attributes]               
+  Related commands: funcff func2d func2dff   
+Cmd> func sin(x)/x 0.1 10 100 'red line=solid,2'
+---> Graphic display of the function
+\end{verbatim}
+The directory {\tt DemoPIApp} contains a number of example
+command script and sample data files.
+
+\subsection{The Object Manager (NamedObjMgr)}
+The {\bf piapp} application is built around an object manager
+(class {\tt NamedObjMgr}) and a graphic application
+(class {\tt PIStdImgApp}). Objects inheriting from 
+the class {\tt AnyDataObj} can be managed through adapter 
+classes (classes inheriting from {\tt NObjMgrAdapter}) by 
+the object manager. 
+\par
+User sees the objects (such as Sophya objects Histo, NTuple,
+Arrays, Images, SkyMaps, \ldots) kept in memory, organized 
+in a single level tree structure. Four memory directories
+are automatically created and can not be removed: \\
+\centerline{\bf /home \hspace{10mm} /old \hspace{10mm} /tmp \hspace{10mm} /autoc}
+The default working directory (in memory) is {\bf /home}.
+Other directories can be created by the user.
+\begin{center} 
+{\bf Warning:} These are only the directory 
+structure managed by the piapp application and do not 
+correspond to the file system directories
+\end{center}
+The window {\bf ObjMgr} shown in figure \ref{figobjmgrw} 
+can be used to navigate in the memory directories and 
+execute simple operations on objects. \\ 
+This window can be displayed using the menu command
+\menubar{Objects / ObjectManager}. 
+The button \framebox{\small \bf SetCurObj} can be used to set the value
+of the interpreter's variable {\tt cobj} to the selected 
+object name. 
+Refer to the commands in group {\bf Object Management} 
+for more information.
+
+\vspace*{5mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=10cm]{piapp_objmgr.eps}
+\caption{The interactive object management window}
+\label{figobjmgrw}
+\end{center}
+\end{figure}
+
+\subsection{command language}
+A basic command interpreter ({\bf PIACmd/Commander}) is included in {\bf piapp} and 
+other command interpreters can be inserted in the application 
+framework.
+This interpreter ({\bf Commander} \myppageref{Commander}) 
+synthax is close to the c-shell 
+(csh) shell script. It is possible to define and use variables
+({\tt set} command, {\tt \$varname}), and execute loops 
+({\tt foreach,for}), as well as simple tests 
+({\tt if test then ... else ... endif}).
+Commands from a file (default extension .pic) can be executed 
+using the {\tt exec} command.
+Long commands can be put on several lines, by ending a line
+by the backslash \\ caracter, to signal that the command
+continues on the next line.
+
+The command macro below shows a sample piapp session, where 
+data from the file {\tt demo.ppf} are displayed.
+\begin{verbatim}
+#  Trace mode -> On
+traceon
+#  Deleting all objects in the current directory
+delobjs *
+#  Opening the PPF file demo.ppf
+openppf demo.ppf
+# Various displays in a graphic window, divided into 2x2 zones
+zone 2 2
+#  1D histogram display
+disp h1d blue
+#  2D histogram display
+disp h2d
+#  Function display
+func sin(x)/x 0.1 10. 200 gold
+#  Surface representation of a matrix
+surf mtx1 colbr32
+# Contour representation of a matrix
+contour mtx1 'colrj32 normalline ncont=7'
+#  3D representation of points using a PAW like command
+n/plot nt31.z%y%x ! ! win
+#  3D points superimposed on the previous display
+nt3d nt32 x y  z ex ey ez - - 'same fcirclemarker7 red'
+\end{verbatim}
+
+\subsection{NTuple vue / PAW like commands}
+It is possible to plot various expressions of objects, seen as
+a 2D table, with named columns. This possibility exist not only 
+for NTuples/DataTables, but also for most objects (from SOPHYA) handled 
+by piapp. The related commands are grouped under {\bf Expr.Plotting} and 
+{\bf pawCmd} and are described in section \ref{tableplot}.
+
+\subsection{C++ execution inside piapp}
+For more complex processings, where the full power of C++
+and the class libraries are necessary, {\bf piapp} provide 
+the possibility of executing C++ code, without the burden 
+of having to write a complete program. The objects 
+present in the current directory are automatically 
+declared. The communication with the piapp application 
+is done by the {\bf NamedObjMgr} class. 
+Two macros {\tt KeepObj()} and {\tt DisplayObj()}
+simplify the task of keeping newly created objects.
+In the example below, we first create a noisy signal 
+in a vector, and we keep it in the application 
+(Notice the use of multiline command) :
+
+\begin{verbatim}
+Cmd> c++exec c++exec Vector in(1024); \
+...? in = RandomSequence(RandomSequence::Gaussian, 0., 1.); \
+...? for(int kk=0; kk<in.Size(); kk++) \
+...? in(kk) += 2*sin(kk*0.05); \
+...? KeepObj(in);
+\end{verbatim}
+We can of course display the resulting vector:
+\begin{verbatim}
+Cmd> disp in 
+\end{verbatim}
+
+And, at a subsequent stage, make a low pass filter 
+on the vector in:
+\begin{verbatim}
+Cmd> c++exec 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.); \
+...? KeepObj(out);
+\end{verbatim}
+
+We can display the new vector {\tt out} overlayed 
+on the previously displayed vector:
+\begin{verbatim}
+Cmd> disp out 'red same'
+\end{verbatim}
+
+See section \ref{flycplusplus} and command group {\bf CxxExecutorCmd} 
+for more information.
+
+\subsection{Extending the application}
+The {\bf piapp} application can easily be extended by the user.
+This is done through shared libraries which can be opened 
+and used by the application. 
+Two main methods can be used (see  command group 
+{\bf ExternalModules}) : 
+\begin{itemize}
+\item Creation of user functions. A shared library containing 
+at least one user function with the following prototype
+should be created:
+\begin{verbatim}
+extern "C" {
+  void myfonction(vector<string>& args);
+}
+\end{verbatim}
+The class {\bf NameObjMgr} should be used to communicate with the 
+application. The {\tt link} \myppageref{link} and {\tt call} \myppageref{call}
+should be used to load and execute user functions. An example of
+user function can be found in DemoPIApp/user.cc exlink.pic.
+
+\item Creation of loadable modules: Loadable modules can be 
+used to extend the application possibilities in a way totally 
+transparent to the user. It is possible to define new commands, 
+handling of new object types, additional graphic functionalities
+in a loadable module.
+
+The class {\bf CmdExecutor} is the base class for extending piapp.
+A shared library should be built, containing two functions,for
+the activation and deactivation of the module, with the following
+prototype (where {\tt mymodule} is the module's name.
+\begin{verbatim}
+extern "C" {
+  void mymodule_init();
+  void mymodule_end();
+}
+\end{verbatim}
+
+\end{itemize}
+
+%%%%%%%%%% Section 3: Graphiques
+\newpage
+\section{Interactive graphics} 
+\label{intgraphics}
+%%%
+\subsection{Display commands}
+Many objects managed by piapp have a default graphic representation. The 
+{\bf disp} command  \myppageref{disp} can be used to display the object, while 
+other commands like {\bf surf} \myppageref{surf} , {\bf imag} 
+or {\bf contour} \myppageref{contour} will try to force a given graphic representation. 
+
+Data from table like objects can be plotted using commands like {\bf nt2d}
+\myppageref{nt2d} or {\bf nt3d} \myppageref{nt3d}. Most objects in piapp 
+can also be manipulated like table for plotting purposes, using commands
+like  {\bf plot2d} \myppageref{plot2d} , {\bf plot3d} \myppageref{plot3d} 
+or {\bf n/plot}  \myppageref{nZplot}. These commands are described in section
+\ref{tableplot}. 
+
+Commands producing a graphic output have usually an optional argument called \\
+{\tt graphic\_attributes} or {\tt gr\_att}. \\
+This argument provide a flexible and easy 
+way to change and customise the output graphic, as discussed in the paragraphs below.
+ 
+The piapp graphics can be exported in postscript (.ps) or encapsulated postscript 
+(.eps) format. The commands {\bf w2ps} \myppageref{w2ps} and 
+ {\bf w2eps} \myppageref{w2eps} as well the menu  \menubar{PostScript} can 
+ be used to export graphics. \\[2mm]
+The examples in the following pages illustrates the usage of some piapp graphic commands. 
+% \newpage
+\begin{enumerate}
+\label{francetopo}
+\item Image display. The following example uses the data file francetopo.ppf
+which can be found in the {\bf DemoData} directory. This PPF file contains 
+a TMatrix$<$int\_2$>$ (short integers) representing  30 arcmin gridded
+($\sim$ 1 km N-S $\times$ 0.7 km E-W) elevation (or altitude)
+for the area centered on France. It has been made using topographic 
+data (DEM: Digital Elevation Model) available from the {\bf N}ational 
+{\bf G}eophysical {\bf D}ata {\bf C}enter 
+\href{http://www.ngdc.noaa.gov/mgg/topo/}{({\bf NGDC/GLOBE})}
+\footnote{NGDC web site: \hspace{5mm} 
+http://www.ngdc.noaa.gov/ }.
+In section \ref{tableplot}, an example shows how to use this data set to 
+create altitude distribution histogram for selected regions.
+\begin{verbatim}
+#  Open a PPF file containing topographic data for france
+#  as a TMatrix<short> 1332x1548 
+#  The file is in the directory DemoData/
+openppf francetopo.ppf
+#  Display the matrix, whit a zoom factor, lut and color map
+disp francetopo 'zoom/3 lut=lin,-700,800 colbr128 win' 
+w2eps francetopo.eps 
+\end{verbatim}
+\begin{center}
+\includegraphics[width=13cm]{francetopo.eps}
+\end{center}
+
+\item Simple 2D graphics with vector displays
+\begin{verbatim}
+#  Create and initialize two vectors - prevent display : nodisp
+Cmd> newvec vva 100 sin(x/10.+0.7)+cos(x/7.+1.4)*1.26 nodisp 
+Cmd> newvec vvb 100 sin(x/10.)+cos(x/7.)*1.34 nodisp 
+#  Set axe drawing options 
+Cmd> setaxesatt 'font=times,bold,16 minorticks tickslen=0.02,0.012'
+#  Display the two vectors, with different graphic attributes
+Cmd> disp vva 'red line=solid,2 notitle'
+#  Define a title for the graphic
+Cmd> settitle 'Example-1: 2 vectors'  ' ' 'font=times,bolditalic,18'
+Cmd> disp vvb 'blue marker=box,7 same'
+#  Save the graphic into an eps file
+Cmd> w2eps gr2vec.eps
+\end{verbatim}
+% \begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=12cm]{gr2vec.eps}
+% \label{g22vec}
+\end{center}
+%%%
+\item Creating a comparison chart using {\bf bargraph}
+\begin{verbatim}
+#  Representation du PNB (en $, 2003) pour quelques pays
+set pays ( Allemagne Espagne France Italie Pays-Bas Suisse UK USA )
+set pnbh ( 22670 14430 22010 18960 23960 37930 25250 35060 )
+setaxesatt 'font=times,bold,16'
+bargraph pnbh pays - 'blue horizontalbars nofill packfrac=0.65 font=helvetica,bold,14'
+setaxelabels 'PNB / Hab , $ 2003' ' ' 'font=times,bold,16'
+w2eps pnbargraph.eps 
+\end{verbatim}
+\begin{center}
+\includegraphics[width=12cm]{pnbbargraph.eps}
+\end{center}
+%%%
+\item Displaying a matrix as a surface 
+\begin{verbatim}
+openppf demo.ppf mtx1
+setaxesatt 'font=time,bold,16'
+surf mtx1 'colbr128 line=solid,1 grey'
+w2eps surfcol.eps
+\end{verbatim}
+\begin{center}
+\includegraphics[width=13cm]{surfcol.eps}
+\end{center}
+
+\end{enumerate}
+
+%%%%%%%%%%
+\subsection{Graphic objects in piapp}
+The piapp graphics is handled by the {\bf PI} \footnote {http://www.sophya.org/PI} library,
+which provide a large variety of 2D representations, 
+few 3D graphics and powerful image display. \\
+Currently, all graphic representations, except for image displays, are handled
+through {\bf PIDrawers} which are managed by a viewer. A viewer can 
+manage several {\bf PIDrawers} objects which correspond then to a multilayer 
+graphic display. The viewers are also responsible for managing user
+interactions. \\
+Image displays are handled through a specific viewer 
+{\bf  PIImage} which is also capable of managing PIDrawer objects 
+for multi-layer 2D overlay vector graphics. \\[2mm]
+%%
+Main piapp/PI graphic viewers, windows and drawer objects are described if 
+the following sections.
+
+\subsubsection{PIScDrawWdg (2D display)}
+The {\bf PIScDrawWdg} handles a set of  of 2-D drawers, managing 
+the 2D coordinate  system and interactive zoom. The axes drawing is 
+handled by a specialised drawer, number 0, which also manages various added 
+graphic elements (text \ldots). The list of various mouse and 
+keyboard actions is described in the reference section, under {\bf PIScDrawWdg} \myppageref{PIScDrawWdg} title. In particular, mouse-button-2 can be used 
+to zoom on a particular part, {\tt $<$Alt$>$A} activates the coordinates
+and axes manipulation window ({\bf PIAxesTools}) and   {\tt $<$Alt$>$G} 
+activates the PIDrawer graphic attributes control window ({\bf PIDrawerTools}).
+%%%
+\subsubsection{PIDraw3DWdg (3D display)}
+The {\bf PIDraw3DWdg}  handles a set of of 3-D drawers, managing
+interactive camera/object rotation (mouse-button-2) and zoom (mouse-button-2). 
+{\tt $<$Alt$>$G} to display/activate  the PIDrawer graphic attributes 
+control window ({\bf PIDrawerTools}).
+See {\bf PIDraw3DWdg} \myppageref{PIDraw3DWdg} for a complete list of mouse
+and keyboard actions.
+Drawer 0 handles axes drawing and graphic elements.
+%%%
+\subsubsection{PIImage (Image Display)}
+The display of 2-D arrays $A(i,j)$ as an image is managed by 
+the {\bf PIImage} viewer/widget. The PI library interface  {\bf P2DArrayAdapter} is used
+to represent a generic 2-D array. The array values are converted into an index, converted 
+itself into a color by the use of a color-map or color-table {\bf PIColorMap}. 
+$$ \mathrm{LUT:} A(i,j) \longrightarrow idx(i,j) \hspace{5mm} \mathrm{ColorMap:}
+ idx(i,j) \longrightarrow col(i,j) $$
+Currently index range is 0...255 with color-map having 32 or 128 distinct colors.
+PIImage viewers  controls a zoom widget, as well as a global image view widget, and 
+a color map view widget. A specific image control window can be activated using 
+ {\tt $<$Alt$>$O}.  See {\bf PIImage} \myppageref{PIImage} for 
+a complete list of mouse and keyboard actions. A base drawer (number 0) can handle
+axes drawing and added graphic elements.
+%%%
+\subsubsection{Windows}
+The viewers described above are displayed in differnt kind of windows.
+The graphic option {\tt next,win,same,stack} can be used to control the way the
+type of windows used. Graphic windows can be divided into several zones
+(Command {\bf zone} \myppageref{zone}). 
+
+When an object is diplayed in piapp, a widget (PIWdg) is created which manages 
+the drawer or the 2d-array.  The default name for this widget is the displayed 
+object name. However, it is possible to specify a name using the graphic attribute: \\
+\hspace*{5mm} {\tt wname=WidgetName} \\
+It is possible to display multiple objects on a single widget, corresponding
+to the superposition of the different drawers. Displaying an object superimposed
+on the previously displayed object can be done using the graphic option 
+{\tt same}. It is also possible to specify a target widget by its name, through 
+the graphic option \\
+\hspace*{5mm} {\tt samew=WidgetName} \\
+It is also possible to specify the display of the drawer in a specified region
+of the last displayed widget \\
+\hspace*{5mm} {\tt same=fx1,fx2,fy1,fy2} \\
+where {\tt fx1,fx2,fy1,fy2} express X and Y limits, as fraction of widget size. 
+ 
+Refer to the command reference section on windows ({\bf Windows}
+\myppageref{Windows})
+for information on the different type of windows used by piapp 
+and their properties. \\
+ 
+%%% 
+\subsubsection{Drawers}
+Graphical representation of most objects in piapp is 
+handled through objects inheriting from the {\bf PIDrawer class}. A base drawer 
+({\bf PIElDrawer}, number 0) is associated to the three viewers presented above,
+and manages the axes drawing as well as the added graphic elements 
+(text, arrow, \ldots). A drawer management menu 
+can be activated using {\tt $<$Alt$>$D}. This menu can be used to move and resize
+drawers, or to display a window for changing drawers graphic attributes. 
+%%%
+\par
+In addition, a number of control windows can be used to examine and 
+change view properties of differents viewers and drawers.
+\begin{itemize}
+\item[] {\bf PIDrawerTools} activated using {\tt $<$Alt$>$G} or 
+\menubar{Tools/Show DrawerTools} on any viewer (see page \myppageref{secdrwtools})
+\item[] {\bf PIAxesTools} activated using {\tt $<$Alt$>$A} or 
+\menubar{Tools/Show AxeTools} on PIScDrawWdg (see page \myppageref{secaxestools})
+\item[] {\bf PIImageTools} activated using {\tt $<$Alt$>$O} or 
+\menubar{Tools/Show ImageTools} on PIImage
+(see page \myppageref{secimagetools})
+\item[] {\bf PIHisto2DTools} activated using {\tt $<$Alt$>$O} or through the PIDrawerTools
+for an active PIHisto2D drawer. (see page \myppageref{sech2dtools})
+\item[] {\bf PIContourTools}  activated using {\tt $<$Alt$>$O} or through the PIDrawerTools
+for an active PIContourDrawer  drawer.  (see page \myppageref{secconttools})
+\end{itemize}
+These control tools are briefly described in appendix.
+
+%%%%%%%%%%
+\subsection{Graphic attributes}
+Graphic attributes are specified as a set of space separated strings. Use 
+quotes to group them into a single argument parsed by the command
+interpreter. The options are decoded by the different objects handling the 
+graphic (viewer widget, drawer, axe drawer). \\
+The complex decoding scheme 
+is usually transparent for piapp users. However, there is an ambiguity when 
+specifying some of the axes attributes, such as color or the font used for 
+drawing the axes. The command {\bf setaxesatt}  (\myppageref{setaxesatt})
+should thus be used to specify generic graphic attributes 
+(color, font, line type) for axes. 
+\subsubsection{PIScDrawWdg}
+The {\bf PIScDrawWdg} which handles 2d graphics recognizes the following options: 
+\begin{verbatim}
+>> To define the 2D axes limits (in user coordinates)
+   xylimits=xmin,xmax,ymin,ymax  
+>>  To define the default drawing rectangle, in fraction of widget size
+  defdrrect=x1,x2,y1,y2  (default: x1=y1=0.1  x2=y2=0.9) 
+>> Axes flags :
+  linx  logx  liny logy 
+>> To change the background color (default=white)
+  wbgcol=colname
+  
+\end{verbatim}
+%%%
+\subsubsection{PIDraw3DWdg}
+The {\bf PIDraw3DWdg} which handles 3d graphics recognizes the following options:
+\begin{verbatim}
+>> To define the 3D box limits : 
+  xyzlimits=xmin,xmax,ymin,ymax,zmin,zmax
+  limit3dbox=xmin,xmax,ymin,ymax,zmin,zmax
+>> Autoscaling flags (rescaling of X/Y or X/Y/Z axes)
+  autoscale3dbox  / noautoscale3dbox
+  autoscalexy3dbox / noautoscalexy3dbox
+  autoscalez3dbox / noautoscalez3dbox
+>> To change the background color (default=white)
+  wbgcol=colname
+  
+\end{verbatim}
+%%%
+\subsubsection{PIImage}
+The {\bf PIImage} which handles image display recognizes the following options: 
+\begin{verbatim}
+>> Define display zoomfactor 
+  zoomxFact     (zoomx2 zoomx3 ... zoomx9 ...)
+  zoom/Fact  (zoom/2 zoom/3 ... )
+>> LUT (look-up table) definition (pixel value to index conversion)
+  lut=type,min,max   (type=lin/log/sqrt/square)
+>> AutoLut selector : define the method for automatic determination 
+     of LUT limits (min/max) 
+  autolut=alt[,ns[,minp,maxp]] (minp<=pixels<=maxp)
+   - autolut=minmax[,Frac] 0<=Frac<=1
+   - autolut=meansig[,ns] --> mean +/- ns*sigma  
+   - autolut=hispeak[,ns] --> around the peak of pixel values histogram
+   - autolut=histail[,ns] --> the tail of pixel values histogram
+>> Define color table and reversing color indexing flag
+  ColTableName     revcmap
+  ==> Standard tables with 32 distinct colors:
+          grey32  invgrey32 colrj32  colbr32  colrv32  
+  ==> Standard tables with 128 distinct colors:
+          grey128  invgrey128  colrj128  colbr128
+  ==> Shades of red/green/blue ...
+           red32cm  green32cm  blue32cm  yellow32cm 
+           orange32cm cyan32cm violet32cm 
+  ==> Some of MIDAS color tables :
+          midas_pastel  midas_heat  midas_rainbow3
+          midas_bluered  midas_bluewhite  midas_stairs8
+          midas_stairs9 midas_staircase midas_color
+          midas_manycol  midas_idl14  midas_idl15
+  ==> Other tables
+          multicol16 multicol64
+>> Viewed center position (image/array coordinates)
+  imagecenter=xc,yc  
+>> Array axes to window axes mapping flags
+  invx  invy  exchxy 
+>> To change the background color (default=black)
+  wbgcol=colname
+  
+\end{verbatim}
+%%% 
+\subsubsection{PIGraphicAtt}
+The {\bf PIGraphicAtt} Generic graphic attributes (color/font/line \ldots)
+decoded by all drawers: 
+\begin{verbatim}
+>>> color=ColorName - fgcolor=ColorName - bgcolor=ColorName 
+   ColorName: black white grey red blue green yellow 
+              magenta cyan turquoise navyblue orange 
+              siennared purple  limegreen gold violet 
+              violetred blueviolet darkviolet skyblue 
+              royalblue forestgreen orangered brown 
+>>> line=DashType,LineWidth  
+   DashType: solid, dash, dotted, dashdotted   Width: 1,2,...
+>>> font=FontName,FontAtt,FontSize  
+   FontName: courier, helvetica, times, symbol   
+   FontAtt: roman, bold, italic, bolditalic  
+   FontSize: 6,8,10,12... (pts) - integer 
+>>> marker=MarkerType,MarkerSize (MarkerSize: integer 3,5,7... 
+   MarkerType: dot, plus, cross, circle, fcircle, box, fbox 
+               triangle, ftriangle, star, fstar 
+>>> arrow=ArrowType,ArrowSize (ArrowSize: integer 3,5,7... 
+   ArrowType: basic, triangle, ftriangle, 
+              arrowshaped, farrowshaped
+>>> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32 
+                grey128  invgrey128  colrj128  colbr128 
+                red32cm  green32cm  blue32cm  yellow32cm 
+                orange32cm cyan32cm violet32cm 
+                midas_pastel midas_heat midas_rainbow3 midas_bluered
+                midas_bluewhite midas_redwhite 
+                multicol16 multicol64
+>   revcmap : This flag reverses ColorMap indexing 
+------- Old style graphic att ---------- 
+>> Lines:  defline normalline thinline thickline dashedline thindashedline 
+           thickdashedline dottedline thindottedline thickdottedline 
+>> Font Att: deffontatt normalfont boldfont italicfont bolditalicfont  
+             smallfont smallboldfont smallitalicfont smallbolditalicfont 
+             bigfont bigboldfont bigitalicfont bigbolditalicfont 
+             hugefont  hugeboldfont hugeitalicfont hugebolditalicfont 
+>> Font Names: deffont courierfont helveticafont timesfont symbolfont  
+>> Marker: dotmarker<S>  plusmarker<S>  crossmarker<S> circlemarker <S> 
+           fcirclemarker<S> boxmarker<S> fboxmarker<S> trianglemarker<S> 
+           ftrianglemarker<S>  starmarker<S>  fstarmarker<S> 
+   with <S> = 1 3 5 7 9 , Example fboxmarker5 , plusmarker9 ... 
+   
+\end{verbatim}
+%%%%
+\subsubsection{PIElDrawer}
+The {\bf PIElDrawer} decodes axe drawing attributes: 
+\begin{verbatim}
+ >> Axe and grid configuration flags: 
+   axesnone  stdaxes defaxes 
+   boxaxes boxaxesgrid fineaxes fineaxesgrid 
+   centeredaxes finecenteredaxes centeredaxesgrid 
+   finecenteredaxesgrid  grid/nogrid 
+ >> Centered axes position: axescenter=xc,yc 
+ >> Axe ticks/labels (h=horizontal/x, v=vertical/y): 
+   labels/nolabels  hlabels/nohlabels vlabels/novlabels 
+   ticks/noticks minorticks/nominorticks 
+   extticks/intticks/extintticks nbticks=X_NbTicks,Y_NbTicks 
+   tickslen=MajorTickLenFrac,MinorTickLenFraC 
+ >> Axe label font size: 
+    autofontsize=FontSizeFrac fixedfontsize 
+ >> Up/Down title: title tit notitle notit 
+    ... Color/Font/line attributes : 
+    
+\end{verbatim}
+The {\bf PINTuple} handles most 2D plotting : \\
+\begin{verbatim}
+  sta,stat,stats:            activate   statistic display
+  nsta,nstat,nostat,nostats: deactivate statistic display
+  statposoff=OffsetX,OffsetY : Position offset for Stats drawing 
+      as a fraction of total size 
+  connectpoints: The points are connected by a line 
+  noconnectpoints (this is the default) 
+  colorscale/nocolorscale (Use color scale for weight) 
+  sizescale/sizescale=nbins/nosizescale (Use marker size for weight) 
+   (and usual color/line/marker/... attribute decoding)
+   
+\end{verbatim}
+%%%
+\subsubsection{PIHisto, PIHisto2D}
+{\bf PIHisto} and {\bf PIHisto2D} handle1D and 2D histograms display. \\
+The following options are recognised by {\bf PIHisto}: \\
+\begin{verbatim}
+ ---- PIHisto options help info : 
+  sta,stat,stats:            activate   statistic display
+  nsta,nstat,nostat,nostats: deactivate statistic display
+  err / noerr,nerr : draw, do not draw error bars
+  autoerr : draw error bars if Marker drawing requested OR Profile histo
+  fill / nofill,nfill : fill, do not fill bars with selected color
+  statposoff=OffsetX,OffsetY : Position offset for Stats drawing 
+       as a fraction of total size 
+  ---- HistoWrapper options : 
+ hbincont: select bin content as Y value for display (default) 
+ hbinerr: select bin error as Y value for display 
+ hbinent: select bin entries as Y value for display 
+ hscale=value : multiplicative factor for Y value 
+ hoffset=value : additive coefficient for Y value 
+ hs1: set hscale=1 hoffset=0  (default) 
+ hscale=value  : multiplicative factor (in Y) 
+
+\end{verbatim}
+The following options are recognised by {\bf PIHisto2D}: \\
+\begin{verbatim}
+- sta,stat,stats:            activate   statistic display
+  nsta,nstat,nostat,nostats: deactivate statistic display
+- h2disp=typ[,fracpts]: choose display type
+    typ=var: variable size boxes
+    typ=hbk: "a la hbook2"
+    typ=img: image like (use "h2col" for color map)
+    typ=pts: point clouds (fracpts=max possible fraction
+             of used pixels per bin [0,1])
+- h2scale=lin/log[,logscale]: choose linear or logarithmic scale
+- h2dyn=[hmin][,hmax]: choose histogramme range for display
+- use general key to define color table (ex: grey32,midas_heat,...)
+            (see general graphicatt description)
+- use key "revcmap" to reverse color table
+- h2frac=[fmin][,fmax]: choose sub-range display [0,1]
+  ---- HistoWrapper options : (see HistoWrapper above)
+
+\end{verbatim}
+%%%%
+\subsubsection{PINTuple3D , PISurfaceDrawer}
+The {\bf PINTuple3D} and {\bf PISurfaceDrawer} 
+handles basic 3D plotting and can decode the common 3D box options:
+\begin{verbatim}
+  X/Y,Z axis rescaling option (-> cubic 3D box)  
+  rescale=autoscale/ norescale=noautoscale : X/Y and Z axis 
+  rescalexy=autoscalexy / norescalexy=noautoscalexy : X/Y  axis 
+  rescalexy=autoscalexy / norescalexy=noautoscalexy : Z axis 
+\end{verbatim}
+The {\bf PINTuple3D} decodes in addition the following options:
+\begin{verbatim}
+ connectpoints: The points are connected by a line 
+  noconnectpoints (this is the default) 
+  colorscale/nocolorscale (Use color scale for weight) 
+  sizescale/sizescale=nbins/nosizescale (Use marker size for weight) 
+  
+\end{verbatim}  
+
+\subsubsection{PIContourDrawer}
+The {\bf PIContourDrawer} decodes the following options :  \\
+\begin{verbatim}
+ autolevels : automatic selection of levels and number of contours 
+ ncont=nLevel (or nc=NLevel) : sets the number of contour
+ lev=v1,v2,v3... (or niv=v1,v2,v3...) set the number and levels of contours
+ lstep=nLev,start,step : define incremental levels 
+ labon/laboff : display of contour level values on/off 
+ linear/bspline/cubicspl=3spl : select contour kind 
+ 
+\end{verbatim}  
+
+\subsubsection{PIBarGraph , PITextDrawer}
+{\bf PIBarGraph} is used by the {\tt bargraph} \myppageref{bargraph}
+command and has the following graphic options:
+\begin{verbatim}
+ ---- PIBarGraph options help info : 
+  fill/nofill: set bar fill option 
+  horizontalbars/verticalbars: set bar orientation 
+  packfrac=value : set bar packing fraction (0..1) 
+  barvaluelabel/nobarvaluelabel: Use/Don't use bar value as labels 
+ --- + Usual colr/line/font  attribute decoding ... 
+ \end{verbatim}
+The command {\tt textdrawer} \myppageref{textdrawer} uses the 
+{\bf PITextDrawer} which has the following options : \\
+\hspace*{10mm} {\tt frame,noframe: enable/disable frame drawing}
+
+
+%%%%%%%%%%%%%%% Section 4 :   I/O
+\newpage
+\section{Data formats and input-output (I/O)}
+The data file formats recognized by piapp are the ones supported by the 
+SOPHYA library or its extension.
+\begin{itemize}
+\item[\bul] ASCII files - Data can be imported from ascii (text) files as
+datatables or arrays. These objects can also be exported as text files.
+\item[\bul] FITS files - FITS is a popular format used in particular in astronomy. 
+\href{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
+Data is usually read from FITS files as vectors, images, cubes or tables. 
+A subset of SOPHYA objects can be imported or exported in FITS format. 
+\item[\bul] PPF (Portable Persistence file Format) is the native SOPHYA 
+data format.
+\item[\bul] PostScript - All graphic output produced by piapp can be exported
+as postscript (.ps) or encapsulated postscript (.eps) files.
+\end{itemize}
+
+\subsection{Text files}
+Text (or ascii) files can be read into array or datatable objects by spiapp. 
+
+{\bf Arrays :} \\
+Arrays can be written to to files in text/ascii format using the {\tt arrtoascii}
+  \myppageref{arrtoascii} command. Double precision matrices and vectors 
+  can be read from text files using the commands 
+  {\tt mtxfrascii}  \myppageref{mtxfrascii} and
+    {\tt vecfrascii}  \myppageref{vecfrascii} . \\
+The menu-bar command  \menubar{File/Open-ASCII} reads in a text 
+file as a matrix. 
+\begin{verbatim}
+#  Create and initialize a matrix
+newmtx arr 250 150 x+3*y 
+#  Save the file in the text file arr.txt
+arrtoascii arr arr.txt
+#  Read the previously created file and fill a matrix
+mtxfrascii mxa arr.txt
+#  Print and display the matrix 
+print mxa
+disp mxa zoomx2
+\end{verbatim}
+It is possible to specify the field separator in the input file, as well as the marker for the comment 
+lines. 
+
+{\bf DataTable :} \\
+Text files can also be read as a 2-D table (NTuple or DataTable). The table should be 
+created using the  {\tt newnt} \myppageref{newnt}  or 
+{\tt newdt} \myppageref{newdt} command.  
+The command {\tt ntfrascii} \myppageref{ntfrascii} can then be used to append
+data from the file to the datatable.
+
+\subsection{PPF}
+%%%
+PPF (Portable Persistence file Format) is the the native persistence 
+format of SOPHYA and thus is fully handled by spiapp.   PPF files can 
+be opened through the menu-bar  \menubar{File/Open-PPF}, or through 
+the {\tt openppf} \myppageref{openppf}.
+
+If the PPF file contains NameTags, only the objects marked with nametags are read and given 
+the corresponding names. Otherwise, all objects are red sequentially, with their names 
+formed by the filename followed by a sequence number. It is also possible to force the sequential 
+reading specifying the {\tt -s} flag for openppf.
+
+The objects managed in spiapp by the {\bf NamedObjMgr} can be saved to PPF files, with their
+names as NameTags. The commands {\tt saveppf} \myppageref{saveppf} or 
+ {\tt saveall} \myppageref{saveall} can be used to this end.
+
+\begin{verbatim}
+# Create two vectors and two matrices
+newvec va1 150 sin(sqrt(x)) 
+newvec vb2 150 sin(sqrt(x))*sqrt(x*0.1)
+newmtx mxa 250 150 x+2.*y
+newmtx mxb 250 150 sin(sqrt(x))*cos(sqrt(y))
+# List of the objects in memory 
+listobjs
+#  Save the two vectors in the file vecab.ppf
+saveppf v* vecab.ppf
+#  Save the two matrices in the file mxab.ppf
+saveppf m* mxab.ppf
+\end{verbatim}
+
+\subsection{FITS}
+FITS files may contain three types of data structures 
+\begin{enumerate}
+\item Image or array data structure : {\tt IMAGE\_HDU}
+\item Binary table : {\tt BINARY\_TBL}
+\item ascii table : {\tt ASCII\_TBL}
+\end{enumerate}
+The {\bf FitsIOServer} module contain FitsHandler classes which 
+can map many SOPHYA classes on FITS data structures.
+Generic {\tt IMAGE\_HDU} correspond to the SOPHYA \tcls{TArray}
+class, while {\tt BINARY\_TBL} or {\tt ASCII\_TBL} is mapped 
+to NTuple or DataTable.
+
+FITS format files can be read through the menu command \menubar{File/Open-Fits},
+or using {\tt readfits/openfits} \myppageref{readfits} command.
+Objects can be exported to FITS using the {\tt writefits/savefits} 
+\myppageref{writefits} command.
+
+\begin{verbatim}
+# Open the PPF file created by the commands above
+openppf vecab.ppf
+# Export the two vector objects to file vecab.fits
+# Note that the '!' forces c-fitsio to overwrite the file, if it exists
+writefits v?? !vecab.fits
+\end{verbatim}
+
+There are two commands useful 
+when analyzing large catalogs (BINARY\_TBL) in FITS format, which avoid reading the whole
+table in memory. {\tt swfitstable}\myppageref{swfitstable} reads a specified HDU 
+as a {\bf SwFitsDataTable} object which uses the FITS file as swap space.
+The {\tt fitsadapt}\myppageref{fitsadapt} can also be used for similar purposes.
+
+The following commands shows how to open a FITS file containing a synchrotron map
+of our galaxy. This file contains sky emission at 408 MHz, 
+as brightness temperature, represented as a SOPHYA spherical map 
+(SphereHEALPix$<$r\_4$>$) in \href{http://healpix.jpl.nasa.gov/}{\bf HEALPix} 
+format \footnote{HEALPix home page: \hspace{5mm} http://healpix.jpl.nasa.gov/}.
+It has been made, by rebinning, from the Haslam 408 MHz 
+all sky survey map, available from the NASA CMB data repository 
+\href{http://lambda.gsfc.nasa.gov/}{\bf LAMBDA}
+\footnote{LAMBDA web site: \hspace{5mm} http://lambda.gsfc.nasa.gov/}.
+\label{syncmap}
+\begin{verbatim}
+#  Open the fits file : the map is in HEALPix format
+readfits syncmap.fits
+#  Create a window with the appropriate size
+newwin 1 1 800 400
+# Display the map, specifying the colormap
+disp syncmap 'lut=lin,2,50 midas_bluered'
+\end{verbatim}
+\begin{figure}[h]
+\begin{center}
+\includegraphics[width=15cm]{syncmap.eps}
+\caption{Synchron map of our Galaxy, displayed in Molleweide projection.
+The underlying SOPHYA object is a \tcls{SphereHEALPix} }
+\end{center}
+\end{figure}
+
+\subsection{Graphic export in postscript}
+%%
+Postscript a page description language widely used for printing and 
+graphic output, developed by Adobe systems. Refer to 
+\href{http://www.adobe.com/products/postscript/}{Adobe/PostScript3} 
+for more detail.
+
+Piapp graphic output can be exported in postscript (level 2) or
+encapsulated postscript format, preserving the full precision 
+of vector graphics. 
+Postscript (.ps) files my contain several pages, each vue or window
+corresponding to one page and are suitable for direct printing. 
+An Encapsulated Postscript (.eps) file contains a single page,
+corresponding to a window and is suitable for inclusion in 
+other document. 
+
+Postscript file can easily be converted to other formats, 
+PDF or image formats (jpeg \ldots) using converters like
+{\bf ps2pdf} or {\bf imagemagick}.  
+
+The menu items under \menubar{PostScript} can be used to export 
+graphics in postscript. The default file name is {\tt pia.ps}
+or {\tt pia1.eps} {\tt pia2.eps} \ldots
+The following commands can also be used to create postscriot file
+from the display in the current graphic window:
+\begin{itemize}
+\item {\tt w2ps} \myppageref{w2ps} to add the current graphic 
+output as a new page to the output postscript file.
+The current output postscript file (default = w2ps.ps) 
+should be closed before being used. Exiting piapp closes automatically 
+all postscript files.
+\item {\tt psclosefile} \myppageref{psclosefile} to close the current
+output postscript file.
+\item {\tt pssetfilename} \myppageref{pssetfilename} To define 
+the output postscript file name for the subsequent {\tt w2ps} commands.
+\item {\tt w2eps} \myppageref{w2eps} to export the current 
+graphic display, in Encapsulated Postscript format to the specified file. 
+\begin{verbatim}
+# Open the PPF file created by the commands above
+openppf vecab.ppf
+# Display one of the vectors
+setaxesatt 'font=helvetica,bold,18 fixedfontsize'
+disp va1 'blue marker=box,5' 
+#  Export the graphic to file va1.eps
+w2eps va1.eps 
+#  The created file can be viewed using gv 
+\end{verbatim}
+\end{itemize}
+
+%%%%%%%%%%%%%%% Section 5 :   analyse a la paw
+\newpage
+\section{Tables and Expression Plotting}
+\label{tableplot}
+A powerful data analysis technic available in piapp is 
+2D, 3D plot, and histogramming applied to arbitrary analytical 
+expression of table columns.
+This analysis technic has been introduced by the popular 
+CERN \href{http://paw.web.cern.ch/paw/}{\bf PAW} 
+({\bf P}hysics {\bf A}nalysis {\bf Workstation}) 
+\footnote{PAW home page : http://paw.web.cern.ch/paw/ } program
+and the underlying HBOOK fortran library.
+Compared to PAW, piapp extends in many respects this capability,
+piapp offers in particular the possibility to manipulate many 
+objects as if they where a DataTable, or NTuple. 
+There are also additional 2D and 3D representations e.g. 
+{\tt plot2de} \myppageref{plot2de},  
+{\tt plot2dw} \myppageref{plot2dw},  
+{\tt plot2dc} \myppageref{plot2dc} and
+{\tt plot3dw} \myppageref{plot3dw}.
+
+\subsection{How does it work ?}
+
+The Expression.Plotting commands in piapp operate on objects through the 
+{\bf NTupleInterface} class methods. Some classes like NTuple or BaseDataTable
+inherit from NTupleInterface, while for the other classes, the corresponding 
+NObjMgrAdapter class exposes an object conforming to NTupleInterface through the 
+method : \\
+\hspace*{5mm} {\tt  NTupleInterface* NObjMgrAdapter::GetNTupleInterface()} \\
+A C file (PIATmp\_xxx/expf\_pia\_dl.c) is created by piapp containing the 
+specified expressions, which should conform to the C-language syntax.
+In addition to the functions in {\tt math.h} (sin, cos, log \ldots), 
+the following functions are defined by piapp and can be used:
+\begin{itemize}
+\item Flat random number generators: {\tt drand01() , drandpm1() }
+\item Gaussian random number generator: {\tt GauRand() }
+\item Angle conversion: {\tt deg2rad(double d), rad2deg(double r) }
+\item $(\theta,\varphi)$ to Molleweide X,Y projection: \\
+\hspace*{5mm}{\tt double tetphi2mollX(double theta, double phi)} \\
+\hspace*{5mm}{\tt double tetphi2mollY(double theta)} 
+\item Longitude(0..360) deg., Latitude(-90..90) deg. conversion to Molleweide X,Y: \\
+\hspace*{5mm}{\tt double longlat2mollX(double longit, double lat) } \\
+\hspace*{5mm}{\tt double longlat2mollY(double lat) }
+\end{itemize}
+
+The processing steps for an Expression.Plotting in piapp :
+\begin{enumerate}
+\item Creation of the C-file. 
+\item On the fly compilation of the generated file.
+\item The resulting shared-object is loaded and linked with the application
+\item Loop over the NTupleInterface object rows. The created function is called
+with the data from each row
+\item The return values are used to fill an histogram, or a matrix/vector or
+another NTuple or to produce a 2D or 3D graphic display. 
+\end{enumerate}
+
+Although rather complex, the efficiency gain during processing data easily compensates
+for the overhead of the compilation step.
+  
+\subsection{Column/variable names}
+
+When working with real 2-D tables (NTuple, DataTable \ldots), the column names
+are the name of the variables which can be used in the C-expressions.
+There is an additional variable, called {\tt \_nl}, automatically
+provided by piapp, corresponding the table row number, starting from 0.
+
+For the other objects in piapp, the variable names are listed below:
+\begin{itemize}
+\item[\rond] For 2D table objects {\bf (NTuple,DataTable,\ldots)}:  ColumnNames,\_nl
+\item[\rond] For FITS files opened through {\tt fitsadapt} command: FITSColumnNames,\_nl
+\item[\rond] For {\bf Histo1D/HProf} objects : i,x,val,err,nb,\_nl
+\item[\rond] For {\bf Histo2D} objects : i,j,x,y,val,err,\_nl
+\item[\rond] For {\bf HistoErr} objects : i,x,val,err2,nb,\_nl
+\item[\rond] For {\bf Histo2DErr} objects : i,j,x,y,val,err2,nb,\_nl
+\item[\rond] For {\bf \tcls{TVector}, \tcls{TMatrix} , \tcls{Image} } objects : \\
+ \hspace*{10mm}  n,r,c,val,real,imag,mod,phas,\_nl
+\item[\rond] For {\bf \tcls{TArray}} objects : n,x,y,z,t,u,val,real,imag,mod,phas,\_nl
+\item[\rond] For {\bf GeneralFitData} objects : x0,ex0 x1,ex1 ...  xn,exn  y,ey ,ok,\_nl
+\item[\rond] For {\bf \tcls{SphereHEALPix} , \tcls{SphereThetaPhi} , \tcls{SphereECP}
+\tcls{LocalMap} } objects : \hspace{10mm} i,k,val,real,imag,mod,phas,teta,phi,\_nl
+\end{itemize}  
+
+%%%%%
+\subsection{Examples}
+The following examples illustrates the use of some Expression Plotting commands
+(see the command groups {\bf Expr. Plotting} \myppageref{ExprZZPlotting} and
+ {\bf pawCmd} \myppageref{pawCmd}).
+The {\bf pawCmd} defines a number of operations with command name and syntax 
+similar to the CERN PAW program.
+The graphic output from the examples below are shown in the figures 
+\ref{exhis2dpl} and \ref{uzcpos}.
+\begin{enumerate}
+\item 2D plot with error bars \\[1mm]
+\begin{verbatim}
+# Set the axes attibute (the font used for axes ...)
+setaxesatt 'font=helvetica,bold,16 minorticks fixedfontsize'
+#  Open the file demo.ppf (in DemoPIApp)
+openppf demo.ppf 
+print nt21
+print nt22 
+# 2D plot directly from the NTuple columns (nt2d)
+# nt2d DO NOT use a compiled c file
+nt2d nt21 x y - - - - 'font=helvetica,bold,16'
+# Overlay a plot with scaled error bars from nt22
+plot2de nt22 x y ex*0.3 ey*0.5 1 \
+  'same marker=box,7 red font=helvetica,bold,16 ' 
+\end{verbatim}
+\vspace*{4mm}
+\item Compute the histogram of pixel values for a \tcls{SphreHEALPix}.
+The data come from the synchrotron map (syncmap.fits), described page \pageref{syncmap}.
+\begin{verbatim}
+# Open the synchrotron map file (HEALPix format spherical map)
+# The file can be found in directory DemoData/
+readfits syncmap.fits
+newwin 1 1 800 400
+disp syncmap 'lut=lin,2,50 midas_bluered'
+newwin 1 2
+# Compute and display the pixel value histogram (brightness temperature)
+n/plot syncmap.val val<200 ! ! 'font=helvetica,bold,16 notit'
+settitle 'Sky brightness @ 408 MHz' ' ' 'font=helvetica,bold,16'
+# display the pixel value histogram in the galactic plane
+n/plot syncmap.val val<200&&(fabs(teta-M_PI/2)<0.025) ! ! 'red notit'
+settitle '408 MHz - Galactic plane' ' ' 'font=helvetica,bold,16 red'
+\end{verbatim}
+\vspace*{4mm}
+\item Sources (galaxies) distribution over the sky. The data used below (uzc.ppf)
+has been extracted from the {\bf U}pdated {\bf Z}wicky {\bf C}atalog of Galaxies,
+available from the Harvard-Smithsonian Center For Astrophysics 
+\href{http://tdc-www.harvard.edu/uzc/}{CfA/UZC web site}.
+\footnote{CfA web site: \hspace{5mm} http://tdc-www.harvard.edu/uzc/} \\[1mm]
+%%% 
+\begin{verbatim}
+#  Keep the synchrotron map
+#  Open the Updated Zwicky Catalog of galaxies (in DemoData)
+openppf uzc.ppf
+zone 1 2
+# Draw a longitude-latitude grid in Molleweide projection
+mollgrid 5 7 'axesnone black font=helvetica,roman,12 notit'
+# Overlay the sources distribution from UZC, for bright objects (mag<14)
+plot2d uzc longlat2mollX(ra*15,dec) longlat2mollY(dec) mag<14 \
+  'same red marker=circle,5'
+# Change the plot title
+settitle 'RA-Dec in degrees UZC (Updated Zwicky Catalog)' ' ' \
+  'font=helvetica,bold,16 red'
+# Display the synchrotron map
+disp syncmap 'lut=lin,2,40 grey128'
+# Add the source distribution in Galactic coordinates
+plot2d uzc longlat2mollX(glong,glat) longlat2mollY(glat) mag<14  \
+  'same nsta red marker=circle,5'
+\end{verbatim}
+%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%
+\item Analysis of elevation (altitude) data for france. We use the francetopo.ppf 
+data set described page \pageref{francetopo}.
+\begin{verbatim}
+# open and display the topographic data for france
+openppf francetopo.ppf (in DemoData/ directory)
+print francetoto
+#--- TMatrix<s>(NRows=1332, NCols=1548) ND=2 SizeX*Y*...= 1548x1332 --- 
+disp francetopo 'zoom/2 imagecenter=750,700 lut=lin,-700,800 colbr128'
+#  Compute the altitude distribution
+newh1d altf 0. 4000 100
+projh1d altf francetopo val val>0.1 
+# Display the histogram overlayed on the topographic map
+disp altf 'white line=solid,2 font=helvetica,bold,14 inset=0.1,0.6,0.45,0.9'
+# Compute altitude distribution for the massif central (Auvergne)
+newh1d altmc 0. 2000 100
+# We select the region as a circle of radius 200, centered on x=c=970,y=r=920
+set regcut (sqrt((c-970)*(c-970)+(r-920)*(r-920))<200)
+projh1d altmc francetopo val (val>0.1)&&$regcut
+# Create a new window and display the two histograms
+newwin 1 2 
+setaxesatt 'font=helvetica,bold,16 fixedfontsize'
+disp altf 'notit'
+settitle 'Elevation (altitude) distribution over France' ' ' \
+  'font=helvetica,bold,16'
+disp altmc 'notit'
+settitle 'Elevation (altitude) distribution over MassifCentral' ' ' \
+  'font=helvetica,bold,16'
+\end{verbatim}
+\end{enumerate}
+
+\begin{figure}[hp]
+\includegraphics[width=15cm]{exhis2dpl.eps}
+\caption{
+top: 2d plot example with error bars \hspace{5mm}
+bottom: Histogram of pixel values from the synchrotron map 
+of our galaxy}
+\label{exhis2dpl}
+\end{figure}
+
+\begin{figure}[p]
+\includegraphics[width=15cm]{uzcpos.eps}
+\caption{UZC: Updated Zwicky Catalog. \hspace{5mm}
+top: The galaxy position distribution in equatorial 
+$(\alpha, \delta)$ coordinates. \hspace{5mm}
+bottom: Position distribution in Galactic coordinates, superimposed on 
+the synchrotron map.}
+\label{uzcpos}
+\end{figure}
+
+%%%%%%%%%%%%%%% Section 6 :  command interpreter 
+\newpage
+\section{Command interpreter}
+piapp uses the class {\bf PIACmd} which extends slightly the 
+SOPHYA class {\bf Commander} as the command interpreter.
+{\bf Commander} is a  c-shell inspired, string oriented command 
+interpreter.  Although it has many limitations compared to 
+c-shell, or Tcl , it provides some interesting possibilities:
+\begin{itemize}
+\item Extended arithmetic operations (c-like and RPN)
+\item Simple and vector variables
+\item Script definition 
+\item Command execution in separate threads
+\item Dynamic Load 
+\end{itemize}
+
+We describe below  the {\bf Commander} possibilities, 
+as well as the few {\bf PIACmd} extensions. 
+
+\subsection{Variables}
+The SOPHYA::Commander interpreter manages non typed set of variables.
+Environment variables are also accessible through 
+the usual {\tt \$varenvname}, unless shadowed by a Commander 
+variable. All Commander variables are vector of strings, and are 
+extended as necessary.  {\tt \$varname} is the string formed by all 
+the vector elements. Except when performing arithmetic operations,
+variables are treated  as strings. 
+\par 
+An application level set of variables is also managed 
+by Commander, through redefinition of \\
+{\tt Commander::GetVarApp() / GetVarApp() \ldots } methods.  \\
+The {\bf PIACmd} in piapp redefines the {\tt GetVarApp() }
+in order to provide an easy access to some of objects attributes or methods, 
+managed by {\bf NamedObjMgr} (See below).
+
+\subsubsection{Interpreter/Commander variables}
+\begin{itemize}
+\item[\rond] {\bf Definition and initialisation of variables }  
+\begin{verbatim}
+# Notice that the set command has no = sign 
+Cmd> set sv StringValue
+# Clearing/removing  of a variable : unset or clearvar 
+Cmd> unset sv 
+
+# Definition of a multi element variable (vector type)
+# Notice that spaces before / after '(' and ')' are mandatory 
+Cmd> set vecv ( mot1 mot2 mot3 mot4 mot5 )
+# Arithmetic  expression : C language syntax - spaces 
+# before/after '=' are mandatory  
+Cmd> a = 2+3*sqrt(4)
+# The '=' operator can also be used to initialize a variable with a string
+Cmd> a = 'Bonjour Madame'
+# A vector element can be specified in the left hand side
+Cmd> vecv[2] = 'coucou'
+# Or using an interpreter variable as index :
+Cmd> i = 3
+Cmd> vecv[i] = 'Ooohhh' 
+\end{verbatim}
+
+On the right hand side, the value of a variable should be accessed using 
+the \$ character.  \\
+A string can be parsed  into words using {\tt  var2words}
+\begin{verbatim}
+Cmd> var2words varname wordvarname [separateur]
+\end{verbatim}
+
+\item[\rond] {\bf Accessing variable contents } \\
+The \$ character is used to access the content of a variable {\tt \$varname} .
+Substitution rules : 
+The {\tt \$xxx} is replaced by the value of  variable xxx. 
+No substitution is performed for strings enclosed in simple quotes {\tt ' ... \$xxx '},
+but substitution is done in strings enclosed in double quotes. 
+Parenthesis or brackets can be used to specify the variable name, inside a string
+without white space: {\tt \${vname} } ou {\tt \$(vname)}.
+\begin{verbatim}
+Cmd> x = 'Hello'
+Cmd> echo $x
+# Size of a vector variable : $#vname
+Cmd> set vx ( 111 2222 3333 444444 )
+Cmd> echo $#vx 
+# Accessing vector elements 
+Cmd> echo $vx[0] $vx[1] 
+#  or using an interpreter variable as index :
+Cmd> i = 2
+Cmd> echo $vx[i] 
+# Special syntax:  $[vname] is replaced by the content
+# of a  variable whose name is $vname
+Cmd> zzz = 'Commander'
+Cmd> xxx = 'zzz'
+Cmd> echo '---> $[xxx]= '  $[xxx]
+---> $[xxx]= Commander
+\end{verbatim}
+
+\par
+\end{itemize}
+
+\subsubsection{Special variables}
+\begin{itemize}
+\item {\tt \$retval} ou {\tt \$retstr}  :  the string specified in the last {\bf return} statement 
+\item {\tt \$status} : Return code from the last executed command.
+Arguments of scripts (see below) or file executed through {\bf exec} command.
+\item {\tt \$\# } : number of arguments, except \$0 
+\item {\tt \$0}  : Script or file name  
+\item {\tt \$1 \$2 \$3} ....  : Arguments  (for scripts and .pic files (exec))
+\end{itemize}
+
+\subsubsection{Environment variables} 
+Environment variables can simply be accessed by {\tt \$varenvname}. 
+However,  the environment variables have the lowest priority during substitution.
+Interpreter's variables have the highest priority, followed 
+by the application level variables.
+
+\subsubsection{Objects/Application level variables} 
+For some classes managed by NamedObjMgr, 
+PIACmd provide acces to some of the attributes of the object by 
+{\tt \${objname.attname} }. This mechanism has been implemented in particular for
+TArrays, TMatrix/TVector, Histograms, NTuples and DataTables.
+In addition, when brackets  are used ($\${vname}$), the priority level between interpreter variables
+and application level variable is changed. If {\tt vname} exist at the application level,
+{\tt \${vname} }  is replaced by its value, even if an interpreter variable with the 
+same name has been defined. 
+\begin{itemize}
+\item[\rond] Accessing object attributes
+\begin{verbatim}
+# -------- Example with a Vector
+piapp[1] newvec va 12 
+piapp[2] echo $va
+TVector<d>(12) (nr=12, nc=1) 
+# ------- An undefined attribute, such as ? might be 
+#           used to get list of valid attributes
+piapp[3] echo ${va.?}
+TMatrix.Att: rank size/nelts nrow/nrows ncol/ncols sum sumsq norm min ...
+#  Compound names, in the form  name.att must be inclosed in
+#    braces {name.att}
+piapp[4] echo ${va.size}
+12 
+# -------- Example with an histogram
+piapp[8] newh1d his 0. 20. 40
+piapp[10] echo ${his.?}
+Histo1D: nbin binw mean sigma over under nentries ndata 
+                 xmin xmax vmin vmax imin imax 
+piapp[11] echo ${his.nbin}
+40 
+\end{verbatim}
+
+\item[\rond] Accessing object.Info() \\
+For objects having an DVList Info() object (TArray/TVector/TMatrix , NTuple, DataTable, SwPPFDataTable, it is possible to access DVList members by the corresponding names : \\
+\hspace*{10mm} {\tt \$\{objName.info.varName\} } 
+\item[\rond] Getting DataTable rows \\
+For NTuple and BaseDataTable objects (DataTable, SwPPFDataTable, SwFitsDataTable), it is 
+possible to get a string representation of a given row, by specifying 
+\$\{tableName.row\} followed by the row number (starting from 0) : \\
+\hspace*{10mm} {\tt \$\{tableName.row.num\} } 
+\end{itemize}
+
+ 
+
+\subsection{Control structures}
+
+\begin{itemize}
+\item[\rond] Enumerated loop:
+\begin{verbatim}
+foreach f ( w1 w2 w3 ... )
+  ...
+  echo $f
+end
+\end{verbatim}
+
+Note that spaces before/after  '(' et and  ')' are mandatory.
+An alternative form uses a vector variable name :
+\begin{verbatim}
+foreach v vecname 
+  ...
+  echo $v
+end
+\end{verbatim}
+
+\item[\rond] Integer type loop:
+\begin{verbatim}
+for i  startInt:endInt[:stepInt]
+  ....
+  echo $i 
+end
+\end{verbatim}
+
+\item[\rond] Integer type loop:
+\begin{verbatim}
+for f  startFloat:endFloat[:stepFloat]
+  ....
+  echo $f
+end
+\end{verbatim}
+
+\item[\rond] Loop over lines of a file 
+\begin{verbatim}
+forinfile line FileName
+  ...
+  echo $line
+end
+\end{verbatim}
+
+\item[\rond] The {\tt break} instruction can be used to exit from a loop 
+
+\item[\rond] {\bf if then else} Conditional execution:
+\begin{verbatim}
+if ( test ) then 
+endif
+
+if ( test ) then
+ ....
+else
+ .... 
+endif
+\end{verbatim}
+Note that spaces before/after  '(' et and  ')' are mandatory.
+
+test is in the form {\tt a == b} OR {\tt a != b} OR {\tt a < b}  OR {\tt a > b} 
+OR {\tt a <= b} OR {\tt a >= b}. Comparison operators should be delimited 
+by spaces.
+{\tt ==} et {\tt !=}  make a string comparison, while
+{\tt < , > , <= , >=} compare the values obtained after string to double conversion.
+\end{itemize}
+
+\subsection{Script definition} 
+A script is a sequence of commands. It is very similar to the execution of commands
+from a file ({\bf exec filename}). Once a script has been defined, it can be called specifying
+specifying the script name followed by its arguments.
+\begin{verbatim}
+#  Script definition :
+defscript scriptname  [description ]
+   ....
+endscript 
+
+#  Executing the script
+Cmd> scriptname arg1 arg2 arg3 ....
+\end{verbatim}
+
+The {\tt return} instruction stops the execution and returns from a script, or from a command
+file called through {\bf exec}. \\
+The commands  {\bf listscript } and  {\bf clearscript scriptname} can be used 
+to obtain the list of already defined script, or to clear a script definition.
+
+\subsection{Other built-in commands}
+\begin{itemize}
+\item[\rond] Instruction {\bf echo } to write the line to cout/stdout
+\item[\rond] Instruction {\bf echo2file} to write (append) the line to file ({\tt echo2file filename ....})
+\item[\rond] Instruction {\bf sleep nsec} wait for {\tt nsec}  seconds
+\item[\rond] Instructions {\bf timingon , timingoff , traceon , traceoff } \\
+%
+\item[\rond] {\bf exec filename [arg1 arg2 ... ] } to execute command from 
+the file named {\tt filename}. {\tt .pic} is the default extension for the interpreter 
+command files. 
+\item[\rond]  {\bf help} and {help keyword/commandname }
+\item[\rond]  {\bf listvars , listcommands } to print the list of defined variables and known
+commands
+\item[\rond]  An alias for a command by {\bf alias aliasname 'string ' }. Alias substitution
+occurs for the first word in a command line. {\bf  listalias} prints the list of all 
+defined aliases. 
+\item[\rond] Execution control (piapp/PIACmd extension):
+It is possible to stop the interpreter execution in a loop, a script or 
+a command file by the {\bf stop} command, or using 
+ {\tt <Cntrl C>} in the piapp console (PIConsole) \\
+\end{itemize} 
+
+\subsection {Command execution in separate threads} 
+It is possible to create new threads to execute commands
+( for non built-in interpreter commands). The syntax is similar 
+to unix shell background tasks: an {\&} should be added at the end
+of the command line.  A new thread is then created for the 
+execution of the command, if declared as thread safe \\
+(see {\tt CmdExecutor::IsThreadable() }. 
+\par
+Thread management commands:
+\begin{itemize}
+\item[\rond] {\bf thrlist }Print current list of threads, with the associated command
+the thread identifier (integer ThrId) and its status.
+\item[\rond] {\bf cleanthrlist } Removes all finished threads from the list.
+An automatic cleanup is performed periodically.
+\item[\rond] {\bf cancelthr ThId } / {\bf killthr ThId } Stops/kills the thread with 
+the identifier ThId. Avoid using theses commands as the cleanup does 
+not release some resources associated with 
+the thread (memory, mutex \ldots). 
+\end{itemize}
+
+Executing commands in a separate thread is useful for CPU or data intensive 
+commands. Most {\bf Expr.Plotting} 
+(plot2d, plot2dw, plot2de, plot3d, ntloop, fillvec, fillmtx \ldots) 
+and some of the {\bf pawCmd} (n/plot n/proj) are thread safe. However, due to the 
+current mutex lock management for these Expr.Plotting/pawCmd commands, only one 
+such command can run concurrently with other piapp threads. 
+Some of the commands in the {\bf CxxExecutorCmd} (
+c++exec, c++execfrf, c++create, c++createfrf, c++compile, c++link) are also thread safe.
+The same remark concerning lock management applies to these commands, while 
+CxxExecutorCmd commands can run in parallel with Expr.Plotting commands.
+
+
+%%%%%%%%%%%%%%% Section 7 :  c++ execution
+\newpage
+\section{On the fly C++ execution}
+\label{flycplusplus}
+Piapp operates on the underlying SOPHYA class library objects.
+Obviously, only a small fraction of functionalities in the libraries 
+are directly available through the commands. On the fly C++ compilation
+and execution in piapp provides an easy access to the whole class library. 
+
+The {\bf NamedObjMgr} class handles most of the communication between different
+component of the application, including user c++ code. 
+The NamedObjMgr class implements a singleton scheme, where all instances of the
+class operate on the same data.
+Most operations, in particular directory and object management are thread-safe.
+The most usefull NamedObjMgr methods in user code are:
+\begin{itemize}
+\item Adding an object using its pointer. The object should be created using new. \\
+{\tt \small bool NamedObjMgr::AddObj(AnyDataObj* obj, string \& nom, bool crd=false) } 
+\item Adding an object using its reference. The Object Adapter is used to Clone
+the object. For classes like TArray or Spherical maps, implementing reference sharing,
+the cloned object shares its data with the original object.
+The Cloned object is then added to the list. \\
+{\tt \small bool NamedObjMgr::AddObj(AnyDataObj\& obj, string \& nom, bool crd=false)}
+\item Object display methods : \\
+{\tt \small NamedObjMgr::DisplayObj(string \& nom, string dopt="")  \\
+NamedObjMgr::DisplayImage(string \& nom, \ldots ) \\
+NamedObjMgr::DisplayNT(string \& nom, \ldots )} \\
+\ldots
+\item Access to other parts of the piapp application : \\
+{\tt \small PIStdImgApp* NamedObjMgr::GetImgApp() \\
+PIACmd* PIStdImgApp::CmdInterpreter() }
+\end{itemize}
+
+\subsection{How does it work ?}
+When one the {\bf CxxExecutorCmd} \myppageref{CxxExecutorCmd} commands
+({\tt c++exec} or {\tt c++execfrf}) is invoked, piapp performs the 
+following operations:
+\begin{itemize}
+\item Create a c++ file, and includes the usual libstc++ and SOPHYA header files
+(file named PIATmp\_xxx/cxx\_spiapp.cc)
+\item The user code is put in a c++ function: \\
+{\small \tt  int usercxx( vector<string> \& args ) }
+\item References to all objects present in the current working NamedObjMgr directory
+(default=/home) are declared and initialized. Objects in the current directory can 
+thus be easily accessed through variables bearing the corresponding object name
+in piapp. 
+\item The c++ source file is compiled and linked with SOPHYA libraries, 
+and any additional library, specified through {\tt c++mylibs} \myppageref{cZZmylibs}).
+The compilation and link steps are carried by the SOPHYA class {\b CxxCompilerLinker}.
+\item The resulting shared object is loaded by piapp and the function
+{\tt usercxx()} is called.
+\end{itemize}
+
+To facilitate communication with piapp/NamedObjMgr, two CPP macros are defined:
+\begin{itemize}
+\item[\rond] {\bf KeepObj(VarName) } where VarName is a user declared 
+c++ variable, corresponding to an object inheriting from AnyDataObj.
+When this macro is called, the corresponding object is cloned by the object
+Adapter and added to the list managed by NamedObjMgr, 
+with VarName as the object name. 
+\item[\rond] {\bf DisplayObj(VarName, graphic\_att) } adds the object and
+request its display.  
+\end{itemize}
+
+\subsection{Examples}
+
+\begin{enumerate}
+\item Computation using TimeStamp object. \\[1mm]
+%%
+$\longrightarrow$ File compdate.cc :
+\begin{verbatim}
+  TimeStamp now;     // Current date
+  TimeStamp y2000(2000,1,1,12,0,0.);  // 1 jan 2000, 12:00 
+  cout << " Y2000=" << y2000 << " --> Now: " << now << endl; 
+  cout << " From Y2000 to Now= " << now.ToDays() - y2000.ToDays() << " days" << endl;
+\end{verbatim}
+$\longrightarrow$ piapp commands : \\
+{\tt piapp> c++execfrf compdate.cc} \\
+$\longrightarrow$ The result : \\
+\begin{verbatim}
+PIABaseExecutor: Call usercxx( ... )                                
+ Y2000= 01/01/2000 12:00:0.0 UT  --> Now:  13/12/2007 14:20:50.0 UT 
+ From Y2000 to Now= 2903.1 days                                 
+\end{verbatim}
+%%%%
+\item Working with objects in piapp: \\[1mm]
+\begin{verbatim}
+#  We create three vectors
+newvec va 256 sin(x/5.)
+newvec vb 256 cos(x/18.)*exp(-x/150.)
+newvec vc 256
+#  We call c++exec to make an operation on these vectors
+c++exec vc=va+3.*vb;
+#  Display the resulting vector
+disp vc
+\end{verbatim}
+%%%
+\item Creating and adding new objects \\[1mm]
+$\longrightarrow$ File myf\_fft.h :
+\begin{verbatim}
+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);
+}
+\end{verbatim}
+$\longrightarrow$ File myf\_fft.h :
+\begin{verbatim}
+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); 
+DisplayObj(in, "");
+DisplayObj(out, "red");
+\end{verbatim}
+$\longrightarrow$ piapp commands :
+\begin{verbatim}
+# Remove existing in/out objects
+rm in out
+# Divide then graphic window in two regions
+zone 1 2
+#  Compile and execute the c++ code
+c++execfrf fft.icc myf_fft.h
+listobjs
+\end{verbatim}
+\end{enumerate}
+
+\subsection{Include files, libraries \ldots}
+\begin{itemize}
+\item[\rond] The different steps of c++exec or c++execfrf
+can be performed by the following commands: {\tt c++create , c++createfrf, 
+c++compile, c++link, call}. This is useful when the same code
+has to be executed multiple times.
+\item[\rond] An interactive editing / c++ execution window can be 
+displayed through the menu-bar, \menubar{Tools/CxxExecutorWindow} 
+\item[\rond] The {\tt c++import} \myppageref{cZZimport} 
+activate inclusion of header files for additional SOPHYA modules, 
+such as Samba SkyMap SkyT FitsIOServe \ldots.
+\item[\rond] The inclusion of additional header files and libraries 
+can be specified using the {\tt c++include} \myppageref{cZZinclude}
+and  {\tt c++mylibs} \myppageref{cZZmylibs}.
+\item[\rond] A dialog window for changing various c++ compile and link 
+options can be displayed by through the menu-bar 
+\menubar{Special/CxxExecOption} 
+\end{itemize}
+
+
+%%%%%%%%%%%%%%% Section 8 :  command reference
+\newpage
+\section{piapp command reference}
+\label{piappcmdref}
+This section contains the description of piapp commands. This information
+is available on-line, through the help command, or through a graphic
+window, accessible  by \menubar{File / Help}.
+The help items and command are divided into different sections,
+where related commands are grouped. \\[10mm]
+
+% \include{piahelp}
+\input{piahelp.tex}
+
+%  La partie des appendix
+\appendix
+\newpage
+\section{Interactive control windows}
+\subsection{DrawerTools} \index{DrawerTools}
+\label{secdrwtools}
+The {\bf PIDrawerTools}, shown in the figure \ref{figdrwtools} can be 
+used to change the graphic attributes (color, font, marker, \ldots)
+of the Drawers displayed in 2D displays 
+({\bf PIScDrawWdg} \myppageref{PIScDrawWdg}) or 3D displays 
+({\bf PIDraw3DWdg} \myppageref{PIDraw3DWdg}), as well in image displays
+{\bf PIImage} (\myppageref{PIImage}). The PIDrawerTools can be activated
+either using {\tt Alt<G>} on a PIScDrawWdg,PIDraw3DWdg,PIImage, 
+or through the \menubar{Tools/Show DrawerTools}.
+A given drawer can be selected through the DrawerId selector (+ / - buttons)
+
+\vspace*{5mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=8cm]{piapp_drwtools.eps}
+\caption{PIDrawerTools}
+\label{figdrwtools}
+\end{center}
+\end{figure}
+%%%%
+\subsection{AxesTools} \index{AxesTools}
+\label{secaxestools}
+The {\bf PIAxesTools}, shown in the figure \ref{figaxestools} can be used to 
+control and change the setting of axes on 2D displays 
+({\bf PIScDrawWdg} \myppageref{PIScDrawWdg}).
+The PIAxesTools can be activated
+either using {\tt Alt<A>} on a PIScDrawWdg or through 
+the \menubar{Tools/Show AxesTools}.
+
+\vspace*{5mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=8cm]{piapp_axestools.eps}
+\caption{PIAxesTools}
+\label{figaxestools}
+\end{center}
+\end{figure}
+%%%%%
+\subsection{ImageTools} \index{ImageTools}
+\label{secimagetools}
+The {\bf PIImageTools}, shown in the figure \ref{figimgtools} can be used to 
+manipulate a display of type image. Image display are handled by the 
+{\bf PIImage} (\myppageref{PIImage}). The PIImageTools can be activated
+either using {\tt Alt<O>} on a PIImage, or through the
+\menubar{Tools/Show ImageTools}.
+
+\vspace*{5mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=8cm]{piapp_imgtools.eps}
+\caption{PIImageTools}
+\label{figimgtools}
+\end{center}
+\end{figure}
+
+\subsection{Histo2DTools} \index{Histo2DTools}
+\label{sech2dtools}
+The {\bf PIHisto2DTools}, shown in the figure \ref{figh2dtools} can be 
+used to control and change the display caracteristics of 2D histograms.
+PIHisto2DTools can be activated 
+either using {\tt Alt<O>} on a PIScDrawWdg, when the active 
+drawer is a PIHisto2DDrawer, or through the generic drawer tool 
+PIDrawerTools.
+
+\vspace*{5mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=8cm]{piapp_h2dtools.eps}
+\caption{PIHisto2DTools}
+\label{figh2dtools}
+\end{center}
+\end{figure}
+
+\subsection{ContourTools} \index{ContourTools}
+\label{secconttools}
+The {\bf PIContourTools}, shown in the figure \ref{figconttools} can be 
+used to control and change the caracteristics of contour displays.
+PIContourTools can be activated  
+either using {\tt Alt<O>} on a PIScDrawWdg, when the active 
+drawer is a PIContDrawer, or through the generic drawer tool 
+PIDrawerTools.
+
+\vspace*{10mm}
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[width=11cm]{piapp_conttools.eps}
+\caption{PIContourTools}
+\label{figconttools}
+\end{center}
+\end{figure}
+
+
+
+Both drawing options  (e.g. color, line type, fonts...) and contour 
+determination parameters (e.g. contour number and levels) are controlled 
+by {\bf PIContourTools}. 
+
+\subsubsection{Drawing options}
+The top choices in {\bf PIContourTools} 
+concern the color map (left choice) or color (right choice) of the contours.
+If a color map has been chosen, it is used to give each contour a color 
+(according to its level). If no color map has been chosen, contours may be 
+given a color using the left choice box. 
+
+Contour are by default traced by lines. 
+Alternatively (or in addition) the user may ask to trace them by markers 
+or to put numeric labels (with the contour's level) aside the contour. 
+These options are enabled/disabled by the {\tt LineON}, {\tt MarkerON} and {\tt LabelON} 
+buttons from {\bf PIContourTools}. 
+
+Options may be recovered ({\tt GetAtt}) or set ({\tt SetAtt})
+from/to a drawer. Setting an option which adds to the screen will be immediately visible 
+whereas unsetting it requires a {\tt Refresh} to be visible.  
+
+
+\subsubsection{Contour options}
+The contouring routines in {\tt spiapp} are based on a hack of the {\tt GNUPlot} 
+routines. Contours are determined from a grid of values 
+using an interpolation scheme. Three schemes may be used
+(selected by the left menu) : 
+\begin{enumerate}
+\item Linear interpolation (default), selected by the  {\tt Int. Lin.} option  
+\item A cubic spline algorithm, selected by the  {\tt CubicSpl} option 
+\item A 2d BSpline algorihm, selected by the  {\tt B-Spline} option
+\end{enumerate}
+ 
+Contour levels and number are automatically 
+determined by the program.  They may be specified differently,  
+ through command-line options 
+(see section \ref{piappcmdref} for the help of the contour/ntcont commands)
+or the lower part of the {\bf PIContourTools} window. 
+
+The user may specify one  of the following alternatives : 
+\begin{enumerate}
+\item the number of contour (their level beeing automatically set). 
+To do this, select {\tt LevelNum} in the right menu and enter the contour number 
+in the left box below.
+\item the levels of the contours, through an array of numerical values 
+(e.g. 1,4,6,9,27,4.5 will result in 6 contour lines being drawn, if possible and necessary). 
+To do this, select {\tt LevelDisc} and enter the contour number (left box) 
+and the values (right box) separated by ``{\tt ,}''.
+\item the levels of the contours through an initial (lower) value and an increment.
+For this, select {\tt LevelInc} and enter the contour number (left box)
+and the initial value and increment in the right box, as above.
+\item come back to the default situation, by choosing {\tt LevelAuto}
+\end{enumerate}
+
+Once these options are set, it is necessary the the program recomputes 
+the contour lines. This is commanded by the {\tt SetParm} button. 
+
+
+\newpage
+\addcontentsline{toc}{section}{Index}
+\printindex
+
+\end{document}
Index: /tags/V_Nov2007/SophyaLib/Manual/pmixer.tex
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/pmixer.tex	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/pmixer.tex	(revision 3445)
@@ -0,0 +1,762 @@
+\documentclass[11pt]{article}
+%\documentstyle[11pt,epsfig,url]{article}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[english]{babel}
+\usepackage{url}
+\usepackage{graphicx}
+
+% package a mettre pour faire du pdf
+\usepackage{palatino}
+
+%  Definition pour Docs Sophya
+\usepackage{defsophya}
+
+
+
+\setlength{\parskip}{\smallskipamount} %\documentclass[a4paper,10pt]{article}
+\newenvironment{maliste}%
+{ \begin{list}%
+        {$\ast$}%
+        {\setlength{\labelwidth}{20pt}%
+         \setlength{\leftmargin}{25pt}%
+         \setlength{\itemsep}{\parsep}}}%
+{ \end{list} }
+\newcommand {\ddate}    {April~12,~2000}
+
+\begin{document}
+%  The title page - top of the page with the title of the paper
+\begin{titlepage}
+\titrehp{The SkyMixer \\ (SkyT and PMixer modules)}
+%  Authors list
+\auteurs{
+R. Ansari            &  ansari@lal.in2p3.fr       \\
+S. Henrot-Versille   &  versille@in2p3.fr     
+}
+%  The title page - bottom of the page with the paper number
+\titrebp{2}
+\end{titlepage}
+
+%--------------------------------------- Abstract ---------------------
+\begin{abstract}
+This note gives a description of the SkyMixer which makes
+use of the PMixer and the SkyT
+modules of the Sophya library.
+In a first part, we provide a user-guide on how to use the
+skymixer and the extractRS program, and how to
+fill the corresponding datacards.
+In a second part, we describe more technically
+the different classes
+of the SkyT module. 
+\end{abstract}
+\newpage
+\tableofcontents
+\newpage
+
+
+\section{Skymixer and its datacard}
+The skymixer program adds several sky component maps
+simulated or measured at several frequencies, such as,
+for example, foregrounds (synchrotron radiation, dust, radio-sources...)
+and the microwave background.
+It takes into account the corresponding radiation spectra
+$F_\nu$ (the one of a black-body for microwave background,
+a power law spectrum for synchrotron...),
+and integrates them over a given detector filter frequency-re\-sponse
+$W_\nu$ according to:
+\begin{eqnarray}
+S &=& \sum_{sky\  components} \int_0^\infty F_\nu W_\nu d\nu \ .
+\end{eqnarray}
+The output maps\footnote{$F_\nu$ is in $\hbox{W}/\hbox{m}^2/\hbox{sr}/\hbox{Hz}$
+and $d\nu$ is in $\hbox{GHz}$, while $W_\nu$ is dimensionless.} are in $10^{-9}\hbox{W}/\hbox{m}^2/\hbox{sr}$.
+
+The interaction between the user and the skymixer is done
+using ASCII cards. The keywords one may use are described below.
+
+The way to call the skymixer program is the following one:
+\begin{verbatim}
+ Usage: skymixer paramFile outputfits [outppfname]
+\end{verbatim}
+where paramFile
+is the name of the datacard (described below) and	
+outputfits is the name of the Fits file in which the
+final map will be saved\footnote{PPFName stands for Planck Persistent File (which can be read using piapp or spiapp).}.
+When asking ``skymixer -h'', the previous usage line will appear on the
+screen.
+
+In the datacards, the lines are activated with the $@$ symbol
+at the start of line. All other lines are treated as comments.
+However for clarity, we use  
+$\#$ to mark commented lines.
+
+\subsection{Input maps}
+	One has to define the number of components one wants to add
+	and the characteristics	
+	of the input maps (namely the NSide of HealPix maps):
+	\begin{verbatim}
+	#  SKYMIX  NbComponents  NSide_HealPix
+	@SKYMIX  1 2048
+	\end{verbatim}
+	Note that, within this scheme, only maps with the same NSide can
+	be added.
+
+ 	In the case the user wants to perform a check on the PDMTYPE
+ 	keyword for the different inputs files, he can use the 
+ 	above CHECKPDMTYPE command (note that by default, no check
+ 	is performed).
+	\begin{verbatim}
+ 	@CHECKPDMTYPE
+ 	\end{verbatim}
+
+
+	In the case the files containing the 
+	maps  are not in the
+	working directory, it is possible to precise the path to
+	their location:
+	\begin{verbatim}
+	 #  MAPPATH  PathForFITS   
+	 #  path for input Sky Component FITS files , 
+	 #   and EmissionSpectra files 
+	 MAPPATH /exp/planck/data/
+	\end{verbatim}
+
+	To have access to different printout, one can play with the
+	DEBUGLEVEL and PRINTLEVEL keywords:
+	\begin{verbatim}
+	 #  Define the Debug level
+	 @DEBUGLEVEL  0
+	 #  Define the Print level
+	 @PRINTLEVEL  5
+	\end{verbatim}
+	when set to 0, almost no printout will be given.
+
+\subsection{Detection filter}
+	Then one has to define the detection frequency 
+	filter response (cf. section
+	\ref{specresp}). 
+	For the example, for a gaussian filter (cf. section \ref{gaussFilt}), 
+	one should use:
+	\begin{verbatim}
+	 #  Defining the Detection filter pass - band
+	 #  GAUSSFILTER -> Gaussian filter
+	 #  GAUSSFILTER  Nu0 Sigma_Nu A NuMin NuMax
+	 @GAUSSFILTER 143 12 0.84 50. 300.
+	\end{verbatim}
+	Note that the frequencies have to be given 
+	in $\hbox{GHz}$.
+	In the case of a detection filter defined in a Fits file
+	with 2$\times$n arrays (one for the frequencies and the other for
+	the transmission values), the syntax would be:
+	\begin{verbatim}
+	 #  Defining the Detection filter pass - band
+	 #  FILTERFITSFILE -> Filter (nu, T(nu)) from FITS 
+	 #  FILTERFITSFILE FileName NuMin NuMax
+	 @FILTERFITSFILE filterfile.fits 50. 230.
+	\end{verbatim}
+
+\subsection{Sky components}
+	Once the detector filter has been defined, one has to 
+	define the different sky components one wants to add
+	and
+	their corresponding radiation spectra. The maps are
+	given the MAPFITSFILEi keyword where i corresponds
+	to a given component (synchrotron radiation,
+	dust...): i has to match between the map
+	and the radiation spectrum. One also has to specify
+	a normalization factor corresponding to each component.
+	\begin{verbatim}
+	#  ----        Sky components  ---------
+	#  MAPFITSFILEi FITSfilename Normalisation
+	@MAPFITSFILE4  dust.fits  1.0  
+	\end{verbatim}	 
+	Here the number 4 (i=4) means that we are refering to
+	the fourth sky components. And the normalization factor
+	of the map is set to 1.
+	
+\subsection{Radiation Spectrum}
+The radiation spectra corresponding to the sky component
+maps can either be defined in a fits files, or by the instanciation
+of the RadSpectra class (cf. \ref{radspec}), or they can depend
+on the position in the map. The different cases are treated differently
+as explained below. There is also the possibility of adding
+a dipole component without the use of a map, as described below.
+
+\subsubsection{A Fits file}
+The user can provide the skymixer program with his own 
+Fits file containing 2 $\times$ n arrays (one for the frequencies and
+one for the corresponding flux values), and a frequency range.
+It will be done for example using:
+ \begin{verbatim}
+ #      ---   Emission Spectra definition -----
+ #   SPECTRAFITSFILEi  FITSfilename  NuMin NuMax 
+ @SPECTRAFITSFILE4  pl.fits 100 600  
+\end{verbatim}
+The flux function will returns 0 outside of the 
+$[ \hbox{Numin,Numax} ]$ range.
+
+\subsubsection{The RadSpectra class}
+For well-known spectra, the user does not have to provide
+a Fits file, nor the function, but rather use already coded
+functions, filling the desired parameter values.
+For example, for a black body emission spectrum:
+\begin{verbatim}
+ #   Other possible definition of emission spectra
+ #   BLACKBODYi  temperature
+ #  The blackbody object returns flux in units of 
+ #    watt/m2/sr 
+ #   We thus scale the map (x 1.e17) 
+ @MAPFITSFILE2  cossin.fits  1.e17 
+ @BLACKBODY2 2.726
+\end{verbatim}
+The user has to give the temperature (here 2.726K).
+
+Another example is given below where one wants to use a
+power law spectrum for the radiation:
+\begin{verbatim}
+ #   For power-law spectrum  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.
+\end{verbatim}
+
+\subsubsection{Map position dependence}
+In the case the emission spectrum depends on the position
+in the map (for example for the case of synchrotron radiation),
+one should use the BETAFITSFILE key word as follows:
+\begin{verbatim}
+ #  For an emission spectrum which depends  
+ #  on the position in the map -> synchrotron 
+ #  for instance (nu/nu0)^(-beta(theta,phi))
+ #  408e-3 is the normalisation frequency of the map
+ @MAPFITSFILE1 Sync/Template408MHz.fits 0.2
+ #  BETAFITSFILE BetaMap NormFreq NsideRePixelization
+ @BETAFITSFILE1 Sync/SpectralIndex.fits  408e-3 16 
+\end{verbatim}
+In this case, a second argument is needed for BETAFITSFILEi
+which corresponds to the  normalization frequency value.
+It is possible to perform the computation using a $\beta$ map
+which has a different number of pixels than the sky map. 
+It is also possible to change the NSideHealpix of the
+$\beta$ map for example to low down the resolution for faster
+computation. This is done using the third argument
+(NsideRePixelization, here taken to be 16). For negative values
+of NsideRePixelization, the original $\beta$ map resolution
+is used.
+
+One can refer to Eq.~\ref{pls} for the formula of the
+radiation spectrum built from the $\beta$ map. In this equation, 
+$\nu_0$ is set to 0 and $\delta \nu$ is given the value of
+the normalisation
+frequency of the map. 
+
+\subsubsection{The dipole}	
+The dipole can be treated in a different manner than the other
+sky components,
+using the DIPOLE card, as follows:
+\begin{verbatim}	
+# For a dipole sky map and emission spectrum
+# use: DIPOLE theta phi amplitude delta_temperature
+# theta and phi are in radian, delta_temp in K
+@DIPOLE1 1.2  0.3  1. 3E-3
+\end{verbatim}
+In that case no MAPFITSFILEi is needed: the DIPOLE
+card will create the sky map according to the
+$(\theta,\phi)$ user requirement and integrate
+the dipole radiation spectrum (DerivBlackBody - cf.~Eq.\ref{derivBB})
+over the filter response.
+Note that if the user prefers to give his own map, he
+can do it as well.
+
+\section{Treating point sources}
+The extractRS code builds a full sky map from two data sets:
+\begin{itemize}
+\item{} a list of point sources with emission spectra described at a
+set of discrete frequencies
+\item{} maps of a small patch of the sky with emission spectrum described
+at a set of discrete frequencies.
+\end{itemize}
+
+It treats the  case when one has made a simulation of a patch of the sky
+producing a set of maps corresponding to the sky emission and the 
+point sources emission at 
+discrete frequencies,
+and wants to build a random map on the basis of these
+two informations.
+The map produced by 
+extractRS can then be given to the skymixer program to be
+added to other sky components. 
+
+As for skymixer, the user interacts with extractRS through
+the use of a datacard (described below).  The way to call
+it is the following one:
+\begin{verbatim}
+   Usage: extractRS parameterFile outputfits  [outppf]
+\end{verbatim}
+where parameterFile is the datacard, and outputfits
+corresponds to the Fits file in which the final map will be
+saved.
+
+An example of the datacard is shown below:
+\begin{verbatim}
+#  EXT_RS  NbComponents  NSide_HealPix
+@EXT_RS  1 256
+
+#  RD_EXT_PATH  PathForFITS   
+#  path for input Sky Component FITS files , 
+#  from which the RadSpec files will be read
+@RS_EXT_PATH /exp/planck/CartesRT/
+
+#  Sky ``map'' for different frequencies 
+#  From which the radspectra will be read
+#  RADSPECMAPi FITSfilename 
+@RADSPECMAP1 	eran102_441_00015000mhz.fits
+
+# Source point ``map'' for different freq
+# From which the radspectra will be read
+#  SOURCEPTMAPi FITSfilename freq(MHz)
+@SOURCEPTMAP1 	eran102_441_00015000mhz.s_rare
+
+# Filter definition now !!
+# define the detector (only one)
+@GAUSSFILTER 143 12 0.84 50. 300.
+\end{verbatim}
+We first indicate in the datacard (after the EXT$\_$RS keyword):
+\begin{maliste}
+\item the number of frequency components we are going to
+process: in the example the code will only process
+one frequency component. 
+\item and the NSideHealpix corresponding to the healpix output maps
+\end{maliste}
+
+Then comes the path (if any) to the maps, followed by the
+name of the fits files containing the ``maps''
+(these maps are not Healpix spheres but matrices). The keyword for
+the frequency
+components is RADSPECMAPi (with i being the sky component number)
+and for the sources: SOURCEPTMAPi. 
+
+The names of the fits
+file should contain the frequency of the map in units of  $\hbox{MHz}$.
+For example: 
+\begin{verbatim}
+@RADSPECMAP1 	eran102_441_00015000mhz.fits
+\end{verbatim}
+corresponds to a frequency of 15000 $\hbox{Mhz}$.
+The sky maps definition is followed by the point source
+fits file, with the keyword SOURCEPTMAPi. 
+
+Then comes the definition of the filter (here it is a
+gaussian filter at 143 $\hbox{GHz}$).
+
+\section{Simulating components and adding them}
+For quick simulations, one can use two codes to generate maps,
+detector filter responses and radiation spectra:
+\begin{itemize}
+\item{} {{\bf tgsky:}}\\
+	this code generates a sky map in a Fits file.	
+\item{} {{\bf tgrsr:}}\\
+	this code writes in a Fits file the
+	definition of a RadSpectraVec or of a SpecRespVec	
+	(i.e. one frequency vector and the corresponding
+	transmission or flux vector.)
+\end{itemize}
+\noindent The way to use these two functions is the following one:
+\begin{itemize}
+\item{} {{\bf tgsky:}}
+\begin{verbatim}
+  Usage: tgsky NSide TypSky Params FitsFile [PPF] 
+\end{verbatim}
+where PPF stands for Planck Persistent File (which can be read using piapp or spiapp),
+NSide is the Healpix map parameter and TypSky and Params are described here:
+\begin{maliste}
+\item  if TypSky = 0, the map will be filled with a gaussian noise,
+	the parameters (Params) are therefore the mean value and the sigma
+	of the gaussian.
+\item  if TypSky = 1, the map will be filled with a $1/\hbox{f}$ noise using
+	the OOFNoise generator. The parameters to give are the
+	sigma of the noise and a constant offset.
+\item  if TypSky = 2, the map is filled with an analytical function of the
+	form:	
+	\begin{eqnarray}
+	f &=& K \cos(a\theta)\sin(b\phi)+m
+	\end{eqnarray}
+	and the corresponding parameters are (in this order): K,a,b,m.
+\item  if TypSky = 3, the map is filled with a dipole,
+	the corresponding parameters are (in this order): theta,phi
+	corresponding to the dipole orientation
+\end{maliste}
+\item{}{{\bf tgrsr:}}
+\begin{verbatim}
+ Usage: tgrsr choice Params NPoints FitsFileName 
+                      [ImageR4FITSName] [ppfname]
+\end{verbatim}
+where choice, and Params are described below, and NPoints corresponds
+to the number of elements in the generated vectors.
+\begin{maliste}
+\item if choice = 0, the code will generate a gaussian spectrum in a Fits file.
+	Params are therefore the parameters of the gaussian plus the
+	minimum and the maximum frequency.
+ 	In the order:  A,Nu0,DNu,MinFreq,MaxFreq.
+\item if choice = 1, the code will generate a power law spectrum in a 
+        Fits file. Params are therefore, in the order:\\
+        A, Nu0, dnu, b, MinFreq, MaxFreq
+\end{maliste}
+\end{itemize}
+
+
+
+\section{The SkyT module}
+The SkyT module is composed of two types of classes:
+\begin{itemize}
+\item{} one which corresponds to an emission spectrum of
+radiation, which is called RadSpectra
+\item{} one which corresponds to the spectral response
+of a given detector (i.e. corresponding to a detector
+filter in a given frequency domain), which is called
+SpectralResponse.
+\end{itemize}
+In the coming sub-sections, we summarize the different functions
+of these two classes and the corresponding subclasses.
+For more informations about the classes, and the functions
+the user may want to use (to have access or reset some
+parameter values for example), we refer the reader to 
+\cite{DOX-Sophya}.
+
+All frequencies are expressed in $\hbox{GHz}$, which enables
+us to represent wavelengths from the radio up to the optical 
+range at a reasonnable accuracy using double values.
+
+\subsection{ConvTools}
+The ConvTools class is a very simple class where are
+defined some needed constants for the computation of the
+spectral emission function, such as:
+\begin{verbatim}
+// 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::c=299792458.; 
+\end{verbatim}
+
+\subsection{SpectralResponse}
+\label{specresp}
+SpectralResponse 
+is an abstract class representing 
+a detector frequency filter
+response, $W_\nu$ as a function of the frequency.
+Several subclasses
+have been written within the SkyT module which are listed
+in the following subsections.
+The constructor takes as arguments the
+minimum and maximum values of the frequency range on
+which the detector response is defined
+
+The main public member function is the  
+transmission function which has to be implemented
+in the subclasses and is purely virtual at this stage:
+\begin{verbatim}
+virtual double transmission(double nu) const =0 ; 
+\end{verbatim}
+The () operator has also been redefined so that
+one can access the transmission value of the detector's
+filter directly writting for example myFilter(myfrequency).
+
+Other member functions  are implemented at this level, but still
+are virtual functions that can be re-implemented in the
+sub-classes: they respectively returns the minimum, the
+maximum, the mean and the peak values of the frequency
+range (where the peak is defined as the maximum of the transmission
+spectrum), but also the value of the transmission at the so-called
+peak. One can also change the range in frequency of the filter
+using the {{\it setMinMaxFreq}} function.
+%\begin{verbatim}
+% virtual double minFreq() const; 
+% virtual double maxFreq() const; 
+% virtual double meanFreq() const;
+% virtual double peakFreq() const;
+% virtual double peakTransmission() const;
+% virtual void	setMinMaxFreq(double numin, double numax);
+%\end{verbatim}
+For all the sub-classes, $\nu$ is given in units of $GHz$ and
+$W_\nu$ is dimensionless.
+
+Since the user may want to integrate the detector response
+within a given frequency range:
+\begin{eqnarray}
+\int_{\nu_{min}}^{\nu_{max}} F_\nu \delta \nu\ \ \ ,
+\end{eqnarray}
+the following functions are
+available:
+\begin{verbatim}
+double IntegratedSpect(double numin,double numax) 
+double logIntegratedSpect(double numin,double numax)
+double IntegratedSpect() 
+double logIntegratedSpect() 
+\end{verbatim}
+When no frequency range is defined the default values are used.
+As, for some spectra, the calculation is more accurate when
+one performs the numerical integration using a logarithmic
+frequency scale.
+
+The following subsections are devoted to the description of the
+SpectralResponse subclasses which are already implemented.
+\subsubsection{SquareFilter}
+\begin{center}
+\dclsbb{SpectralResponse}{SquareFilter}
+\end{center}
+The square filter is the simplest filter one can think of:
+it is defined by a minimum and a maximum frequencies. 
+\begin{verbatim}
+SquareFilter (double numin, double numax)
+\end{verbatim}
+The transmission function returns 1 when the tested frequency
+is within this range and 0 outside.
+For the peakFrequency and peakTransmission functions, the square
+filter returns respectively the frequency and the transmission
+corresponding to the middle of the frequency range.
+To use the SquareFilter class, one should include the squarefilt.h file.
+
+\subsubsection{TriangleFilter}
+\begin{center}\dclsbb{SpectralResponse}{TriangleFilter}\end{center}
+For the triangle filter, as it was the case for the
+square filter, its name itself is sufficient to define it:
+the corresponding constructor is:
+\begin{verbatim}
+ TriangleFilter (double numin, double numax,
+		double nupeak, double valueatpeak); 
+\end{verbatim}
+To use the TriangleFilter class, one should include the trianglefilt.h file.
+
+\subsubsection{GaussianFilter}
+\label{gaussFilt}
+\begin{center}\dclsbb{SpectralResponse}{GaussianFilter}\end{center}
+The constructor of the gaussian filter defines the parameters
+of the corresponding gaussian:
+\begin{verbatim}
+ GaussianFilter (double nu0, double s, double A=1., 
+           double numin=0., double numax= 9.e49); 
+\end{verbatim}
+where the transmission function returns:
+\begin{eqnarray}
+\label{gaussian}
+W_\nu&=& A  e^{-{({\nu-\nu_0/ s})^2}};
+\end{eqnarray}
+%There are functions to reset or
+%get back the value of the parameters (there are
+%described in \cite{}. 
+%using the 
+%following functions:
+%\begin{verbatim}
+%  double giveNorm()
+%  double giveNu0()
+%  double giveDNu()
+%\end{verbatim}
+%or reset them with:
+%\begin{verbatim}
+%  virtual void setParams(double nu0, double s, double a=1.);
+%\end{verbatim}
+To use the GaussianFilter class, one should include the gaussfilt.h file.
+
+\subsubsection{SpecRespVec}
+\begin{center}\dclsbb{SpectralResponse}{SpecRespVec}\end{center}
+One may also want to give the filter of a detector as a 
+set of frequencies and the corresponding filter transmission values,
+when there is no analytic expression to describe it.
+In that case he/she should use the SpecRespVec class:
+\begin{verbatim}
+  SpecRespVec(Vector const & nu, Vector const & fdenu, 
+              double numin, double numax)
+\end{verbatim}
+The first vector (called nu) is the frequency vector and the
+second one (called fdenu) is the corresponding transmission:
+note that the two vectors should have the same length, otherwise
+an exception will be launched ({\it SzMismatchError}).
+
+%One can access the different vectors with the use
+%of appropriate functions (cf. \cite{}).
+%Several functions are defined to access these vectors, either
+%as a whole or element per element:
+%\begin{verbatim}
+%  Vector&  getNuVec()  { return _vecOfNu; } ;
+%  Vector& getTNuVec()  { return _vecOfFDeNu; }
+%  double getNuVec(int i) const { return _vecOfNu(i); }
+%  double getTNuVec(int i) const { return _vecOfFDeNu(i); }
+%  int NbElts() const { return _size;}
+%\end{verbatim}
+To use the SpecRespVec class, one should include the specrespvector.h file.
+
+\subsection{RadSpectra}
+\label{radspec}
+The name RadSpectra stands for Radiation Spectrum.
+The aims of RadSpectra is to define a base class
+for the radiation emission spectra. It is therefore
+abstract and contains one virtual member function 
+which has to be implemented in the subclasses:
+\begin{verbatim}
+    virtual double flux(double nu) const =0;
+\end{verbatim}
+This function returns the value of the
+flux (the spectral energy distribution), $F_\nu$,
+as a function of the frequency $\nu$,
+As in the SpectralResponse class,
+the () operator has been redefined at this level, so that
+the user can access the flux value, either by calling the
+function or directly by using this operator.
+
+The constructor takes as an argument the minimum
+and the maximum frequency of the spectrum, if any.
+In the case the user does not want to specify these
+values, there are set respectively to 0. and $9.10^{49}$
+by default.
+For all the sub-classes, $\nu$ is given in units of $\hbox{GHz}$ and
+the flux is returned in units of $\hbox{W}/\hbox{m}^2/\hbox{sr}/\hbox{Hz}$.
+
+%We also defined functions to access the minimum, maximum,
+%peak frequency values, or to change them 
+%(see \cite{}). 
+%And the user may change the
+%values of the frequency range using the function:
+%\begin{verbatim}
+%virtual void	 setMinMaxFreq(double numin, double numax);
+%\end{verbatim}
+One may also want to  integrate the emission
+spectrum: this can be done in a given frequency
+range, or in the full range of definition of the spectrum,
+or  taking into account the
+SpectralResponse (in frequency) of a detector (see section \ref{specresp}):
+\begin{verbatim}
+  virtual double integratedFlux
+            (double numin, double numax)
+  virtual double integratedFlux()
+  virtual double filteredIntegratedFlux 
+            (SpectralResponse const & filter, 
+             double numin, double numax)
+  virtual double filteredIntegratedFlux
+            (SpectralResponse const & filter)
+  virtual double logIntegratedFlux
+            (double numin, double numax) 
+  virtual double logIntegratedFlux() 
+  virtual double filteredLogIntFlux
+            (SpectralResponse const & filter, 
+             double numin, double numax)
+  virtual double filteredLogIntFlux
+            (SpectralResponse const & filter);
+\end{verbatim}
+
+Several sub-classes of RadSpectra have been defined, which are listed
+below with their corresponding characteristics.
+\subsubsection{BlackBody}
+\begin{center}\dclsbb{RadSpectra}{BlackBody}\end{center}
+This class corresponds to the emission spectrum of a 
+blackbody radiation: by default the temperature of the 
+blackbody is 2.728K (as defined in convtools.cc), but when
+the object is instanciated the temperature 
+can be given any other value.
+\begin{verbatim}
+  BlackBody (double temp = ConvTools::tcmb);
+\end{verbatim}
+The flux function is the well known formula: 
+\begin{eqnarray}
+F_\nu &=& {2 h_{pl} (1.10^9*\nu)^3 / c^2 (e^{{h_{pl}(1.10^9*\nu) / kT}} -1)}
+\end{eqnarray}
+
+%In addition to the flux member function, we can get or set the
+%temperature of the blackbody spectrum (see \cite{}).
+%\begin{verbatim}
+%  double getTemperature() 
+%  void setTemperature(double newtemp)
+%\end{verbatim}
+To use the BlackBody class, one should include the blackbody.h file.
+
+
+\subsubsection{DerivBlackBody}
+\begin{center}\dclsbb{RadSpectra}{DerivBlackBody}\end{center}
+This class corresponds to the emission spectrum of a 
+the dipole (since its emission spectrum is the derivation
+of a blackbody spectrum wrt the temperature): 
+by default the temperature of the 
+DerivBlackBody is set 2.728K (as defined in convtools.cc), but when
+the object is instanciated the temperature 
+can be given any other value.
+\begin{verbatim}
+  DerivBlackBody (double temp = ConvTools::tcmb);
+\end{verbatim}
+The flux function is simply given by: 
+\begin{eqnarray}
+\label{derivBB}
+F_\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}}
+\end{eqnarray}
+
+%In addition to the flux member function, we can get or set the
+%temperature as for the spectrum (see \cite{}).:
+%\begin{verbatim}
+%  double getTemperature() 
+%  void setTemperature(double newtemp)
+%\end{verbatim}
+To use the DerivBlackBody class, one should include the derivblackbody.h file.
+
+\subsubsection{PowerLawSpectra}
+\begin{center}\dclsbb{RadSpectra}{DerivBlackBody}\end{center}
+This class corresponds to a power law spectrum, the
+flux function being defined as follows:
+\begin{eqnarray}
+\label{pls}
+I_\nu &=& A ({\nu-\nu_0\over \delta\nu})^\beta 
+\end{eqnarray}
+The constructor takes as arguments the parameters of this
+function and therefore reads:
+\begin{verbatim}
+PowerLawSpectra(double a, double beta, double nu0, 
+	double dnu, double numin=0., double numax=9.e49);
+\end{verbatim}
+%The intrinsic member functions of this class 
+%helps getting back these parameters, once an object of this class
+%has been
+%instanciated:
+%\begin{verbatim}
+%  double giveNorm()
+%  double giveNu0()
+%  double giveDNu()
+%  double giveExp() 
+%\end{verbatim}
+%One can also set them using:
+%\begin{verbatim}
+%  void setNorm(double myvalue)
+%  void setNu0(double myvalue)
+%  void setDNu(double myvalue)
+%  void setExp(double myvalue) 
+%\end{verbatim}
+%
+To use the PowerLawSpectra class, one should include the nupower.h file.
+
+
+\subsubsection{RadSpectraVec}
+\begin{center}\dclsbb{RadSpectra}{RadSpectraVec}\end{center}
+As in the case of the SpectralResponse class, one may define the radiation
+spectrum with two vectors: one for the frequencies and the second for the
+values of the flux function. In that case, the class to use is RadSpectraVec
+and the corresponding constructor is:
+\begin{verbatim}
+ RadSpectraVec (Vector const nu, Vector const fdenu, 
+		double numin=0., double numax=9.e49);
+\end{verbatim}
+%The following functions helps getting back the input vectors, or their
+%number of elements:
+%\begin{verbatim}
+%  Vector&  getNuVec()
+%  Vector& getTNuVec()
+%  double getNuVec(int i)
+%  double getTNuVec(int i)
+%  int NbElts() 
+%\end{verbatim}
+To use the RadSpectraVec class, one should include the radspecvector.h file.
+
+\begin{thebibliography}{99}
+\bibitem{DOX-Sophya}
+\url{http://www.sophya.org/}
+\end{thebibliography}
+\end{document}
Index: /tags/V_Nov2007/SophyaLib/Manual/sophya.tex
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/sophya.tex	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/sophya.tex	(revision 3445)
@@ -0,0 +1,2741 @@
+\documentclass[twoside,10pt]{article}
+%  Package standard : Utilisation de caracteres accentues, mode francais et graphique
+\usepackage{url}
+\usepackage[latin1]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[english]{babel}
+\usepackage{graphicx}
+% package a mettre pour faire du pdf
+\usepackage{palatino}
+
+%  Extension de symboles mathematiques
+\usepackage{amssymb}
+
+%  Definition pour Docs Sophya
+\usepackage{defsophya}
+
+%  Constitution d'index
+\usepackage{makeidx}
+    
+\usepackage[ps2pdf,bookmarks,bookmarksnumbered,%
+              urlcolor=blue,citecolor=blue,linkcolor=blue,%
+                pagecolor=blue,%hyperindex,%
+                 colorlinks=true,hyperfigures=true,hyperindex=true
+           ]{hyperref}
+
+\makeindex     %  Constitution d'index
+
+\newcommand{\rond}{$\bullet \ $}
+\newcommand{\etoile}{$\star \ $}
+\newcommand{\cercle}{$\circ \ $}
+\newcommand{\carre}{$\Box \ $}
+
+
+\begin{document}
+
+\begin{titlepage}
+%  The title page - top of the page with the title of the paper
+\titrehp{Sophya  \\ An overview }
+%  Authors list
+\auteurs{
+R. Ansari            &  ansari@lal.in2p3.fr       \\
+E. Aubourg           &  aubourg@hep.saclay.cea.fr \\
+G. Le Meur           &  lemeur@lal.in2p3.fr       \\
+C. Magneville        &  cmv@hep.saclay.cea.fr     \\
+}
+% \auteursall
+%  The title page - bottom of the page with the paper number
+\vspace{1cm}
+\begin{center}
+{\bf \Large Sophya Version: 2.1 (V\_Nov2007) }
+\end{center}
+\titrebp{1}
+\end{titlepage}
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+
+{\bf SOPHYA} ({\bf SO}ftware for {\bf PHY}sics {\bf A}nalysis) 
+is a collection of C++ classes designed for numerical and
+physics analysis software development. Our goal is to provide
+easy to use, yet powerful classes which can be used by scientists.
+Although some of the SOPHYA modules (SkyMap, Samba, SkyT) 
+have been designed with the specific goal of CMB data analysis, most
+modules presented here have a much broader scope and can be
+used in scientific data analysis and modeling/simulation. 
+Whenever possible, we use existing numerical packages and libraries, 
+encapsulating them in classes in order to facilitate their usage.
+\par
+Our main requirements in designing SOPHYA classes can be summarized as
+follow:
+\begin{itemize}
+\item[\rond] Provide a comprehensive set of data containers, such as arrays and tables 
+(tuple) covering the most common needs in scientific simulation and data analysis
+softwares.
+\item[\rond] Take advantage of the C++ language and define methods and operators 
+for most basic operation, such as arithmetic operations, in a rather intuitive way, while
+maintaining performances comparable to low level coding in other languages 
+(C, Fortran, F90 \ldots) 
+\item[\rond] Simplify memory management for programmers using the class library.
+This has been a strong requirement for most SOPHYA classes. Automatic reference 
+sharing and memory management is implemented in SOPHYA classes intended 
+for large size objects. We recommend to allocate SOPHYA objects on the stack,
+including when objects are returned by methods or functions. 
+See section \ref{memgt} for more information.
+\item[\rond] Archiving, importing (reading) and exporting (writing) data in a 
+efficient and consistent way is a major concern in many scientific software 
+and projects. SOPHYA provide a native data I/O or persistence system, 
+(PPF, \ref{ppfdesc}) as well as import/export  services for ASCII and FITS formats.
+\end{itemize}
+
+% \vspace*{2mm}
+This documents
+presents only a brief overview of the class library, 
+mainly from the user's point of view. A more complete description
+can be found in the reference manual, available from the SOPHYA
+web site: % {\bf http://www.sophya.org}.
+\href{http://www.sophya.org}{http://www.sophya.org}. 
+%%%
+%%%
+\subsection{Acknowlegments}
+Many people have contributed to the development SOPHYA and/or the PI library 
+and (s)piapp interactive analysis tool.
+we are grateful to the following people:
+
+\begin{tabular}{lcl}
+Reza Ansari & \hspace{5mm} & (LAL-Univ.Paris Sud, Orsay) \\
+Eric Aubourg & & (DAPNIA-CEA/APC, Saclay) \\
+Sophie Henrot-Versille & & (LAL-IN2P3/CNRS, Orsay) \\
+Alex Kim & & (LBL, Berkeley) \\
+Guy Le Meur & & (LAL-IN2P3/CNRS, Orsay) \\
+Eric Lesquoy & & (DAPNIA-CEA, Saclay) \\
+Christophe Magneville & & (DAPNIA-CEA, Saclay) \\
+Bruno Mansoux & & (LAL-IN2P3/CNRS, Orsay) \\
+Olivier Perdereau & & (LAL-IN2P3/CNRS, Orsay) \\
+Nicolas Regnault & & (LPNHE-IN2P3/CNRS, Paris) \\
+Benoit Revenu & & (APC/Univ.Paris 7, Paris) \\
+Francois Touze & & (LAL-IN2P3/CNRS, Orsay) \\
+\end{tabular}
+
+We thank also the persons who have helped us by useful suggestions, among others : \\
+S. Bargot, S. Plasczczynski, C. Renault and D. Yvon.
+
+\subsection{SOPHYA modules}
+\label{sopmodules}
+The source directory tree 
+\footnote{ CVS: cvsserver.lal.in2p3.fr:/exp/eros/CVSSophya} 
+is organised into a number of modules. 
+
+\begin{itemize}
+\item[] {\bf BuildMgr/}  Scripts for code management, 
+makefile generation and software installation
+\item[] {\bf BaseTools/} General architecture support classes such 
+as {\tt PPersist, NDataBlock<T>}, and few utility classes 
+such as the dynamic variable list manager ({\tt DVList}) as well
+as the basic set of exception classes used in SOPHYA.
+\item[] {\bf TArray/} template numerical arrays, vectors and matrices \\
+({\tt TArray<T> TMatrix<T> TVector<T> } \ldots) 
+\item[] {\bf NTools/} Some standard numerical analysis tools 
+(linear, and non linear parameter fitting, FFT, \ldots)
+\item[] {\bf HiStats/}  Histogram-ming and data set handling classes (tuples) \\
+({\tt Histo Histo2D NTuple DataTable} \ldots)
+\item[] {\bf SkyMap/} Local and full sky maps, and some 3D geometry 
+handling utility classes. \\
+({\tt PixelMap<T>, LocalMap<T>, SphericalMap<T>, \ldots})
+\item[] {\bf SUtils/} This module contains few utility classes, such as the
+{\tt DataCard} class, as well as string manipulation functions in C and C++.
+\item[] {\bf SysTools/} This module contains classes implementing 
+an interface to various OS specific services, such 
+threads and dynamic link/shared library handling.
+
+\end{itemize}
+
+The modules listed below are more tightly related to the 
+CMB (Cosmic Microwave Background) data analysis problem:
+\begin{itemize}
+\item[] {\bf SkyT/} 
+classes for spectral emission and detector frequency response modelling \\
+({\tt SpectralResponse, RadSpectra, BlackBody} \ldots)
+\item[] {\bf Samba/} Spherical harmonic analysis, noise generators \ldots 
+\end{itemize}
+
+The following modules contain the interface classes with 
+external libraries:
+\begin{itemize}
+\item[] {\bf FitsIOServer/} Classes for handling file input-output 
+in FITS format using the cfitsio library. 
+FITS is maintained by NASA and SAO and is available from: \\
+\href{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
+{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
+\item[] {\bf LinAlg/} Interface with Lapack linear algebra package.
+Lapack is a linear algebra package and can be downloaded from: \\ 
+\href{http://www.netlib.org/lapack/}{http://www.netlib.org/lapack/}
+\item[] {\bf IFFTW/} Interface with FFTW package (libfftw.a).
+FFTW is a package for performing Fourier transforms, written in C.
+Documentation and source code can be found at: \\
+\href{http://www.fftw.org/}{http://www.fftw.org/}
+\item[] {\bf XAstroPack/} Interface to some common astronomical 
+computation libraries. Presently, this module uses an external library
+extracted from the {\bf Xephem } source code. The corresponding source 
+code is also available from SOPHYA cvs repository, module {\bf XephemAstroLib}. 
+Information on Xephem can be found at : \\
+\href{http://www.clearskyinstitute.com/xephem/}{http://www.clearskyinstitute.com/xephem/}
+
+\end{itemize}
+
+The following modules contain each a set of related programs using the 
+SOPHYA library.
+\begin{itemize}
+\item[] {\bf Tests/} Simple test programs. Many of these test programs can be also used 
+as examples for using SOPHYA. 
+\item[] {\bf PrgUtil/} Various utility programs (runcxx, scanppf, scanfits, \ldots)
+\item[] {\bf PrgMap/} Programs performing operations on skymaps: projections, 
+power spectrum in harmonic space, \ldots
+\end{itemize}
+
+As a companion to SOPHYA, the {\bf (s)piapp} interactive data analysis
+program is built on top of SOPHYA and the {\bf PI} GUI class library 
+and application framework. The {\bf PI} ({\bf P}eida {\bf Interactive})
+development started in 1995, in the EROS \footnote{EROS: {\bf E}xp\'erience 
+de {\bf R}echerche d'{\bf O}bjets {\bf S}ombres - http://eros.in2p3.fr}
+microlensing search collaboration, with PEIDA++ \footnote {PEIDA++: 
+The EROS data analysis class library - 
+http://www.lal.in2p3.fr/recherche/eros/PeidaDoc/}.
+The {\bf PI} documentation and the {\bf piapp} user's guide are available
+from \href{http://www.sophya.org}{http://www.sophya.org}.
+%\href{http://www.sophya.org}{http://www.sophya.org}. 
+The {\bf PI} is organized as the following modules:
+\begin{itemize}
+\item[] {\bf PI/} Portable GUI class library and application development 
+framework kernel.
+\item[] {\bf PIGcont/} Contour-plot drawing classes.
+\item[] {\bf PIext/} Specific drawers and adapters for SOPHYA objects,
+and the {\bf piapp} interactive data analysis framework.
+\item[] {\bf ProgPI/} interactive analysis tool main program and pre-loaded 
+modules.
+\end{itemize}   
+
+Modules containing examples and demo programs and scripts:
+\begin{itemize}
+\item[] {\bf Examples/} Sample SOPHYA codes and example programs and
+makefiles.
+\item[] {\bf DemoPIApp/} Sample scripts and programs for (s)piapp 
+interactive analysis tools.
+\end{itemize}   
+
+The following modules contains additional programs or libraries, based on SOPHYA :
+\begin{itemize}
+\item[] {\bf AnaLC} contains program files extracted from the EROS/PEIDA software
+and adapted to be compiled with SOPHYA. It can be used in particular to read and analyse
+EROS light curve data files. 
+\item[] {\bf LUC} {\bf L}ittle {\bf U}niverse {\bf C}alculator is a module containing classes to 
+perform basic computation related to the universe geometry (FRW metric).
+\item[] {\bf PMixer/} skymixer and related programs
+\end{itemize}
+
+\newpage 
+
+\section{Using Sophya}
+The organisation of SOPHYA directories and some of the associated 
+utility programs are described in this section.
+Basic usage of Sophya classes is described in the following sections.
+Complete Sophya documentation can be found at our web site
+{\bf http://www.sophya.org}. 
+
+\subsection{Directories, environment variables, configuration files}
+\label{directories}
+The environment variable {\bf SOPHYABASE}  is used 
+to define the path where the Sophya libraries and binaries are installed.
+\begin{itemize}
+\item \$SOPHYABASE/include : Include (.h) files
+\item \$SOPHYABASE/lib : Path for the archive libraries (.a)
+\item \$SOPHYABASE/slb: Shared library path (.so or .dylib on Darwin/MacOS)
+\item \$SOPHYABASE/exe : Path for binary program files
+\end{itemize}
+
+The directory { \tt \$SOPHYABASE/include/SophyaConfInfo/ } contains files
+describing the installed configuration of SOPHYA software.
+
+The file { \tt \$SOPHYABASE/include/machdefs.h } contains definitions
+(flags, typedef) used in SOPHYA, while some more specific flags,
+are found in  { \tt \$SOPHYABASE/include/sspvflags.h }  
+
+The file { \tt \$SOPHYABASE/include/sophyamake.inc } contains the 
+compilation commands and flags used for building the software. 
+Users can use most of compilation and link commands defined in this file:
+ {\tt \$CCOMPILE , \$CXXCOMPILE . \$CXXLINK \ldots}. 
+ (See module Example).
+
+The configure script (BuildMgr/configure) creates the directory tree and the
+above files. It also copy (or create symbolic link) for all SOPHYA include 
+files as well as symbolic links for external libraries 
+include files path in {\tt \$SOPHYABASE/include} (FitsIO, FFTW, XAstro \ldots). 
+
+Object files for each module are grouped in a static archive library 
+by the build procedure (libXXX.a for module
+XXX, with XXX = BaseTools, TArray, HiStats,  FitsIOServer  \ldots).
+
+When shared libraries are build, all stand alone SOPHYA modules
+are grouped in  {\tt libsophya.so},  {\tt libextsophya.so} contains 
+the interface modules with external libraries {\bf (FitsIOServer, LinAlg \ldots)},
+while {\bf PI, PIext, PIGcont} modules  are grouped in  {\tt libPI.so}.
+Alternatively, it is possible to group all modules in a single shared 
+library {\tt libAsophyaextPI.so} (See \ref{build})
+
+In order to use the shared libraries, the {\bf LD\_LIBRARY\_PATH} variable
+should contain the Sophya shared library path 
+({\tt \$SOPHYABASE/slb}). 
+On Silicon Graphics machines with IRIX64 operating system, 
+the default SOPHYA configuration correspond to the 64 bit architecture. 
+The environment variable { \bf LD\_LIBRARY64\_PATH } replace in
+this case the usual {\bf LD\_LIBRARY\_PATH} variable.
+On IBM machines with AIX, the {\bf LIBPATH} environment variables 
+contains the shared libraries search path.
+
+When using the dynamic load services in SOPHYA ({\tt PDynLinkMgr}
+class), in runcxx or (s)piapp applications for example, the shared 
+library search path must contain the current working directory (
+dot . in unix).
+
+\subsection{Copy constructor and assignment operator}
+\label{memgt}
+In C++, objects can be copied by assignment or by initialisation.
+Copying by initialisation corresponds to creating an object and
+initialising its value through the copy constructor.
+The copy constructor has its first argument as a reference, or
+const reference to the object's class type. It can have  
+more arguments, if default values are provided.
+Copying by assignment applies to an existing object and
+is performed through the assignment operator (=). 
+The copy constructor implements this for identical type objects:
+\begin{verbatim}
+class MyObject {
+public:
+  MyObject();      // Default constructor
+  MyObject(MyObject const & a);  // Copy constructor
+  MyObject & operator = (MyObject const & a) // Assignment operator
+}
+\end{verbatim}
+The copy constructors play an important role, as they are 
+called when class objects are passed by value, 
+returned by value, or thrown as an exception. 
+\begin{verbatim}
+// A function declaration with an argument of type MyObject,
+// passed by value, and returning a MyObject
+MyObject f(MyObject x) 
+{
+  MyObject r;
+  ...
+  return(r);  // Copy constructor is called here
+}
+// Calling the function :
+MyObject a;
+f(a);        // Copy constructor called for a
+\end{verbatim}
+It should be noted that the C++ syntax is ambiguous for the 
+assignment operator. {\tt MyObject x; x=y; } and 
+{\tt MyObject x=y;} have different meaning.
+\begin{verbatim}
+MyObject a;        // default constructor call
+MyObject b(a);     // copy constructor call
+MyObject bb = a;   // identical to bb(a) : copy constructor call
+MyObject c;        // default constructor call
+c = a;             // assignment operator call
+\end{verbatim}
+
+As a general rule in SOPHYA, objects which implements 
+reference sharing on their data members have a copy constructor
+which shares the data, while the assignment operator copies or
+duplicate the data.
+
+\subsection{Multi-thread programming with SOPHYA}
+Multi-thread programming is usually safe as long as different threads DO NOT access
+the same memory locations. SOPHYA is mainly organized as classes having only 
+data members, with very few cases having static data members (memory locations
+common to all instances of a class), or seldom, global variables. \\
+Using different instances of a class in different threads is thus safe for most 
+classes / methods in SOPHYA. \\
+A major exception is the reference sharing mechanism, where different instances
+of a class may  shared memory locations. This reference sharing mechanism has been
+made thread-safe in SOPHYA, from version V=2.1. \\
+As a consequence, different execution threads can access non overlapping sub-arrays
+and access (read/write) the corresponding elements without the need of 
+mutex and thread synchonisation. Moreover, thread safe filling of 
+NTuple and DataTable objects can be activated, on an object per object basis. \\
+The {\tt ZThread, ZMutex \ldots} classes in the {\bf SysTools } module offer a relatively 
+easy way of writing multi-threaded programs.   
+
+\subsection{the runcxx program}
+\index{runcxx} \label{runcxx}
+{\bf runcxx} is a simple program which can be used to compile, link
+and run simple C++ programs. It handles the creation of a
+complete program file, containing the basic set C++ include files,
+the necessary include files for SOPHYA SysTools, TArray, HiStats 
+and NTools modules, and the main program with exception handling.
+Other Sophya modules can be included using the {\tt -import} flag.
+Use of additional include files can be specified using the 
+{\tt -inc} flag.
+\begin{verbatim}
+csh> runcxx -h
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  1.9 Revision 0 (V_Mai2005) -- May 31 2005 15:11:32 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, XAstroPack 
+\end{verbatim}
+Most examples in this manual can be tested using runcxx. 
+The preprocessor macro {\tt KeepObj()} is defined by runcxx and let the user 
+to save an objet to an PPF file, with the same name as the corresponding variable.
+The example below shows how to compile, link and run a sample
+code.
+\begin{verbatim}
+##  File example.icc :
+
+Matrix mxa(3,3);
+mxa = IdentityMatrix(1.);
+cout << mxa ; 
+// Save the object mxa in a PPF file named mxa
+KeepObj(mxa);
+
+## Executing this sample code
+csh> runcxx -f example.icc
+\end{verbatim}
+
+\subsection{the scanppf program}
+\index{scanppf} \label{scanppf}
+{\bf scanppf} is a simple SOPHYA application which can be used to check 
+PPF files and list their contents. It can also provide the list of all registered
+PPF handlers.
+\begin{verbatim}
+csh> scanppf -h
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx 
+ Usage: scanppf [flags] filename 
+ flags = -s -n -a0 -a1 -a2 -a3 -lh -lho -lmod 
+   -s[=default} : Sequential reading of objects 
+   -n : Object reading at NameTags 
+   -a0...a3 : Tag List with PInPersist.AnalyseTags(0...3) 
+   -lh : List PPersist handler classes 
+   -lho : List PPersist handler and dataobj classes 
+   -lmod : List initialized/registered modules 
+\end{verbatim}
+
+\subsection{the scanfits program}
+\index{scanfits} \label{scanfits}
+{\bf scanfits} is a SOPHYA program using the FitsIOServer 
+\footnote{FitsIOServer module uses the cfitsio library. scanfits has to be linked with
+with FitsIOServer module and cfitsio libraries, or libextsophya.so}
+module which can be used 
+to analyse the content of FITS files. It can list the FITS headers,  the appropriate 
+SOPHYA-FITS handler (implementing {\tt FitsHandlerInterface}) class, and the list of
+all registered  FITS handlers. 
+\begin{verbatim}
+csh> scanfits -h
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx 
+ Usage: scanfits [flags] filename 
+ flags = -V1 -lh -rd -header 
+   -V1 : Scan using old (V1) code version 
+   -lh : Print the list of registered handlers (FitsHandlerInterface) 
+   -rd : try to read each HDU data using appropriate handler 
+   -header : List header information 
+\end{verbatim}
+
+\subsection{the spiapp program}
+\index{spiapp} \label{spiapp}
+{\bf spiapp} is an interactive data analysis program, built on top of the SOPHYA 
+library, , the PI GUI library. The interactive data analysis framework is defined 
+by the classes in the {\bf PIext} module. spiapp has a c-shell like 
+command interpreter and can be used to manipulate SOPHYA and display 
+objects. Refer to the piapp user manual for more information.
+\begin{verbatim}
+csh> spiapp -h 
+ SophyaInitiator::SophyaInitiator() BaseTools Init
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  2.1 Revision 0 (V_Nov2007) -- Nov 24 2007 13:08:58 gcc 3.3 20030304 (Apple Computer, Inc. build 1495)
+
+ piapp: Interactive data analysis and visualisation program 
+ Usage: piapp [-nored] [-doublered] [-termread] [-term] 
+              [-hidezswin] [-small] [-nosig] [-nosigfpe] [-nosigsegv] 
+              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] 
+  -nored : Don't redirect stdout/stderr to piapp console
+  -doublered : Redirect stdout/stderr to piapp console AND the terminal 
+  -termread : Read commands on terminal (stdin)
+  -term : equivalent to -nored -termread -small 
+  -hidezswin : Hide Zoom/Stat/ColMap window 
+  -small : Create small size main piapp window 
+  -nosig : Don't catch SigFPE, SigSEGV 
+  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV 
+  -tmpdir TmpDirectory: defines TMDIR for temporary files 
+  -help2tex: Create a LaTeX help file (piahelp.tex)
+  -exec file [args] : Execute command file (last option)
+
+\end{verbatim}
+
+
+\newpage
+\section{Module BaseTools}
+
+{\bf BaseTools} contains utility classes such as 
+{\tt DVlist}, an hierarchy of exception classes for Sophya, a template
+class {\tcls{NDataBlock}} for handling reference counting on numerical
+arrays, as well as classes providing the services for implementing simple
+serialisation (object persistence services).
+\vspace*{5mm}
+
+\subsection{Initialisation}
+\index{SophyaInitiator}
+A number of actions have to be taken before 
+some of the services provided by SOPHYA become operational. This is the case
+of SOPHYA persistence, as well as FITS I/O facilities. 
+Initialisation of many SOPHYA modules is performed through an initialiser class,
+which inherits from {\bf SophyaInitiator}. 
+\par
+Static instance of each initialiser class exist in the library and the various SOPHYA services
+should be operational when the user code ({\tt main()}) starts, except for 
+modules in the second or third shared libraries 
+({\tt libextsophya.so libPI.so}). Indeed, a problem related 
+to the initialisation of shared libraries arises on some systems
+(Darwin/Mac OS X in particular) causing program crash at start-up, 
+if static instance of initialiser class is present in the second shared library. 
+The FitsIOServer module should thus be explicitly initialised in the user 
+program. 
+\par 
+In cases where the run time loader does not perform correctly the static 
+object initialisation, the initialiser class for the modules used in the 
+program must be instanciated in the beginning of your main program: \\
+{\tt TArrayInitiator , HiStatsInitiator , SkyMapInitiator , FitsIOServer \ldots}
+%%%
+\subsection{SOPHYA persistence}
+\label{ppfdesc}
+\index{PPersist} \index{PInPersist} \index{POutPersist}
+\begin{figure}[hbt]
+\dclsa{PPersist}
+\dclsccc{PPFBinarIOStream}{PPFBinaryInputStream}{PInPersist}
+\dclscc{PPFBinaryOutputStream}{POutPersist}
+\caption{partial class diagram for classes handling persistence in Sophya}
+\end{figure}
+A simple persistence mechanism is defined in SOPHYA. Its main 
+features are:
+\begin{itemize}
+\item[] Portable file format, containing the description of the data structures
+and object hierarchy. \\
+{\bf PPF} {\bf P}ortable {\bf P}ersistence file {\bf F}ormat.
+\index{PPF}
+\item[] Handling of read/write for multiply referenced objects.
+\item[] All write operations are carried using sequential access only. This
+holds also for read operations, unless positional tags are used. 
+SOPHYA persistence services can thus be used to transfer objects
+through network links.
+\item[] The serialisation (reading/writing) for objects for a given class
+is implemented through a handler object. The handler class inherits
+from {\tt PPersist} class.
+\item[] A run time registration mechanism is used in conjunction with 
+RTTI (Run Time Type Identification) for identifying handler classes
+when reading {\bf PInPersist} streams, or for associating handlers
+with data objects {\bf AnyDataObject} for write operations.
+\end{itemize}
+The most useful methods for using Sophya
+persistence are listed below. A brief description of the PPF file format 
+and some guidelines for writing writing delegate classes for handling 
+object persistence can be found in the following paragraphs.
+\begin{itemize}
+\item[] {\tt POutPersist::PutObject(AnyDataObj \& o)} \\ 
+Writes the data object {\bf o} to the output stream.
+\item[] {\tt POutPersist::PutObject(AnyDataObj \& o, string tagname)} \\
+Writes the data object {\bf o} to the output stream, associated with an
+identification tag {\bf tagname}.
+\item[] {\tt PInPersist::GetObject(AnyDataObj \& o)} \\ 
+Reads the next object in stream into {\bf o}. An exception is 
+generated for incompatible object types.
+\item[] {\tt PInPersist::GetObject(AnyDataObj \& o, string  tagname)} \\
+Reads the object associated with the tag {\bf tagname} into {\bf o}. 
+An exception is generated for incompatible object types.
+\end{itemize}
+The operators {\tt operator << (POutPersist ...) } and 
+{\tt operator >> (PInPersist ...) } are often overloaded 
+to perform {\tt PutObject()} and {\tt GetObject()} operations.
+the {\bf PPFNameTag} (ppfnametag.h) class can be used in conjunction with 
+{\tt << >> } operators to write objects with a name tag or to retrieve
+an object identified with a name tag. The example below shows the
+usage of these operators:
+\begin{verbatim}
+// Creating and filling a histogram
+Histo hw(0.,10.,100);
+...
+// Writing histogram to a PPF stream
+POutPersist os("hw.ppf");
+os << PPFNameTag("myhisto") << hw;
+
+// Reading a histogram from a PPF stream
+PInPersist is("hr.ppf");
+is >> PPFNameTag("myhisto")  >> hr;
+\end{verbatim}
+
+The {\bf scanppf} program can be used to list the content of a PPF file.
+
+\subsubsection{PPF file format}
+The PPF file consist of :
+\begin{itemize}
+\item[\rond] A file header (3x32=96 bytes) , containing  an identification string, 
+PPF format version (currently V3), the file endiannes {\tt (BIG-ENDIAN , LITTLE-ENDIAN)}
+and the file creation date and time. It should be noted that the present SOPHYA version 
+(V=2.1) does not allow updating an existing PPF file.
+\item[\rond] A collection of tagged data items and data structuring tags. 
+the PPF tags are one byte (8 bits) long and may be followed by a length information
+for arrays, or strings. The length information might be 4 bytes or 8 bytes long.
+Characters, various length (1,2,4,8 bytes long) signed and unsigned integers, 
+simple or double precision (4/8) bytes floating point and complex numbers are 
+the basic data types handled by PPF streams.
+\begin{verbatim}
+tag=PPS_SIMPLE_Integer4  +  data (4 bytes)
+tag=PPS_SIMPLE_Float4 + data (4 bytes)
+tag=PPS_SIMPLE_Complex8 + data (2x8=16 bytes)
+tag=PPS_STRING + Length (4 bytes) + data (Length bytes)
+tag=PPS_SIMPLE_ARRAY4_UInt2 + Length (4 bytes) + data (2xLength bytes)
+\end{verbatim}
+The two tags  {\tt PPS\_OBJECT} and {\tt PPS\_ENDOBJECT} are used for identifying 
+objects. 
+\item[\rond] The file trailer contains some global statistics such as the total number 
+of objects in file, the list of name tags, with their corresponding positions. 
+These informations are grouped under the identifier tag {\tt  PPS\_NAMETAG\_TABLE }.
+The last byte in file contains the value {\tt PPS\_EOF}
+\end{itemize}
+We show below the result of the analysis of a PPF file using 
+ {\tt PPFBinaryInputStream::AnalyseTags()}. This can easily be done using the 
+ {\bf runcxx} program.
+The PPF file contains four objects: 
+a {\tt TimeStamp} object, two {\tt NDataBlock} objects, the second one sharing its data with 
+the first one. The second NDataBlock is only written as a reference to the first object. The fourth 
+object is a {\tt RandomGenerator} which has an {\tt NDataBlock} object as data member. 
+Notice the corresponding nested structure of object marker tags.
+The first object and the last objects in the file are written associated with a {\bf NameTag}.
+{\small 
+\begin{verbatim}
+ ---------------------------------------------------------- 
+ PPFBinaryInputStream::AnalyseTags(Level= 49)
+   FileName= toto.ppf
+   Version= 3 FileSize= 8884 Creation Date= Fri Dec  7 15:30:58 2007
+
+ NbPosTag=0 NbNameTag=2 NbObjs=4 NbTopLevObjs=3 NbRefs=1 MaxNest=2
+
+<PPS_NAMETAG_MARK> tag at position 60
+<PPS_OBJECT> tag at position 61 ClassId= c09dfe032b341cee  ObjectId= 10
+  <PPS_SIMPLE> tag at position 72 DataType=INTEGER x4
+  <PPS_SIMPLE> tag at position 77 DataType=INTEGER x8
+  <PPS_SIMPLE> tag at position 80 DataType=FLOAT x8
+<PPS_ENDOBJECT> tag at position 89  ObjectId= 10
+<PPS_OBJECT> tag at position 92 ClassId= e670300b367585d1  ObjectId= 21
+  <PPS_SIMPLE_ARRAY4> tag at position a3 DataType=UNSIGNED x8 NElts= 3
+  <PPS_SIMPLE_ARRAY4> tag at position c0 DataType=INTEGER x4 NElts= 50
+<PPS_ENDOBJECT> tag at position 18d  ObjectId= 21
+<PPS_REFERENCE> tag at position 196  ObjectId= 21  OrigPos=92
+<PPS_NAMETAG_MARK> tag at position 1a7
+<PPS_OBJECT> tag at position 1a8 ClassId= eb6c427a5a30caed  ObjectId= 30
+  <PPS_SIMPLE_ARRAY4> tag at position 1b9 DataType=UNSIGNED x4 NElts= 6
+  <PPS_SIMPLE> tag at position 1d6 DataType=UNSIGNED x8
+  <PPS_SIMPLE> tag at position 1df DataType=UNSIGNED x8
+  <PPS_OBJECT> tag at position 1e8 ClassId= 6531a8f47336d4aa  ObjectId= 41
+    <PPS_SIMPLE_ARRAY4> tag at position 1f9 DataType=UNSIGNED x8 NElts= 3
+    <PPS_SIMPLE_ARRAY4> tag at position 216 DataType=FLOAT x8 NElts= 1024
+  <PPS_ENDOBJECT> tag at position 221b  ObjectId= 41
+<PPS_ENDOBJECT> tag at position 2224  ObjectId= 30
+<PPS_NAMETAG_TABLE> tag at position 222d
+<PPS_NAMETAG_ENTRY>  NameTag=rg-randgen NameTagMark Position=1a7
+<PPS_NAMETAG_ENTRY>  NameTag=ts-timestamp NameTagMark Position=60
+<PPS_EOF> tag at position 22b3 TagPos=222d
+ PPFBinaryInputStream::AnalyseTags() - End - Total Number of Tags= 23
+ ---------------------------------------------------------- 
+\end{verbatim}
+}  % fin de small 
+
+\subsubsection{Writing PPF handlers}
+Here are some guidelines for creating PPF handler classes to make 
+a class persistent through the SOPHYA PPersist mechanism. The example
+discussed here can be found in the {\bf Examples} module, in the directory 
+{\bf MyPPF}. 
+\begin{enumerate}
+\item The class should inherit from the {\bf SOPHYA::AnyDataObj} class. 
+   In the example here, we want to make the class {\bf Vfs} persistent
+\begin{verbatim}   
+class Vfs : public SOPHYA::AnyDataObj {
+ ... 
+}
+\end{verbatim}
+%%%%
+\item The PPF handler class 
+should inherit from {\bf SOPHYA::PPersist} . The pure virtual methods 
+of PPersist class (DataObj() , SetDataObj() , ReadSelf(), WriteSelf()
+must be implemented. 
+\begin{verbatim}   
+class PPFHandlerVfs : public SOPHYA::PPersist {
+public:
+  virtual SOPHYA::AnyDataObj* DataObj();
+  virtual void       SetDataObj(SOPHYA::AnyDataObj &);
+protected: 
+  virtual void       ReadSelf(SOPHYA::PInPersist&);
+  virtual void       WriteSelf(SOPHYA::POutPersist&) const;
+}
+\end{verbatim}
+%%%
+It is possible to use the template class {\tt SOPHYA::ObjFileIO<T>}, and 
+specialize it for the tharget class (here {\tt SOPHYA::ObjFileIO<Vfs>}), 
+by defining the two methods :  \\
+\hspace*{5mm} {\tt  SOPHYA::ObjFileIO<Vfs>::ReadSelf(SOPHYA::PInPersist\&) } \\
+\hspace*{5mm}  {\tt  SOPHYA::ObjFileIO<Vfs>::WriteSelf(SOPHYA::POutPersist\&) const }
+%%%%
+\item If it is NOT possible to have the target class inherit from {\bf AnyDataObj}, 
+a wrapper class should be used. The same class can play the role of wrapper
+AND the PPF handler. See the PPF handler / wrapper class for STL vectors : \\
+\hspace*{5mm} {\tt   SOPHYA::PPFWrapperSTLVector<T>} in file BaseTools/ppfwrapstlv.h 
+%%%
+\item Implement the ReadSelf() and WriteSelf() methods of the PPF handler.
+All the I/O services from the following classes can be used : 
+\begin{itemize}
+\item PPFBinaryIOStrem , PPFBinaryInputStream , PInPersist
+\item PPFBinaryIOStrem , PPFBinaryOutputStream , POutPersist
+\end{itemize}
+Writing and reading of the embeded objects for which a handler has been register
+ed can simply be performed by :  \\
+\hspace*{5mm} {\tt   POutPersist::PutObject() } \\
+\hspace*{5mm} {\tt   PInPersist::GetObject() }
+
+{\bf Warning:} The services associated with nametags : \\
+\hspace*{5mm}  {\tt PPFBinaryOutputStream::WriteNameTag() } \\
+\hspace*{5mm}  {\tt PPFBinaryInputStream::GotoNameTag() } \\
+are {\bf NOT} intented to be used in WriteSelf() , ReadSelf()
+%%%%%
+\item The new PPF handler, as well as the list of classes it can handle has to be
+registered prior to use PPF read/write for the target classes. This must be 
+performed during the initialization phase, for example at the beginning of the 
+main() program. Another possibility is to use a module initializer 
+(See {\bf SophyaInitiator} class in file BaseTools/sophyainit.h ) 
+and declare a static instance of the class. Notice that this works only if 
+the system loader handles correcly the call of constructor 
+for the statically declared objects. 
+
+The registration can be performed using the CPP macros defined in 
+BaseTools/ppersist.h
+\begin{verbatim}
+  // First, register the PPF handler ObjFileIO<Vfs> 
+  PPRegister(ObjFileIO<Vfs>);
+  // Register the list of classes which can be handled by ObjFileIO<Vfs> 
+  DObjRegister(ObjFileIO<Vfs>, Vfs);
+\end{verbatim}
+%%%%%%%%%%%%%%%%
+\end{enumerate}
+
+%%%%%%%%%%%%
+\subsection{\tcls{NDataBlock}}
+\index{\tcls{NDataBlock}}
+\begin{figure}[hbt]
+\dclsbb{AnyDataObj}{\tcls{NDataBlock}}
+\dclsbb{PPersist}{\tcls{FIO\_NDataBlock}}
+\end{figure}
+The {\bf \tcls{NDataBlock}} is designed to handle reference counting 
+and sharing of memory blocs (contiguous arrays) for numerical data 
+types. Initialisation, resizing, basic arithmetic operations, as
+well as persistence handling services are provided. 
+The persistence handler class ({\tt \tcls{FIO\_NDataBlock}}) insures
+that a single copy of data is written for multiply referenced objects,
+and the data is shared among objects when reading. 
+\par
+The example below shows writing of NDataBlock objects through the 
+use of overloaded operator $ << $ :
+\begin{verbatim}
+#include "fiondblock.h"
+// ...
+POutPersist pos("aa.ppf");
+NDataBlock<r_4> rdb(40);
+rdb = 567.89;
+pos << rdb;
+// We can also use the PutObject method
+NDataBlock<int_4> idb(20);
+idb = 123;
+pos.PutObject(idb);
+\end{verbatim}
+The following sample programs show the reading of the created PPF file : 
+\begin{verbatim}
+PInPersist pis("aa.ppf");
+NDataBlock<r_4> rdb;
+pis >> rdb;
+cout << rdb;
+NDataBlock<int_4> idb;
+cout << idb;
+\end{verbatim}
+
+\subsection{DVList, MuTyV and TimeStamp classes}
+\index{DVList} \index{MuTyV} \index{TimeStamp}
+\begin{figure}[hbt]
+\dclsa{MuTyV}
+\dclsbb{AnyDataObj}{DVList}
+\dclsbb{PPersist}{\tclsc{ObjFileIO}{DVList}}
+\end{figure}
+The {\bf DVList} class objects can be used to create and manage list
+of values, associated with names. A list of pairs of (MuTyV, name(string))
+is maintained by DVList objects. {\bf MuTyV} is a simple class
+capable of holding string, integer, float or complex values, 
+providing easy conversion methods between these objects.
+{\bf MuTyV} objects can also hold {\bf TimeStamp } objects.
+\begin{verbatim}
+// Using MuTyV objects
+MuTyV s("hello");  // string type value
+MuTyV x;
+x = "3.14159626";    // string type value, ASCII representation for Pi
+double d = x;        // x converted to double = 3.141596
+x = 314;             // x contains the integer value = 314
+// Using DVList
+DVList  dvl;
+dvl("Pi") = 3.14159626;            // float value, named Pi
+dvl("Log2") = 0.30102999;          // float value, named Log2
+dvl("FileName") = "myfile.fits";   // string value, named myfile.fits
+// Printing DVList object
+cout << dvl;
+\end{verbatim}
+
+\begin{figure}[hbt]
+\dclsbb{AnyDataObj}{TimeStamp}
+\end{figure}
+%
+The {\bf TimeStamp} class represent date and time and provides
+many standard operations, such as Initialisation from strings,
+conversion to strings and time interval computations. \\
+Usage example:
+\begin{verbatim}
+// Create a object with the current date and time and prints it to cout
+TimeStamp ts; 
+cout << ts << endl;
+// Create an object with a specified date and time 
+TimeStamp ts2("01/01/1905","00:00:00");
+// Get the number of days since 0 Jan 1901
+cout << ts2.ToDays() << endl;
+
+// Combined use of TimeStamp and MuTyV 
+string s;         
+TimeStamp ts;      // Current date/time
+MuTyV mvt = ts;
+s = mvt;           // s contains the current date in string format
+cout << s << endl;
+\end{verbatim}
+
+\subsection{\tcls{SegDataBlock} , \tcls{SwSegDataBlock}}
+\index{\tcls{SegDataBlock}}  \index{\tcls{SwSegDataBlock}}
+%%
+\begin{figure}[hbt]
+\dclsccc{AnyDataObj}{\tcls{SegDBInterface}}{ \tcls{SegDataBlock} }
+\dclscc{\tcls{SegDBInterface}}{ \tcls{SwSegDataBlock} }
+\end{figure}
+\begin{itemize} 
+\item[\rond] \tcls{SegDataBlock}  handles arrays of object of
+type {\bf T} with reference sharing in memory. The array can be extended
+(increase in array size) with fixed segment size. It implements the interface
+defined by \tcls{SegDBInterface}.
+\item[\rond] \tcls{SwSegDataBlock} Implements the same \tcls{SegDBInterface}
+using a data swapper object. Data swappers implement the interface defined in 
+(\tcls{DataSwapperInterface} class.  \tcls{SwSegDataBlock} can 
+thus be used to handle arrays with very large number of objects.
+These classes handles reference sharing.
+\end{itemize}
+ 
+ \subsection{Random numbers}
+ \index{RandomGenerator}
+ The C-functions defined in the file BaseTools/srandgen.h can be used
+ for generating sequence of random numbers with different PDF (probability 
+ distribution functions : flat, gaussian, poisson \ldots.
+ However, we advise to use the {\bf RandomGenerator} class which provides
+can be used in multi-threaded programs. In this case, a different instance of
+the  RandomGenerator class should be created in each thread running in parallel.
+In addition, this class has a PPF handler which saves the complete state of the class and 
+the underlying generatoir to the PPF stream. This can be used to generate very long sequence
+of random numbers, distributed over several runs.
+\begin{verbatim}
+sa_size_t N = 1000;
+Vector vf(2*N), vg(2*N);
+{
+// Instanciate the random generator
+RandomGenerator rg;
+// Generate some sequence of random numbers
+for(sa_size_t i=0; i<N; i++) {
+  vf(i) = rg.Flat01();
+  vg(i) = rg.Gaussian(); 
+  }
+// Save the generator to file rg.ppf
+POutPersist po("rg.ppf");
+po << rg;  
+}
+// ....
+{
+// Create and read the generator from file rg.ppf
+RandomGenerator rg;
+PInPersist pi("rg.ppf");
+pi >> rg;  
+// Continue the generation sequence
+for(sa_size_t i=N; i<2*N; i++) {
+  vf(i) = rg.Flat01();
+  vg(i) = rg.Gaussian(); 
+  }
+}
+\end{verbatim}
+
+%%%%%%%%%%%%
+\newpage
+\section{Module TArray}
+\index{\tcls{TArray}}
+{\bf TArray} module contains template classes for handling standard 
+operations on numerical arrays. Using the class {\tt \tcls{TArray} },
+it is possible to create and manipulate up to 5-dimension numerical
+arrays {\tt (int, float, double, complex, \ldots)}. The include
+file {\tt array.h} declares all the classes and definitions 
+in module TArray. {\bf Array} is a typedef for arrays 
+with double precision floating value elements. \\
+{\tt typedef TArray$<$r\_8$>$ Array ; }
+
+\begin{figure}[hbt]
+\dclsccc{AnyDataObj}{BaseArray}{\tcls{TArray}}
+\dclsbb{PPersist}{\tcls{FIO\_TArray}}
+\end{figure}
+
+The development of this module started around 1999-2000,
+after evaluation of a number of publicly  available 
+C++ array hadling packages, including TNT, Lapack++, Blitz++, 
+as well as commercial packages from RogueWave (math.h++ \ldots). 
+Most of these packages provide interesting functionalities, however, 
+not any one package seemed to fulfill most of our requirements.
+\begin{itemize}
+\item Capability to handle {\bf large - multidimensional - dense} 
+arrays, for numerical data types. Although we have used templates, for
+data type specialisation, the actual code, apart inline functions is
+not in header files. Instead, we use explicit instanciation, and the 
+compiled code for the various numerical types of arrays is the
+library .
+\item The shape and size of the arrays can be defined and changed
+at run time. The classes ensure the memory management of the 
+created objets, with reference sharing for the array data. 
+The default behaviour of the copy constructor is to share the data,
+avoiding expensive memory copies.
+\item The package provides transparent management of sub-arrays
+and slices, in an intuitive way, somehow similar to what is
+available in Mathlab or Scilab.
+\item The memory organisation for arrays, specially matrices 
+(row-major or column major) can be 
+controled. This provide compatibility when using existing C or
+Fortran coded numerical libraries.
+\item The classes provide efficient methods to perform basic arithmetic
+and mathematical operations on arrays. In addition, operator overload 
+provides intuitive programming for element acces and most basic
+arithmetic operations.
+\item Conversion can be performed between arrays with different
+data types. Copy and arithmetic operations can be done transparently 
+between arrays with different memory organisation patterns.   
+\item This module does not provide more complex operations 
+such as FFT or linear algebra. Additional libraries are used, with interface
+classes for these operations.
+\item ASCII formatted I/O, for printing and read/write operations to/from text files.
+\item Efficient binary I/O for object persistence (PPF format), or import/export 
+to other data formats, such as FITS are provided by helper or handler classes. 
+\end{itemize}
+
+\subsection{Using arrays}
+\index{Sequence} \index{RandomSequence} \index{RegularSequence} 
+\index{EnumeratedSequence}
+The example below shows basic usage of arrays, creation, initialisation
+and arithmetic operations. Different kind of {\bf Sequence} objects
+can be used for initialising arrays. 
+
+\begin{figure}[hbt]
+\dclsbb{Sequence}{RandomSequence}
+\dclsb{RegularSequence}
+\dclsb{EnumeratedSequence}
+\end{figure}
+
+The example below shows basic usage of arrays: 
+\index{\tcls{TArray}} 
+\begin{verbatim}
+// 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;
+\end{verbatim}
+
+The copy constructor shares the array data, while the assignment operator
+copies the array elements, as illustrated in the following example:
+\begin{verbatim}
+TArray<int> a1(4,3);
+a1 = RegularSequence(0,2);
+// Array a2 and a1 shares their data 
+TArray<int> a2(a1);
+// a3 and a1 have the same size and identical elements
+TArray<int> a3;
+a3 = a1;
+// Changing one of the a2 elements
+a2(1,1,0) = 555;
+// a1(1,1) is also changed to 555, but not a3(1,1)
+cout << "Array<int> a1 = " << a1;
+cout << "Array<int> a3 = " << a3;
+\end{verbatim} 
+
+\subsection{Arithmetic operations}
+The four usual arithmetic operators ({\bf  + \, - \, * \, / }) are defined
+to perform constant addition, subtraction, multiplication and division. 
+The three operators ({\bf  + \, - \, / }) between two arrays of the same type
+are defined to perform element by element addition, subtraction
+and division. In order to avoid confusion with matrix multiplication, 
+element by element multiplication is defined by overloading the
+operator {\bf \, \&\& \, }, as shown in the example below:
+\begin{verbatim}
+TArray<int_4> a(4,3), b(4,3), c , d, e;
+a = RegularSequence(1.,1.);
+b = RegularSequence(10.,10.);
+cout << a << b ;
+c = a && b; 
+d = c / a;
+e = (c / b) - a;
+cout << c << d << e;
+\end{verbatim}
+
+\subsection{Matrices and vectors}
+\index{\tcls{TMatrix}}  \index{\tcls{TVector}}
+\begin{figure}[hbt]
+\dclsccc{\tcls{TArray}}{\tcls{TMatrix}}{\tcls{TVector}}
+\end{figure}
+Vectors and matrices are 2 dimensional arrays. The array size
+along one dimension is equal 1 for vectors. Column vectors
+have {\tt NCols() = 1} and row vectors have {\tt NRows() = 1}.
+Mathematical expressions involving matrices and vectors can easily 
+be translated into C++ code using {\tt TMatrix} and 
+{\tt TVector} objects. {\bf Matrix} and {\bf Vector} are 
+typedefs for double precision float matrices and vectors.
+The operator {\bf *} beteween matrices is redefined to 
+perform matrix multiplication. One can then write: \\
+\begin{verbatim}
+  // We create a row vector
+  Vector v(1000, BaseArray::RowVector);
+  // Initialize values with a random sequence
+  v = RandomSequence();
+  // Compute the vector length (norm)
+  double norm = (v*v.Transpose()).toScalar();
+  cout << "Norm(v) = " << norm << endl;
+\end{verbatim}
+
+This module contains basic array and matrix operations 
+such as the Gauss matrix inversion algorithm
+which can be used to solve linear systems, as illustrated by the 
+example below:
+\begin{verbatim}
+#include "sopemtx.h"
+// ...
+// Creation of a random 5x5 matrix
+Matrix A(5,5);
+A = RandomSequence(RandomSequence::Flat);
+Vector X0(5);
+X0 = RandomSequence(RandomSequence::Gaussian);
+// Computing B = A*X0
+Vector B = A*X0;
+// Solving the system A*X = B 
+Vector X;
+LinSolve(A, B, X);
+// Checking the result
+Vector diff = X-X0;
+cout << "X-X0= " << diff ;
+double min,max;
+diff.MinMax(min, max);
+cout << " Min(X-X0) = " << min << " Max(X-X0) = " << max << endl; 
+\end{verbatim}
+
+{\bf Warning: } The operations defined in {\tt sopemtx.h}, such as 
+matrix inversion and linear system solver use a basic Gauss pivot
+algorithm which are not adapted for large matrices ($>\sim 100x100$).
+The services provided in other modules, such as {\bf LinAlg} should
+be preferred in such cases.
+
+\subsection{Working with sub-arrays and Ranges}
+\index{Range}
+A powerful mechanism is included in array classes for working with 
+sub-arrays. The class {\bf Range} can be used to specify range of array 
+indexes in any of the array dimensions. Any regularly spaced index
+range can be specified, using the {\tt start} and {\tt end} index
+and an optional step (or stride). It is also possible to specify
+the {\tt start} index and the number of elements.
+\begin{itemize}
+\item {\bf Range::all()} {\tt = Range(Range::firstIndex(), Range::lastIndex())}  \\
+return a Range objects representing all  valid indexes along the 
+corresponding axe.
+\item {\bf Range::first()} {\tt = Range(Range::firstIndex())}  \\
+return a Range object representing the first valid index
+\item {\bf Range::last()} {\tt = Range(Range::lastIndex())} 
+return a Range object representing the last valid index
+\item {\bf Range(idx)} represents a single index ({\bf = idx})
+\item {\bf Range(first, last)} represents the range of indices
+{\bf first} $\leq$ index $\leq$ {\bf last}.\\
+The static method {\tt Range::lastIndex()} can be used 
+to specify the last valid index.
+\item {\bf Range(first, last, step)} represents the range of index
+which is equivalent to \\  {\tt for(index=first; index <= last; index += step) }
+\item { \bf Range (first, last, size, step) } the general form can be used 
+to specify an index range, using the number of elements. 
+It is possible to specify a range of index, ending with the last valid index. 
+For example \\
+\hspace*{5mm} 
+{\tt Range(Range::lastIndex(), Range::lastIndex(), 3, 2) }  \\
+defines  the index range: \hspace*{5mm}  last-4, last-2, last.
+
+\begin{center}
+\begin{tabular}{ll}
+\hline \\
+\multicolumn{2}{c}{ {\bf Range} {\tt (start, end, size, step) } } \\[2mm]
+\hline \\
+{\bf Range} {\tt r(7); } &  index range:  \hspace{2mm} 7 \\
+{\bf Range} {\tt r(3,6); } &  index range:  \hspace{2mm} 3,4,5,6 \\
+{\bf Range} {\tt r(3,7,2); } &  index range: \hspace{2mm} 3,5,7 \\
+{\bf Range} {\tt r(7,0,3,1); } &  index range: \hspace{2mm} 7,8,9 \\
+{\bf Range} {\tt r(10,0,5,2); } &  index range: \hspace{2mm} 10,12,14,16,18 \\[2mm]
+\hline 
+\end{tabular}
+\end{center}
+\end{itemize}
+
+The method {\tt TArray<T>SubArray(Range ...)} can be used 
+to extract subarrays and slices. The operator {\tt operator() (Range rx, Range ry ...)}
+is also overloaded for sub-array extraction.
+For matrices, {\tt TMatrix<T>::Row()} and {\tt TMatrix<T>::Column()} 
+extract selected matrix rows and columns.
+
+The example illustrates the sub-array extraction using Range objects:
+\begin{verbatim}
+  // Creating and initialising a 2-D (6 x 4) array of integers
+  TArray<int> iaa(6, 4);
+  iaa = RegularSequence(1,2);
+  cout << "Array<int> iaa = \n" << iaa;
+  // We extract a sub-array - data is shared with iaa
+  TArray<int> iae = iaa(Range(1, Range::lastIndex(), 3) ,
+                        Range::all(), Range::first() );
+  cout << "Array<int> iae=subarray(iaa) = \n" << iae;
+  // Changing iae elements changes corresponding iaa elements
+  iae = 0;
+  cout << "Array<int> iae=0 --> iaa = \n" << iaa;
+
+\end{verbatim}
+
+In the following example, a simple low-pass filter, on a one 
+dimensional stream (Vector) has been written using sub-arrays:  
+
+\begin{verbatim}
+// 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.);
+\end{verbatim}
+
+\subsection{Input, Output}
+Arrays can easily be saved to, or restored from files in different formats.
+SOPHYA library can handle array I/O to ASCII formatted files, to PPF streams, 
+as well as to files in FITS format.
+FITS format input/output is provided through the classes in 
+{\bf FitsIOServer} module. Only arrays with data types 
+supported by the FITS standard can be handled during 
+I/O operations to and from FITS streams (See the FitsIOServer section
+for additional details).
+
+\subsubsection{PPF streams} 
+
+SOPHYA persistence (PPF streams) handles reference sharing, and multiply 
+referenced objects are only written once. A hierarchy of arrays and sub-arrays
+written to a PPF stream is thus completely recovered, when the stream is read.
+The following example illustrates this point:
+\begin{verbatim}
+{
+// Saving an array with a sub-array into a POutPersist file
+Matrix A(3,4);
+A = RegularSequence(10,5);
+// Create a sub-array of A 
+Matrix AS = A(Range(1,2), Range(2,3));
+// Save the two arrays to a PPF stream
+POutPersist pos("aas.ppf");
+pos << A << AS; 
+}
+{
+// Reading arrays from the previously created PPF file aas.ppf
+PInPersist pis("aas.ppf");
+Matrix B,BS;
+pis >> B >> BS;
+// BS is a sub-array of B, modifying BS changes also B
+BS(1,1) = 98765.;
+cout << " B , BS after BS(1,1) = 98765. " 
+     << B << BS << endl; 
+}
+\end{verbatim} 
+The execution of this sample code creates the file {\tt aas.ppf} and 
+its output is reproduced here. Notice that the array hierarchy is 
+recovered. BS is a sub-array of B, and modifying BS changes also
+the corresponding element in B.
+\begin{verbatim}
+ B , BS after BS(1,1) = 98765.
+
+--- TMatrix<double>(NRows=3, NCols=4) ND=2 SizeX*Y*...= 4x3 ---
+10 15 20 25
+30 35 40 45
+50 55 60 98765
+
+--- TMatrix<double>(NRows=2, NCols=2) ND=2 SizeX*Y*...= 2x2 ---
+40 45
+60 98765
+\end{verbatim} 
+
+{\bf Warning: }
+There is a drawback in this behaviour: only a single 
+copy of an array is written to a file, even if the array is modified, 
+without being resized and written (dumped) again to the same  PPF stream. 
+However, this behavior can be changed using the {\tt RenewObjId()} method,
+as illustrated below.
+\begin{verbatim}
+{
+POutPersist pos("mca.ppf");
+TArray<int_4> ia(5,3);
+ia = 8;
+pos << ia;         // (1) 
+ia = 16;
+pos << ia;        // (2) Only a reference to the previously ia array is written
+ia = 32;
+ia.RenewObjId();    // We change the object Id
+pos << ia;        //  (3) The complete array is dumped again 
+}
+\end{verbatim}
+
+Only a single copy of the data is effectively written to the output 
+PPF file, corresponding to the value 8 for array elements, for the first two 
+write operations. When we 
+read the three array from the file mca.ppf, the same array elements
+are obtained two times (all elements equal to 8), and a different array is obtained 
+the third time 
+\begin{verbatim}
+{
+PInPersist pis("mca.ppf");
+TArray<int_4> ib;
+pis >> ib;
+cout << " First array read from mca.ppf : " << ib;
+pis >> ib;
+cout << " Second array read from mca.ppf : " << ib;
+pis >> ib;
+cout << " Third array read from mca.ppf : " << ib;
+}
+\end{verbatim}
+
+\subsubsection{ASCII streams} 
+
+The {\bf WriteASCII} method can be used to dump an array to an ASCII 
+formatted file, while the {\bf ReadASCII} method can be used to decode 
+ASCII formatted files. Space or tabs are the possible separators. 
+Complex numbers should be specified as a pair of comma separated 
+real and imaginary parts, enclosed in parenthesis. 
+
+\begin{verbatim}
+{
+// Creating array A and writing it to an ASCII file (aaa.txt)
+Array A(4,6);
+A = RegularSequence(0.5, 0.2);
+ofstream ofs("aaa.txt");
+A.WriteASCII(ofs);
+}
+{
+// Decoding the ASCII file aaa.txt
+ifstream ifs("aaa.txt");
+Array B;
+sa_size_t nr, nc;
+B.ReadASCII(ifs,nr,nc);
+cout << " Array B; B.ReadASCII() from file " << endl;
+cout << B ;
+}
+\end{verbatim}
+
+\subsection{Cast without conversion}
+Data conversion between arrays with different data type is handled transparently,
+through the copy constructor or the assignment (=) operator . However, in rare cases, 
+one wants to access the same memory locations, without data type conversion.
+The template functions defined in {\tt arrctcast.h} can be used to access the same 
+memory locations, by arrays with different data types. The SOPHYA/NDataBlock 
+reference sharing mechanism is effective When using these functions.
+Notice that the array size or stride may change during these cast operations. \\
+ {\tt arrctcast.h} has been introduced in version V=2.1 (Nov 2007), and has not been 
+ fully tested for non packed arrays.
+\begin{verbatim}
+// We define and initialize a  real array :
+TArray<r_4> fa(5);
+fa = RegularSequence(1.25,0.5);
+cout << " fa= " << fa;
+// We construct an integer array from fa, where the floating point values
+// are converted to integer values
+TArray<uint_2> ia(fa);
+cout << "  ia= " << ia;
+cout << "  ia (in hex)= " << hex << ia << dec;
+// We can also access the fa memory locations interpreted as short integers
+uint_2 ui2;
+// Note that sfia size is double the fa size 
+TArray<uint_2> sfia = ArrayCast(fa, ui2);
+cout << "  sfia= " << sfia;
+cout << "  sfia (in hex)= " << hex << sfia << dec;
+\end{verbatim}
+One of the most useful case of these array type cast without conversion 
+correspond to accessing the real or imaginary part of a complex array. 
+Two specific template functions {\tt SDRealPart()} and {\tt SDImagPart()}
+are also defined in  {\tt arrctcast.h}. Two other functions {\tt ArrCastR2C()}
+and {\tt ArrCastC2R() } are also defined for real to complex, and
+complex to real cast. 
+Their usage is shown in the next  paragraph on complex arrays.
+
+\subsection{Complex arrays}
+The {\bf TArray} module provides few functions for manipulating
+arrays of complex numbers (single and double precision).
+These functions are declared in {\tt matharr.h}.
+\begin{itemize}
+\item[\bul] Creating a complex array through the specification of the 
+real and imaginary parts. 
+\item[\bul] Functions returning arrays corresponding to real and imaginary 
+parts of a complex array: {\tt real(za) , imag(za) } 
+({\bf Warning:} Note that the these functions create an array and copies
+the data from the original complex array. They do not provide
+shared memory access to real and imaginary parts. 
+For shared memory access, use functions {\tt SDRealPart()} and
+{\tt SDImagPart() } (see below). 
+\item[\bul] Functions returning arrays corresponding to the module, 
+phase, and module squared of a complex array:
+ {\tt phase(za) , module(za) , module2(za) } 
+\end{itemize}
+
+\begin{verbatim}
+  TVector<r_4> p_real(10, BaseArray::RowVector);
+  TVector<r_4> 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= " << 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) ;
+\end{verbatim}
+
+The decoding of complex numbers from an ASCII formatted stream 
+is illustrated by the next example. As mentionned already, 
+complex numbers should be specified as a pair of comma separated 
+real and imaginary parts, enclosed in parenthesis. 
+
+\begin{verbatim}
+csh> cat zzz.txt
+(1.,-1) (2., 2.5) -3. 12.
+-24. (-6.,7.) 14.2 (8.,64.)
+
+//  Decoding of complex numbers from an ASCII file
+//  Notice that the << operator can be used instead of ReadASCII
+TArray< complex<r_4> > Z;
+ifstream ifs("zzz.txt");
+ifs >> Z;
+cout << " TArray< complex<r_4> > Z from file zzz.txt " << Z ;
+\end{verbatim}
+
+\noindent {\bf Shared data access :} It is possible to access a complex array 
+elements (real and imaginary parts) through the template functions defined 
+in {\tt arrctcast.h} and discussed above. The example below shows how to use 
+these functions.
+
+\begin{verbatim}
+// We define a complex array 
+TArray< complex<r_4> > za(5);
+cout << " za= " << za;
+// And two real arrays, corresponding to the real and imaginary parts 
+TArray<r_4> rza = SDRealPart(za); 
+TArray<r_4> iza = SDImagPart(za); 
+// We initialize the real and imaginary parts of the complex array 
+rza = RegularSequence(10.,2.);
+iza = RegularSequence(5.,0.75);
+cout << " rza=..., iza=... ----> za = " << za;
+// The complex array seen as a real array (double size)
+TArray<r_4> aza = ArrCastC2R(za);
+cout << " za --> aza= " << aza;
+TArray< complex<r_4> > zb;
+zb = ArrCastR2C(aza);
+KeepObj(zb);
+\end{verbatim}
+
+\subsection{Memory organisation}
+{\tt \tcls{TArray} } can handle numerical arrays with various memory 
+organisation, as long as the spacing (steps) along each axis is 
+regular. The five axis are labeled X,Y,Z,T,U. The examples below
+illustrates the memory location for a 2-dimensional, $N_x=4 \times N_y=3$.
+The first index is along the X axis and the second index along the Y axis.
+\begin{verbatim}
+    | (0,0)  (1,0)  (2,0)  (3,0) |
+    | (0,1)  (1,1)  (2,1)  (3,1) |
+    | (0,2)  (1,2)  (2,2)  (3,2) |
+\end{verbatim}
+In the first case, the array is completely packed 
+($Step_X=1, Step_Y=N_X=4$), with zero offset,
+while in the second case, $Step_X=2, Step_Y=10, Offset=10$:
+\begin{verbatim}
+    | 0  1  2  3  |         | 10 12 14 16 |
+Ex1 | 4  5  6  7  |     Ex2 | 20 22 24 26 |
+    | 8  9  10 11 |         | 30 32 34 36 | 
+\end{verbatim} 
+
+For matrices and vectors, an optional argument ({\tt MemoryMapping}) 
+can be used to select the memory mapping, where two basic schemes 
+are available: \\
+{\tt CMemoryMapping} and {\tt FortranMemoryMapping}. \\
+In the case where {\tt CMemoryMapping} is used, a given matrix line
+is packed in memory, while the columns are packed when 
+{\tt FortranMemoryMapping} is used. The first index when addressing 
+the matrix elements (line number index) runs along
+the Y-axis if  {\tt CMemoryMapping} is used, and along the X-axis
+in the case of {\tt FortranMemoryMapping}. 
+Arithmetic operations between matrices
+with different memory organisation is allowed as long as 
+the two matrices have the same sizes (Number of rows and columns). 
+The following code example and the corresponding output illustrates 
+these two memory mappings. The {\tt \tcls{TMatrix}::TransposeSelf() }
+method changes effectively the matrix memory mapping, which is also 
+the case of {\tt \tcls{TMatrix}::Transpose() } method without argument.
+
+\begin{verbatim}
+BaseArray::SetDefaultMemoryMapping(BaseArray::CMemoryMapping);
+TArray<r_4> X(4,2); 
+X = RegularSequence(1,1);
+cout << "Array X= " << X << endl;
+TMatrix<r_4> X_C(X, true);
+cout << "Matrix X_C (CMemoryMapping) = " << X_C << endl;
+TMatrix<r_4> X_F(X_C, true);
+X_F.TransposeSelf();    // we make it a FortranMemoryMapping matrix
+cout << "Matrix X_F (FortranMemoryMapping) = " << X_F << endl;
+\end{verbatim}
+This code would produce the following output (X\_F = Transpose(X\_C)) :
+\begin{verbatim}
+Array X= 
+--- TArray<f>  ND=2 SizeX*Y*...= 4x2 ---
+1, 2, 3, 4
+5, 6, 7, 8
+
+Matrix X_C (CMemoryMapping) = 
+--- TMatrix<f>(NRows=2, NCols=4) ND=2 SizeX*Y*...= 4x2 ---
+1, 2, 3, 4
+5, 6, 7, 8
+
+Matrix X_F (FortranMemoryMapping) = 
+--- TMatrix<f>(NRows=4, NCols=2) ND=2 SizeX*Y*...= 4x2 ---
+1, 5
+2, 6
+3, 7
+4, 8
+\end{verbatim}
+
+{\bf Note:} Only the {\tt TMatrix} class is sensitive to the memory organisation. It should also 
+be noted that the first index for a matrix is the row index. For a {\tt TArray} object, the first 
+index correspond always to the X axis. For a matrix in the {\tt CMemoryMapping}, the row
+index is the Y index of the corresponding array, while for a matrix 
+with {\tt FortranMemoryMapping}, the row index is the X index.
+\begin{verbatim}
+#  2D array  arr ,  matrix mx
+TArray<r_4> arr; 
+...
+TMatrix<r_4> mx(arr);
+...
+###   CMemoryMapping  :
+mx( row , col ) -> arr( ix=col, jy= row )
+###   FortranMemoryMapping  :
+mx( row , col ) -> arr( ix=row, jy= col )
+\end{verbatim}
+The following code fragment shows the difference between element access 
+index order for the different memory organisation:
+\begin{verbatim}
+   TArray<int_4> a(5,3);
+   a = RegularSequence(10,2);
+   cout << "Array a = " << a << endl;
+   TMatrix<r_4> mac(a);
+   cout << "Matrix mac (CMemoryMapping) = " << mac << endl;
+   TMatrix<r_4> maf(mac);
+   maf.TransposeSelf();    // we make it a FortranMemoryMapping matrix
+   cout << "Matrix maf (FortranMemoryMapping) = " << maf << endl;
+   // ---- element access
+   cout <<  " Array(ix,jy) : a(2,0)= " << a(2,0) << " a(1,2)= " << a(1,2) 
+        <<   "  a(0,2)= " << a(0,2) << endl;
+   cout <<  " mac(row,col) :  mac(2,0)= " << mac(2,0) << " mac(1,2)= " << mac(1,2) 
+        <<   "  mac(0,2)= " << mac(0,2) << endl;
+   cout <<  " maf(row,col) :  maf(2,0)= " << maf(2,0) << " maf(1,2)= " << maf(1,2) 
+        <<   "  maf(0,2)= " << maf(0,2) << endl;
+\end{verbatim}
+
+
+\newpage 
+
+\section{Module HiStats}
+\begin{figure}[hbt]
+\dclsbb{AnyDataObj}{Histo}
+\dclscc{Histo}{HProf}
+\dclsbb{AnyDataObj}{Histo2D}
+\dclsbb{AnyDataObj}{HistoErr}
+\dclsbb{AnyDataObj}{Histo2DErr}
+\caption{partial class diagram for histograms and ntuples}
+\end{figure}
+
+{\bf HiStats} contains classes for creating, filling, printing and
+doing various operations on one or two dimensional histograms
+{\tt Histo} and {\tt Histo2D} as well as profile histograms {\tt HProf}. \\
+This module also contains {\tt NTuple} and {\tt DataTable} which are
+more or less the same as the binary or ascii FITS tables.
+
+\subsection{Histograms}
+\subsubsection{1D Histograms}
+\index{Histo}
+For 1D histograms, various numerical methods are provided such as
+computing means and sigmas, finding maxima, fitting, rebinning,
+integrating \dots \\
+The example below shows creating and filling a one dimensional histogram
+of 100 bins from $-5.$ to $+5.$ to create a Gaussian normal distribution
+with errors~:
+\begin{verbatim}
+#include "histos.h"
+// ...
+Histo H(-0.5,0.5,100);
+H.Errors();
+for(int i=0;i<25000;i++) {
+  double x = NorRand();
+  H.Add(x);
+}
+H.Print(80);
+\end{verbatim}
+
+\subsubsection{2D Histograms}
+\index{Histo2D}
+Much of these operations are also valid for 2D histograms. 1D projection
+or slices can be set~:
+\begin{verbatim}
+#include "histos2.h"
+// ...
+Histo2D H2(-1.,1.,100,0.,60.,50);
+H2.SetProjX(); // create the 1D histo for X projection
+H2.SetBandX(25.,35.); // create 1D histo  projection for 25.<y<35.
+H2.SetBandX(35.,45.); // create 1D histo  projection for 35.<y<45.
+H2.SetBandX(40.,55.); // create 1D histo  projection for 40.<y<55.
+//... fill H2 with what ever you want
+H2.Print();
+Histo *hx = H2.HProjX();
+  hx->Print(80);
+Histo *hbx2 = HBandX(1); // Get the second X band (35.<y<45.)
+  hbx2->Print(80);
+\end{verbatim}
+
+\subsubsection{Profile Histograms}
+\index{HProf}
+Profiles histograms {\bf HProf} contains the mean and the 
+sigma of the distribution
+of the values filled in each bin. The sigma can be changed to
+the error on the mean. When filled, the profile histogram looks
+like a 1D histogram and much of the operations that can be done on 1D histo
+may be applied onto profile histograms.
+
+\subsubsection{Histograms HistoErr and Histo2DErr}
+\index{HistoErr}
+The {\bf HistoErr} are basic histograms where the number of entries for each bin is kept.
+Methods to compute of the mean and the variance in each bin are provided.
+The {\bf Histo2DErr} is the same for $2$ dimensions.
+
+\subsection{Data tables (tuples)}
+\begin{figure}[hbt]
+\dclsbb{AnyDataObj}{NTuple}
+\dclsccc{AnyDataObj}{BaseDataTable}{DataTable}
+\dclscc{BaseDataTable}{SwPPFDataTable}
+\end{figure}
+
+\subsubsection{NTuple}
+\index{NTuple}
+{\bf NTuple} are memory resident tables of 32 or 64 bits floating values 
+(float/double).They are arranged in columns. Each line is often called an event.
+These objects are frequently used to analyze data.
+The piapp graphicals tools can plot a column against an other one
+with respect to various selection cuts. \\
+Here is an example of creation and filling~:
+\begin{verbatim}
+#include "ntuple.h"
+#include "srandgen.h"
+// ...
+char* nament[4] = {"i","x","y","ey"};
+r_4 xnt[4];
+NTuple NT(4,nament);
+for(i=0;i<5000;i++) {
+  xnt[0] = i+1;
+  xnt[1] = 5.*drandpm1();       // a random value between -5 and +5
+  xnt[2] = 100.*exp(-0.5*xnt[1]*xnt[1]) + 1.;
+  xnt[3] = sqrt(xnt[2]);
+  xnt[2] += xnt[3] * NorRand(); // add a random gaussian error
+  NT.Fill(xnt);
+}
+\end{verbatim}
+
+{\bf XNTuple} provide additional functionalities, compared to NTuple. However,
+this class is deprecated and superseded by classes inheriting from  BaseDataTable.
+It is only kept  for backward compatibility and should not be used anymore. 
+Use DataTable and  SwPPFDataTable instead. 
+Object of type XNTuple handle various types
+of column values (double,float,int,string,...) and can handle
+very large data sets, through swap space on disk. 
+
+\subsubsection{DataTables}
+\label{datatables}
+\index{DataTable} 
+The class {\bf DataTable} extends significantly the functionalities provided by 
+NTuple. DataTable is a memory resident implementation of the interface 
+{\bf BaseDataTable } which organizes the data as a 2-D table. User can define
+the name and data type of each column. Data is added to the table as rows.
+The table is extended as necessary when adding rows. 
+The sample code below shows an example of DataTable usage :
+\begin{verbatim}
+   #include "datatable.h"
+   // ...
+   {
+   DataTable dt(64);
+   dt.AddFloatColumn("X0_f");
+   dt.AddFloatColumn("X1_f");
+   dt.AddDoubleColumn("X0X0pX1X1_d");
+   double x[5];
+   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];
+     dt.AddLine(x);
+   }
+   // Printing table info
+   cout << dt ;
+   // Saving object into a PPF file
+   POutPersist po("dtable.ppf");
+   po << dt ;
+   }
+\end{verbatim}
+
+
+\index{SwPPFDataTable}
+The class {\bf SwPPFDataTable} implements the BaseDataTable interface
+using segmented data blocks with swap on PPF streams. Very large data sets
+can be created and manipulated through this class. A similar class
+SwFitsDataTable (\ref{SwFitsDataTable}), using 
+FITS files as swap space is also provided in the FitsIOServer module.
+
+\index{DataTableRow}
+The class {\bf DataTableRow } is an auxiliary class which simplifies the manipulation
+of BaseDataTable object rows. 
+The example below show how to create and filling a table, using a PPF stream as 
+swap space. In addition, we have used a {\tt DataTableRow} to prepare data 
+for  each table line.
+\begin{verbatim}
+   #include "swppfdtable.h"
+   // ...
+   {
+   // ---------- Create an output PPF stream (file)
+   POutPersist po("swdtable.ppf");
+   // ------------------
+   // Create a table with 3 columns, using the above stream as swap space
+   SwPPFDataTable dtrow(po, 64);
+   dtrow.AddStringColumn("sline");
+   dtrow.AddIntegerColumn("line");
+   dtrow.AddDateTimeColumn("datime");   
+   //
+   TimeStamp ts, ts2;  // Initialize current date and time
+   string sline;
+   //---- Create a table row with the required structure
+   DataTableRow row = dtrow.EmptyRow();
+   // ----- Fill the table
+   for(int k = 0; k<2500; k++) {
+     sline = "L-";
+     sline += (string)MuTyV(k);
+     row["sline"] = sline;
+     row[1] = k;
+     ts2.Set(ts.ToDays()+(double)k);
+     row["datime"] = ts2;
+     dtrow.AddRow(row);
+  }
+  //------ Write the table itself to the stream, before closing the file
+  po << PPFNameTag("SwTable") << dtrow;
+  }
+\end{verbatim}
+%%
+The  previously created table can easily be read in, as shown below:
+%%
+\begin{verbatim}
+   #include "swppfdtable.h"
+   // ...
+   {
+   // ------ Create the input  PPF stream (file)
+   PInPersist pin("swdtable.ppf");
+   // ------ Read in the SwPPFDataTable object 
+   SwPPFDataTable dtr;
+   pin >> PPFNameTag("SwTable") >> dtr;
+   // ---- Create a table row with the required structure
+   DataTableRow row = dtr.EmptyRow();
+   // ---- Acces and print two of the table rows :
+   cout << dtr.GetRow(6, row) << endl;
+   cout << dtr.GetRow(17, row) << endl;   
+  }
+\end{verbatim}
+   
+\subsection{Writing, viewing \dots }
+%%
+Histogram and NTuple/DataTable objects have PPF handlers and 
+can be written to or read from PPF files. Sophya graphical tool (spiapp) can 
+automatically display and operate on all these objects.
+The following example shows how to write the previously created objects
+into such a file~:
+\begin{verbatim}
+{
+char *fileout = "myfile.ppf";
+string tag;
+POutPersist outppf(fileout);
+tag = "H";   outppf.PutObject(H,tag);
+tag = "H2";   outppf.PutObject(H2,tag);
+tag = "NT";   outppf.PutObject(NT,tag);
+}  // closing ``}'' destroy ``outppf'' and automatically close the file !
+\end{verbatim}
+
+\newpage
+\section{Module NTools}
+
+This module provides elementary numerical tools for numerical integration,
+fitting, sorting and ODE solving. FFTs are also provided (Mayer,FFTPack).
+
+\subsection{Fitting}
+\index{Fitting} \index{Minimisation}
+Fitting is done with two classes {\tt GeneralFit} and {\tt GeneralFitData}
+and is based on the Levenberg-Marquardt method.
+\index{GeneralFit} \index{GeneralFitData}
+GeneralFitData is a class which provide a description of the data
+to be fitted. GeneralFit is the fitter class. Parametrized functions
+can be given as classes which inherit {\tt GeneralFunction}
+or as simple C functions. Classes of pre-defined functions are provided
+(see files fct1dfit.h and fct2dfit.h). The user interface is very close
+from that of the CERN {\tt Minuit} fitter.
+Number of objects (Histo, HProf \dots ) are interfaced with GeneralFit
+and can be easily fitted. \\
+Here is a very simple example for fitting the previously created NTuple
+with a Gaussian~:
+\begin{verbatim}
+#include "fct1dfit.h"
+// ...
+
+// Read from ppf file
+NTuple nt;
+{
+PInPersist pis("myfile.ppf");
+string tag = "NT";  pis.GetObject(nt,tag);
+}
+
+// Fill GeneralData
+GeneralData mGdata(nt.NEntry());
+for(int i=0; i<nt.NEntry(); i++)
+  mGdata.AddData1(xnt[1],xnt[2],xnt[3]); // Fill x, y and error on y
+mGData.PrintStatus();
+
+// Function for fitting : y = f(x) + noise
+Gauss1DPol mFunction; // gaussian + constant
+
+// Prepare for fit
+GeneralFit mFit(&mFunction);  // create a fitter for the choosen function
+mFit.SetData(&mGData);        // connect data to the fitter
+
+// Set and initialise the parameters (that's non-linear fitting!)
+//           (num par, name, guess start, step, [limits min and max])
+mFit.SetParam(0,"high",90.,1..);
+mFit.SetParam(1,"xcenter",0.05,0.01);
+mFit.SetParam(2,"sigma",sig,0.05,0.01,10.);
+                              // Give limits to avoid division by zero
+mFit.SetParam(3,"constant",0.,1.);
+
+// Fit and print result
+int rcfit = mFit.Fit();
+mFit.PrintFit();
+if(rcfit>0) {)
+  cout<<"Reduce_Chisquare = "<<mFit.GetChi2Red()
+      <<" nstep="<<mFit.GetNStep()<<" rc="<<rcfit<<endl;
+} else {
+  cout<<"Fit_Error, rc = "<<rcfit<<"  nstep="<<mFit.GetNStep()<<endl;
+  mFit.PrintFitErr(rcfit);
+}
+
+// Get the result for further use
+TVector<r_8> ParResult = mFit.GetParm();
+cout<<ParResult;
+\end{verbatim}
+
+Much more usefull possibilities and detailed informations might be found
+in the HTML pages of the Sophya manual.
+
+\subsection{Simplex method}
+The class {\bf MinZSimplex} implements the simplex method for non linear 
+optimization / minimization. See the SOPHYA manual for more information.
+
+\subsection{Polynomial}
+\index{Polynomial} \index{Poly} \index{Poly2}
+Polynomials of 1 or 2 variables are supported ({\tt Poly} and {\tt Poly2}).
+Various operations are supported~:
+\begin{itemize}
+\item elementary operations between polynomials $(+,-,*,/) $
+\item setting or getting coefficients
+\item computing the value of the polynomial for a given value
+      of the variable(s),
+\item derivating
+\item computing roots (degre 1 or 2)
+\item fitting the polynomial to vectors of data.
+\end{itemize}
+Here is an example of polynomial fitting~:
+\begin{verbatim}
+#include "poly.h"
+// ...
+Poly pol(2);
+pol[0] = 100.; pol[1] = 0.; pol[2] = 0.01; // Setting coefficients
+TVector<r_8> x(100);
+TVector<r_8> y(100);
+TVector<r_8> ey(100);
+for(int i=0;i<100;i++) {
+  x(i)  = i;
+  ey(i) = 10.;
+  y(i)  = pol((double) i) + ey(i)*NorRand();
+  ey(i) *= ey(i)
+}
+
+TVector<r_8> errcoef;
+Poly polfit;
+polfit.Fit(x,y,ey,2,errcoef);
+
+cout<<"Fit Result"<<polfit<<endl;
+cout<<"Errors :"<<errcoef;
+\end{verbatim}
+
+Similar operations can be done on polynomials with 2 variables.
+
+\subsection{Integration, Differential equations}
+\index{Integration}
+The NTools module provide also simple classes for numerical integration 
+of functions and differential equations.
+\begin{figure}[hbt]
+\dclsbb{Integrator}{GLInteg}
+\dclsb{TrpzInteg}
+\end{figure}
+
+\index{GLInteg} \index{TrpzInteg}
+{\bf GLInteg} implements the integration through Gauss-Legendre method
+and {\bf TrpzInteg} implements trapeze integration. For {\bf TrpzInteg},
+number of steps specify the number of trapeze, and integration step, 
+their width.
+The sample code below illustrates the use of TrpzInteg class:
+\begin{verbatim}
+#include "integ.h"
+// ......................................................
+// Function to be integrated
+double myf(double x)
+{
+// Simple a x + b x^2  (a=2 b=3)
+return (x*(2.+3.*x));
+}
+// ......................................................
+
+// Compute Integral(myf, 2., 5.) between xmin=2., xmax=5.
+TrpzInteg trpz(myf, 2., 5.);
+// We specify an integration step
+trpz.DX(0.01);
+// The integral can be computed as trpz.Value() 
+double myf_integral = trpz.Value();
+// We could have used the cast operator :
+cout << "Integral[myf, 2., 5.]= " << (double)trpz << endl;
+// Limits can be specified through ValueBetween() method 
+cout << "Integral[myf, 0., 4.]= " << trpz.ValueBetween(0.,4.) << endl;
+\end{verbatim}
+
+\subsection{Fourier transform (FFT)}
+\index{FFT} \index{FFTPackServer}
+An abstract interface for performing FFT operations is defined by the 
+{\bf FFTServerInterface} class. The {\bf FFTPackSever} class implements
+one dimensional FFT, on real and complex data. FFTPackServer uses an
+adapted and extended version of FFTPack (available from netlib), 
+translated in C, and can operate on single and double precision
+({\tt float, double}) data.
+
+The sample code below illustrates the use of FFTServers:
+\begin{verbatim}
+#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;
+\end{verbatim}
+
+% \newpage
+\section{Module SUtils}
+Some utility classes and C/C++ string manipulation functions are gathered
+in {\bf SUtils} module.
+\subsection{Using DataCards}
+\index{DataCards}
+The {\bf DataCards} class can be used to read parameters from a file.
+Each line in the file starting with \@ defines a set of values
+associated with a keyword. In the example below, we read the 
+parameters corresponding with the keyword {\tt SIZE} from the 
+file {\tt ex.d}. We suppose that {\tt ex.d} contains the line: \\
+{\tt @SIZE 400 250} \\
+\begin{verbatim}
+#include "datacards.h"
+// ...
+// Initialising DataCards object dc from file ex.d
+DataCards dc( "ex.d" );
+// Getting the first and second parameters for keyword size
+// We define a default value 100
+int size_x = dc.IParam("SIZE", 0, 100);
+int size_y = dc.IParam("SIZE", 1, 100);
+cout << " size_x= " << size_x << " size_y= " << size_y << endl;
+\end{verbatim}
+ 
+\section{Module SysTools}
+The {\bf SysTools} module contains classes implementing interface to some 
+OS specific services, such as thread creation and management, dynamic loading and 
+resource usage information. For example, yhe class {\bf Periodic} provides the 
+necessary services needed to implement the execution of a periodic action.
+
+\subsection{Resource usage (CPU, memory \ldots) }
+ The class {\bf ResourceUsage} \index{ResourceUsage}
+and {\bf Timer} \index{Timer} provides access to information 
+about various resource usage (memory, CPU, ...).
+The class {\bf Timer} \index{time (CPU, elapsed)} and c-functions
+{\tt InitTim() , PrtTim(const char * Comm) } can be used to print 
+the amount of CPU and elapsed time in programs.
+
+The following sample code illustrates the use of {\bf ResourceUsage} :
+\begin{verbatim}
+  // 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;
+\end{verbatim}
+
+\subsection{Thread management classes}
+\index{ZThread} \index{ZMutex} 
+A basic interface to POSIX threads is also provided
+through the \index{threads} {\bf ZThread}, {\bf ZMutex} and {\bf ZSync}
+classes. The best way to use thread management classes is by inheriting
+from {\bf ZThread} and redefining the {\tt run() } method. 
+It is also possible to use the default {\tt run() } implementation and associate 
+a function to perform the action, as in the example below :
+\begin{verbatim}
+  // 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();
+\end{verbatim}
+The classes {\bf ZMutex} \index{mutex} and {\bf ZSync} can be used 
+to perform synchronisation and signaling between threads.
+Example multithread programs using these classes can be found in
+the {\bf Tests} module : \\
+\hspace{10mm} {\tt zthr.cc  , tmtdt.cc , tmtrnd.cc }
+
+\subsection{Dynamic linker and C++ compiler classes}
+\index{PDynLinkMgr}
+The class {\bf PDynLinkMgr} can be used for managing shared libraries
+at run time. The example below shows the run time linking of a function:\\
+{\tt extern "C" { void myfunc(); } } \\
+\begin{verbatim}
+#include "pdlmgr.h"
+// ...
+string soname = "mylib.so";
+string funcname = "myfunc";
+PDynLinkMgr dyl(soname);
+DlFunction f = dyl.GetFunction(funcname); 
+if (f != NULL) { 
+// Calling the function 
+  f();    
+}
+\end{verbatim}
+
+\index{CxxCompilerLinker}
+The {\bf CxxCompilerLinker} class provides the services to compile C++ code and building 
+shared libraries, using the same compiler and options which have 
+been used to create the SOPHYA shared library. 
+The sample program below illustrates using this class to build
+the shared library (myfunc.so) from the source file myfunc.cc :
+\begin{verbatim}
+#include "cxxcmplnk.h"
+// ...
+string flnm = "myfunc.cc";
+string oname, soname;
+int rc;
+CxxCompilerLinker cxx;
+// The Compile method provides a default object file name
+rc = cxx.Compile(flnm, oname);
+if (rc != 0 ) { // Error when compiling ... }
+// The BuildSO method provides a default shared object file name
+rc = cxx.BuildSO(oname, soname);
+if (rc != 0 ) { // Error when creating shared object ... }
+\end{verbatim}
+
+\subsection{Command interpreter}
+\index{Commander}
+\index{Expression evaluation}
+The class {\bf Commander} can be used in interactive programs to provide
+c-shell like command interpreter and scripting capabilties. 
+Arithmetic expression evaluation is implemented through the {\bf CExpressionEvaluator}
+and {\bf RPNExpressionEvaluator} classes. The latter can be used to perform evaluation
+in reverse polish notation (old HP calculators), 
+while the former uses the usual algebraic (c-language like) expressions.
+The command language provides variable manipulation through the usual 
+{\tt \$varname} vector variable and arithmetic expression extensions, as well 
+as the control and test blocs. 
+\begin{verbatim}
+#include "commander.h"
+...
+Commander cmd;
+char* ss[3] = {"foreach f ( AA bbb CCCC ddddd )", "echo $f" , "end"};
+for(int k=0; k<3; k++) {
+  string line = ss[k];
+  cmd.Interpret(line);
+}
+\end{verbatim}
+ 
+\newpage
+\section{Module SkyMap}
+\begin{figure}[hbt]
+\dclsbb{AnyDataObj}{PixelMap}
+\dclsccc{PixelMap}{Sphericalmap}{SphereHEALPix}
+\dclsc{SphereThetaPhi}
+\dclsc{SphereECP}
+\dclsb{LocalMap}
+\caption{partial class diagram for spherical map classes  in Sophya}
+\end{figure}
+The {\bf SkyMap} module provides classes for creating, filling, reading pixelized spherical  and 2D-maps. The types of values stored in pixels can be int, float, double , complex etc. according to the specialization of the template type. 
+\subsection{3D geometry}
+Some of the classes in this module simplify the angle manipulation, or the 3D geometry
+and rotation calculations, such as the {\bf Vector3d} and {\bf UnitVector} classes.
+\index{Vector3d}
+The classes {\bf Vector3d} and {\bf UnitVector}  are useful for angle conversions.
+\index{Angle}
+{\bf LongLat} class and {\bf Angle} class (defined in file vector3d.h) can be used for
+angle conversions :
+\begin{verbatim}
+   // Example to convert 0.035 radians to arcsec
+   double vr = 0.035;
+   cout << "Angle rad= " << vr << " ->arcsec= " << Angle(vr).ToArcSec() << endl;
+   // Example to convert 2.3 arcmin to radian - we use the conversion operator
+   double vam = 2.3;
+   cout << "Angle arcmin= " << vam << " ->rad= " 
+        << (double)Angle(vam, Angle::ArcMin) << endl;
+\end{verbatim}
+%%%
+\subsection {Spherical maps}
+SkyMap module provides three classes for representing data with pixels distributed over complete ($4 \pi$ steradians) spheres. These classes implements the common interface defined 
+in the base class \tcls{SphericalMap} with three different algorithms or 
+pixelization scheme. 
+The spherical maps can be instanciated for the followind data types: \\
+\hspace*{5mm} int\_4 , r\_4 (float) , r\_8 (double) , complex$<$r\_4$>$ , complex$<$r\_8$>$. \\
+The SphereHEALPix can in addition be instanciated for T=uint\_2.
+
+\begin{enumerate}
+\item \index{\tcls{SphereHEALPix}} 
+{\bf \tcls{SphereHEALPix}} implements the HEALPix 
+({\bf H}ierarchical {\bf E}qual {\bf A}rea iso{\bf L}atitude {\bf Pix}elization) scheme, 
+developped originaly by K. Gorski \& E. Hivon. Refer to 
+\href{http://healpix.jpl.nasa.gov/}{HEALPix home page} for 
+detailed information about this pixelisation scheme and related software
+\footnote{HEALPix home page: http://healpix.jpl.nasa.gov/ }.
+FITS read/write for SphereHEALPix objects is handled by the \tcls{FITS\_SphereHEALPix}
+class in module FitsIOServer.
+\item \index{\tcls{SphereThetaPhi}} 
+{\bf \tcls{SphereThetaPhi}} represents spheres pixelized following an algorithm 
+developed at LAL-ORSAY, for SOPHYA. 
+The sphere is divided into a number of rings or slices
+along the parallels, corresponding to different values of the angle $\theta$.
+Each slice is then divided into a number of pixels, with an aspect ratio close 
+to one (square pixels). Pixels are exactly iso-latitude and very uniform in surface,
+over the sphere. 
+
+\item \index{\tcls{SphereECP}}
+
+The {\bf \tcls{SphereECP}} class correspond to the cylindrical projection.
+Like SphereThetaPhi class, the sphere is divided into a number of rings
+or slices, and each ring is divided into a constant number of pixels
+along the $\varphi$ direction. Although the \tcls{SphereECP} does not have 
+equal area pixels when used for complete spheres, it can be used for 
+representing partial or full spherical maps. 
+\end{enumerate}
+
+The example below shows creating and filling of a 
+SphereHEALPix with nside = 8 
+(The sphere will have $12 \times 8 \times 8= 768$ pixels) :
+
+\begin{verbatim}
+#include "spherehealpix.h"
+// ...
+SphereHEALPix<double> sph(8);
+for (int k=0; k< sph.NbPixels(); k++) sph(k) = (double)(10*k);
+\end{verbatim}
+
+Pixels at an angular posistion can be directly accessed through the operator \\
+\hspace*{15mm} T \tcls{SphericalMap}::operator()($\theta, \varphi$) :
+\begin{verbatim}
+#include "vector3d.h"
+#include "spherethetaphi.h"
+...
+// Create a sphere with 40 arcmin resolution
+int M = SphereThetaPhi<r_4>::ResolToSizeIndex(
+        Angle(40., Angle::ArcMin).ToRadian() );
+SphereThetaPhi<r_4> sphtp(M);
+double tet, phi;
+for (int k=0; k< sphtp.NbPixels(); k++) {
+  sphtp.PixThetaPhi(k, tet, phi);
+  sphtp(k) = cos(5.*tet)*sin(7.*phi);
+}
+cout << sphtp;
+// To save sphtp to file sphtp (if executed through runcxx)
+KeepObj(sphtp);
+\end{verbatim}
+
+\index{\tcls{SphereThetaPhi}}
+
+\subsection {Local maps}
+\index{\tcls{LocalMap}}
+A local map is a 2 dimensional array, with i as column index and j as row index. The map is supposed to lie on a plan tangent to the celestial sphere in a point whose coordinates are (x0,y0) on the local map and (theta0, phi0) on the sphere. The range of the map is defined by two values of angles covered respectively by all the pixels in x direction and all the pixels in y direction (SetSize()). Default value of (x0, y0) is middle of the map, center of pixel(nx/2, ny/2).
+
+Internally, a map is first defined within this reference plane and tranported until the point (theta0, phi0) in such a way that both axes are kept parallel to meridian and parallel lines of the sphere. The user can define its own map with axes rotated with respect to reference axes (this rotation is characterized by angle between the local parallel line and the wanted x-axis-- method SetOrigin(...))
+
+The example below shows creating and filling of a LocalMap with 4 columns and 5 rows. The origin is set to default. The map covers a sphere portion defined by two angles of 30. degrees (methods \textit{SetOrigin()} and \textit{SetSize()} must be called in order to completely define the map).
+\begin{verbatim}
+#include "localmap.h"  
+//..............       
+  LocalMap<r_4> locmap(4,5);
+  for (int k=0; k<locmap.NbPixels();k++) locmap(k)=10.*k;
+  locmap.SetOrigin();
+  locmap.SetSize(30.,30.);
+\end{verbatim}
+
+\subsection{Writing, viewing \dots }
+
+All these objects have been design to be written to or read from a persistant file.
+The following example shows how to write the previously created objects
+into such a file~:
+\begin{verbatim}
+//-- Writing
+
+#include "fiospherehealpix.h" 
+//................
+
+char *fileout = "myfile.ppf";
+POutPersist outppf(fileout);
+FIO_SphereHEALPix<r_8> outsph(sph);
+outsph.Write(outppf);
+FIO_LocalMap<r_8> outloc(locmap);
+outloc.Write(outppf);
+// It is also possible to use the << operator
+POutPersist os("sph.ppf");
+os << outsph;
+os << outloc;
+\end{verbatim}
+
+Sophya graphical tools (spiapp) can automatically display and operate
+all these objects.
+
+\newpage
+\section{Samba and SkyT}
+\subsection{Samba}
+\index{Spherical Harmonics}
+\index{SphericalTransformServer}
+The module provides several classes for spherical harmonic analysis. The main class is \textit{SphericalTranformServer}. It contains methods for analysis and synthesis of spherical maps. The following example fills a vector of Cl's, generate a spherical map from these Cl's. This map is analysed back to Cl's...
+\begin{verbatim}
+#include "skymap.h"
+#include "samba.h"
+....................
+
+// 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.);
+\end{verbatim}
+
+\subsection{Module SkyT}
+\index{RadSpectra} \index{SpectralResponse} 
+The SkyT module is composed of two types of classes:
+\begin{itemize}
+\item{} one which corresponds to an emission spectrum of
+radiation, which is called RadSpectra
+\item{} one which corresponds to the spectral response
+of a given detector (i.e. corresponding to a detector
+filter in a given frequency domain), which is called
+SpectralResponse.
+\end{itemize}
+\begin{figure}[hbt]
+\dclsbb{RadSpectra}{RadSpectraVec}
+\dclsb{BlackBody}
+\dclsccc{AnyDataObj}{SpectralResponse}{SpecRespVec}
+\dclsc{GaussianFilter}
+\caption{partial class for SkyT module}
+\end{figure}
+
+\begin{verbatim}
+#include "skyt.h"
+// ....
+// Compute the flux from a blackbody at 2.73 K through a square filter
+BlackBody myBB(2.73);
+// We define a square filter from 100 - 200 GHz
+SquareFilter mySF(100,200);
+// Compute the filtered integrated flux :
+double flux = myBB.filteredIntegratedFlux(mySF);
+\end{verbatim}
+
+A more detailed description of SkyT module can be found in: 
+{\it The SkyMixer (SkyT and PMixer modules) - Sophya Note No 2. }
+available also from Sophya Web site.
+
+\newpage
+\section{Module FitsIOServer}
+This module provides classes for handling file input-output in FITS 
+\footnote{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html} 
+format using the cfitsio library. Its
+design is similar to  the SOPHYA persistence (see Module BaseTools). 
+Delegate classes or handlers perform the actual read/write from/to fits files. 
+\par
+Compared to the SOPHYA native persistence (PPF format),
+FITS format has the advantage of being used extensively, and handled 
+by a many different software tools. It is a de facto standard in 
+astronomy and astrophysics. 
+However, FITS lacks some of the features present in SOPHYA PPF, and although 
+many SOPHYA objects can be saved in FITS files, FITS persistence has 
+some limitations. For example, FITS does not currently handle complex arrays.
+\subsection{FITS streams}
+\index{FITS} \index{FitsInOutFile} 
+%%
+The class {\bf FitsInOutFile} can be seen as a wrapper class for the cfitsio library functions.  
+This class has been introduced in 2005 (V=1.9), when the module has been 
+extensively  changed. In order to keep backward compatibility, the old fits wrapper 
+classes ({\bf  FitsFile, FitsInFile, FitsOutFile}) has been changed to inherit from
+ {\bf FitsInOutFile}.  The use of class FitsFile and specific services of these old classes 
+ should  be avoided, but FitsInFile, FitsOutFile can be safely considered a specialisation
+ of FitsInOutFile for read/input and write/output operations respectively.
+ Most c-fitsio errors are converted to an exception: {\bf FitsIOException}.
+ \par
+ File names are passed to cfitsio library. It is thus possible to use cfitsio file name conventions,
+ such as {\bf ! } as the first character, for overwriting existing files (when creating files).
+ The diagram below shows the class hierarchy for cfitsio wrapper classes.
+\begin{figure}[hbt]
+\dclsa{FitsInOutFile}
+\dclscc{FitsFile}{FitsInFile}
+\dclscc{FitsFile}{FitsOutFile}
+\end{figure}
+%%%%
+\subsection{FITS handlers and I/O operators}
+\index{FitsManager}
+Handlers classes inheriting from {\bf FitsHandlerInterface} perform write/read operations
+for AnyDataObj objects to/from FitsInOutFile streams. The {\bf FitsManager} class provides
+top level services for object read/write in FITS files. 
+\par  In most cases, 
+\hspace{5mm} {\tt FitsInOutFile\& $<<$ } \, and \,  {\tt FitsInOutFile\& $>>$ } \hspace{5mm}
+operators can be used to write and read objects.  
+When reading objects from a fits file using the {\tt FitsInOutFile\& $>>$ } operator, 
+the fits file is positioned on the next HDU, after reading. Also, if the {\bf FitsInOutFile}
+object is positioned on a first empty HDU (without data, naxis=0), reading in objects
+corresponding to a binary or ascii table using the operator $>>$  will skip automatically 
+the empty HDU and position the fits file on the second HDU, before trying to read in
+the object.
+\par
+The two main types of fits data structures, images and tables 
+{\tt (IMAGE\_HDU , BINARY\_TBL , ASCII\_TBL)} are handled by the generic handlers: \\
+{\bf \tcls{FitsArrayHandler}}  and {\bf FitsHandler$<$BaseDataTable$>$}.  
+\par
+A number of more specific handlers are also available, in particular for NTuple,
+\tcls{SphereHealPix} and \tcls{SphereThetaPhi}.  \\[2mm]
+{\bf Warning:} Some handlers were written with the old FitsIOServer classes.
+They  inherit from the intermediate class {\bf FitsIOHandler} and
+have been adapted to the new scheme. \\[2mm] 
+%%%
+The examples below illustrates the usage of FitsIOServer classes. They can be compiled
+and executed using runcxx, without the {\tt include} lines: \\[1mm]
+\hspace*{5mm} {\tt csh> runcxx -import SkyMap -import FitsIOServer -inc fiosinit.h } 
+%%%
+\begin{enumerate}
+\item Saving an array and a HealPix map to a Fits file
+\begin{verbatim}
+#include "fitsioserver.h"
+#include "fiosinit.h"
+// ....
+{
+// Make sure FitsIOServer module is initialised :
+FitsIOServerInit();
+//  Create and open a fits file named myfile.fits
+FitsInOutFile fos("myfile.fits", FitsInOutFile ::Fits_Create);
+// Create and save a 15x11 matrix of integers
+TMatrix<int_4> mxi(15, 11);
+mxi = RegularSequence(10.,10.);
+fos << mxi;
+// Save a HEALPix spherical map using FitsManager services 
+SphereHEALPix<r_8> sph(16);
+sph = 48.3;
+FitsManager::Write(fos, sph);
+// --- The << operator could have been used instead :    fos << sph;
+}
+\end{verbatim}
+%%%%
+%%%%
+\item Reading objects and the header from the previously created fits file:
+\begin{verbatim}
+{
+FitsIOServerInit();   //  Initialisation 
+// ----  Open the fits file named myfile.fits
+FitsInFile fis("myfile.fits");
+//---- print file information on cout
+cout << fis << endl;
+//--- Read in the array 
+TArray<int_4> arr; 
+fis >> arr;
+arr.Show();
+//--- Position on second HDU 
+fis.MoveAbsToHDU(2);
+//--- read and display header information
+DVList hdu2;
+fis.GetHeaderRecords(hdu2, true, true);
+cout << hdu2;
+//--- read in the HEALPix map 
+SphereHEALPix<r_8> sph;
+FitsManager::Read(fis, sph);
+// --- The >> operator could have been used instead :    fis >> sph;
+sph.Show();
+}
+\end{verbatim}
+%%%%%%%
+%%% 
+\item DataTable objects can be read from and written to FITS files as ASCII or
+binary tables. The example belo show reading the DataTable created in the example
+in section \ref{datatables} from a PPF file and saving it to a fits file.
+\begin{verbatim}
+#include "swfitsdtable.h"
+// ....
+{
+FitsIOServerInit();   //  FitsIOServer Initialisation 
+//--- Reading in DataTable object from PPF file
+PInPersist pin("dtable.ppf");
+DataTable dt;
+pin >> dt;
+dt.Show(); 
+//--- Saving table to FITS
+FitsInOutFile fos("!dtable.fits", FitsInOutFile ::Fits_Create);
+fos << dt;
+}
+\end{verbatim}
+%%%%
+\end{enumerate}
+%%%
+A partial class diagram of FITS persistence handling classes is shown below. The 
+class {\tt FitsIOhandler} conforms to the old FitsIOServer module design and 
+should not be used anymore. 
+\begin{figure}[hbt]
+\dclsbb{FitsHandlerInterface}{FitsArrayHandler$<$T$>$}
+\dclsb{\tcls{FitsHandler}}
+\dclscc{FitsIOhandler}{FITS\_NTuple}
+\dclsc{FITS\_SphereHEALPix}
+% \dclsb{FITS\_LocalMap}
+\end{figure}
+
+\subsection{SwFitsDataTable and other classes}
+\label{SwFitsDataTable}
+\index{SwFitsDataTable} 
+The {\bf SwFitsDataTable} class implements the BaseDataTable interface
+using a FITS file as swap space. Compared to SwPPFDataTable, they can be 
+used in R/W mode (reading from the table, when it is being created / filled).
+They can be used in a way similar to DataTable and SwPPFDataTable. 
+When creating the table, a {\tt FitsInOutFile } stream, opened for writing has
+to be passed to the creator. No further operation is needed. 
+\begin{verbatim}
+// ....
+FitsInOutFile so("!myswtable.fits", FitsInOutFile::Fits_Create);
+SwFitsDataTable dt(so, 16);
+// define table columns
+dt.AddIntegerColumn("X0_i");
+dt.AddFloatColumn("X1_f");
+// ... Fill the table
+r_8 x[5];
+for(int i=0; i<63; i++) {
+    x[0] = (i%9)-4.;  x[1] = (i/9)-3.;  
+    dt.AddLine(x);
+}
+\end{verbatim}
+The class {\bf FitsBTNtuIntf } provide an alternative tool to read FITS tables. 
+{\bf FitsABTColRd} , {\bf FitsABTWriter } and {\bf FitsImg2DWriter } can also 
+be used to manipulate FITS files.
+\par 
+The {\bf scanfits} program can be used to check FITS files and analyse their
+content (See \ref{scanfits}).
+
+%%%%   
+\newpage
+\section{LinAlg and IFFTW modules}
+An interface to use LAPACK library (available from {\tt http://www.netlib.org})
+is implemented by the {\bf LapackServer} class, in module LinAlg.
+\index{LapackServer}.
+The sample code below shows how to use SVD (Singular Value Decomposition)
+through LapackServer:
+\begin{verbatim}
+#include "intflapack.h"
+// ...
+// Use FortranMemoryMapping as default
+BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+// Create an fill the arrays A and its copy AA
+int n = 20;
+Matrix A(n , n), AA;
+A = RandomSequence(RandomSequence::Gaussian, 0., 4.);  
+AA = A;  // AA is a copy of A
+// Compute the SVD decomposition
+Vector S;  // Vector of singular values
+Matrix U, VT;
+LapackServer<r_8> lpks;
+lpks.SVD(AA, S, U, VT);
+// We create a diagonal matrix using S
+Matrix SM(n, n); 
+for(int k=0; k<n; k++) SM(k,k) = S(k);
+// Check the result : A = U*SM*VT
+Matrix diff = U*(SM*VT) - A;
+double min, max;
+diff.MinMax(min, max);
+cout << " Min/Max difference Matrix (?=0) , Min= " << min 
+     << " Max= " << max << endl;
+\end{verbatim}
+
+\index{FFTWServer}
+The {\bf FFTWServer} class (in module FFTW) implements FFTServerInterface class 
+methods, for one dimensional and multi-dimensional Fourier 
+transforms  using the FFTW package (available from {\tt http://www.fftw.org}).
+Depending on the configuration options during library build, only 
+transforms on double precision data might be available.
+
+\newpage
+\section{Building and installing Sophya}
+\subsection{Supported platforms}
+Presently, the Sophya library has been tested with the following
+compiler/platform pairs:
+
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline
+OS & compiler \\
+\hline
+Linux (32 bits)          &     g++  (3.x \, 4.0)  \\
+Linux  (SCL, 32)          &     icc - Intel compiler (9.0)   \\
+Linux  (SCL, 64)          &     g++  3.3 \, 3.4  \\
+MacOSX/Darwin (PowerPC) 10.3 \, 10.4  &         g++ (3.3  \, 4.0)\\
+MacOSX/Darwin (Intel) 10.4  &         g++ (4.0)\\
+HP/Compaq/DEC Tru64 ( OSF1)  &     cxx  (6.1  6.3)  \\
+SGI IRIX64       &     CC   (7.3)   \\
+IBM AIX (5.3)      &     xlC   (8.0)   \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsection{Library and makefile structure}
+% 
+The object files from a given Sophya module are grouped in an archive library 
+with the module's name ({\tt libmodulename.a}). All Sophya modules 
+ are grouped in a single shared library ({\tt libsophya.so}), while the 
+modules with reference to external libraries are grouped in 
+({\tt libextsophya.so}). The {\bf PI} and {\bf PIext} modules are 
+grouped in ({\tt libPI.so}).
+Alternatively, it is possible to group all modules in a single shared 
+library {\tt libAsophyaextPI.so}.
+\par 
+Each library module has a {\tt Makefile} which compiles the source files
+and build the correspond static (archive) library using the compilation
+rules and flags defined in \\ 
+\hspace*{5mm} {\tt \$SOPHYABASE/include/sophyamake.inc}. \\
+Each program module has a {\tt Makefile} which compiles and link the 
+corresponding programs using the compilation rules and libraries
+defined in {\$SOPHYABASE/include/sophyamake.inc}. 
+The top level Makefile in BuildMgr/ compiles each library modules
+and builds shared libraries. 
+\par
+Some of the modules in the Sophya package uses external libraries. The 
+{\bf FitsIOServer} is an example of such a module, where the {\tt libcfitsio.a}
+is used. The list of all Sophya modules using external libraries is
+presented in section \ref{sopmodules}.
+The external libraries should be installed before the configure step
+(see below) and the compilation of the corresponding Sophya modules. 
+\par 
+The series of Makefiles use the link to {\tt sophyamake.inc} in BuildMgr.
+There are also the {\tt smakefile} series which uses the explicit path, using
+{\tt \$SOPHYABASE} environment variable.
+
+\subsection{Build instructions} 
+\label{build}
+The build procedure has two main steps: 
+\begin{enumerate}
+\item The configure step (BuildMgr/configure) setup the directory structure and
+the necessary configuration file. Refer to section \ref{directories} for 
+the description of SOPHYA directory tree and files.
+\item The make step compiles the different sources files, create the library and optionaly
+builds all or some of the associated executables. 
+\end{enumerate}
+
+{\tt BuildMgr/configure } is a c-shell script with a number of arguments:
+\begin{verbatim}
+csh> ./configure -h
+configure [-sbase SOPHYABASE] [-scxx SOPHYACXX] [-incln] 
+  [-minc mymake.inc]  [-compopt 'cc/cxxOptions'] 
+  [-arch64] [-sasz64] [-nofpic] [-nothsafe] [-boundcheck] [-sodebug]
+  [-extp dir1 -extp dir2 ...] [-extip dir1 -extip dir2 ... ] [-extlp dir1 -extlp dir2 ... ]
+  [-noextlib] [-noext fits] [-noext fftw] [-noext lapack] [-noext astro]
+  [-noPI] [-slballinone]
+  [-alsofftwfloat] [-usefftw2] [-uselapack2] 
+  (See SOPHYA manual/web pages for a detailed description of configure options)
+\end{verbatim}
+\begin{itemize}
+\item[] -sbase : define SOPHYA installation base directory. \$SOPHYABASE is used 
+if not specified.
+\item[] -scxx : selects the C++ compiler. \$SOPHYACXX  s used 
+if not specified.
+\item[] -incln : creates symbolic link for include files, instead of copying them. 
+\item[] -minc : give an explicit name for the file used to generate 
+\$SOPHYABASE/include/sophyamake.inc. If {\tt -minc} is not specified, one of
+the files in BuildMgr/ directory is selected, based on the system name and the 
+compiler {\tt  Linux\_g++\_make.inc , OSF1\_cxx\_make.inc , AIX\_xlC\_make.inc \ldots}
+\item[] -extp : Adds the specied path to the search path of the external libraries 
+include files and archive library.
+\item[] -extip : Adds the specied path to the search path of the external libraries 
+include files.
+\item[] -extp : Adds the specied path to the search path of the external libraries 
+archive (libxxx.a).
+\item[] -noextlib : Disable compiling of modules referencing external libraries.
+\item[] -noext : Disable compiling of the specified module (with reference to external
+library : {\tt -noext fits , -noext fftw \ldots }
+\item[] -usefftw2: Use FFTW V2 instead of the default FFTW V3 - A preprocessor
+flag will be defined in sspvflags.h 
+\item[] -uselapack2: Lapack V2 is being used (defaulr V3) - A preprocessor
+flag will be defined in sspvflags.h 
+\item[] -alsofftwfloat : compile single precision (float) version  of the Fourier 
+transform methods (module IFFTW, class FFTWServer). A preprocessor
+flag will be defined in sspvflags.h and float version of the FFTW library 
+(libfftw3f.a) will be linked with SOPHYA, in addition to the default double
+precision library (libfftw3.a).
+\item[] -noPI : has currently no effect 
+\item[] -slballinone: A single shared library for all SOPHYA, PI and external library interface
+modules will be build. A compilation flag 
+will be defined in sspvflags.h . \\ See also target {\tt slballinone} below. 
+\end{itemize}
+
+{\large \bf configure steps } \\[1mm]
+The configure script performs the following actions :
+\begin{enumerate}
+\item Creating directory tree under {\tt \$SOPHYABASE }
+\item Cpoying include files (or creating symbolic) in {\tt \$SOPHYABASE/include/ }
+\item Search for external libraries include files and create the necessary links 
+in {\tt \$SOPHYABASE/include}
+\item Search for external libraries (-lfits \ldots) and add the corresponding 
+directories to the library search path, in {\tt sophyamake.inc}
+\item Creates the file { \tt \$SOPHYABASE/include/sophyamake.inc }
+\item Creates the file {\tt  machdefs.h} from { BaseTools/machdefs\_mkmf.h } and 
+{\tt sspvflags.h }
+\item Creates the object list files for shared library creation
+\end{enumerate}
+
+{\large \bf Example } \\[1mm]
+
+In the example below, we assume that we want to install Sophya from a 
+released (tagged) version in the source directory {\tt \$SRC} in the
+{\tt /usr/local/Sophya} directory, using {\tt g++}. We assume that 
+the external libraries can be found in {\tt /usr/local/ExtLibs/}. 
+We disable the compilation of the XAstroPack package.
+
+\vspace*{3mm}
+\begin{verbatim}
+# Create the top level  directory
+csh> mkdir /usr/local/Sophya/
+csh> cd $SRC/BuildMgr
+# Step 1.a : Run the configuration script 
+csh> ./configure -sbase /usr/local/Sophya -scxx g++  -extp /usr/local/ExtLibs/ \
+-noext astro
+# Step 1.b : Check the generated file  $SOPHYABASE/include/sophyamake.inc
+csh> ls -lt *.inc 
+csh> more sophyamake.inc 
+\end{verbatim}
+If necessary, edit the generated file {\tt sophyamake.inc } in order to modify 
+compilation flags, library list. The file is rather short and self documented.
+\begin{verbatim}
+# Step 2.a: Compile the modules without external library reference
+csh> make libs
+# Step 2.b: Compile the modules WITH  external library reference (optional) 
+csh> make extlibs
+# Step 2.c: Build libsophya.so
+csh> make slb
+# Step 2.d: Build libextsophya.so (optional)
+csh> make slbext
+# Step 2.e: Compile the PI and PIext modules (optional)
+csh> make PI
+# Step 2.f: Build the corresponding shared library libPI.so (optional)
+csh> make slbpi
+\end{verbatim}
+
+To compile all modules and build the shared libraries, it is possible 
+to perform the steps 2.a to 2.f using the targets {\tt all} and {\tt slball} 
+defined  in the Makefile
+\begin{verbatim}
+# Step 2.a ... 2.f
+csh> make all slball
+\end{verbatim}
+
+It is also possible to group all modules in a single shared library using 
+the target {\tt slballinone}. 
+\begin{verbatim}
+# Step 2.a ... 2.f
+csh> make all slballinone
+\end{verbatim}
+
+At this step, all libraries should have been made. Programs using
+Sophya libraries can now be built:
+\begin{verbatim}
+# To compile some of the test programs
+csh> make basetests
+# To compile runcxx , scanppf , scanfits 
+csh> make prgutil
+# To build (s)piapp (libPI.so is needed)
+csh> make piapp 
+\end{verbatim}
+
+If no further modification or update of source files is foreseen, it is possible 
+to remove all .o files:
+\begin{verbatim}
+#  To clean $SOPHYABASE/obj directory :
+csh> make cleanobj
+\end{verbatim}
+
+
+\subsection{Notes}
+\begin{itemize}
+\item[{\bf Makefile}] List of top level Makefile build targets 
+\begin{verbatim}
+> libs extlibs PI = all 
+> slb slbext slbpi = slball    (OR = slballinone)
+> clean  cleanobj
+> tests prgutil prgmap progpi = prgall 
+> basetests piapp (ou progpi)  pmixer 
+\end{verbatim}
+\item[{\bf MacOS X}] A high performance mathematic and signal processing
+library, including LAPACK and BLAS is packaged in Darwin/MacOS X (10.3, 10.4) : \\
+\hspace*{5mm} {\bf -framework Accelerate}
+\item[{\bf Tru64/OSF}] An optimised math library with LAPACK and BLAS might 
+optionaly be installed {\bf (-lcxlm) }. On our system, this libray contained Lapack V2.
+So we used the LAPACK, as compiled from the public sources, and linked with 
+the Tru64 native BLAS.
+\item[{\bf  IRIX64}] We used the math library with LAPACK V2 and BLAS 
+from SGI : {\bf -lcomplib.sgimath}
+\item[{\bf AIX}] There seem to be a problem on AIX when several shared 
+libraries are used. We have been able to run SOPHYA programs either 
+using static libraries, or a single shared library (libAsophyaextPI.so) 
+if extlibs and PI are needed, in addition to stand alone SOPHYA modules.
+It has not been possible to link SOPHYA with fortran libraries
+\item[{\bf Mgr}] This module contains makefiles and build scripts
+that were used in SOPHYA up to version 1.7 (2004) : OBSOLETE.
+\end{itemize}
+
+\subsection{Files and scripts in BuildMgr/ }
+\begin{itemize}
+\item[] {\bf Makefile:} Top level Makefile for building SOPHYA.
+{\tt smakefile} is similar to Makefile, except that it uses 
+the smakefiles in each module.
+\item[] {\bf mkmflib:}  c-shell script for creation of library module 
+Makefile / smakefile. \\
+\hspace*{5mm} {\tt  ./mkmflib -sbase /tmp/sbase SUtils } 
+\item[] {\b mkmfprog:} 
+c-shell script for creation of programs module Makefile / smakefile \\
+\hspace*{5mm}  {\tt ./mkmfprog -sbase /tmp/sbase ProgPI }
+\item[] {\bf domkmf:} c-shell script - calls mkmflib for all modules \\
+\hspace*{5mm} {\tt ./domkmf -sbase /tmp/sbase}
+\item[] {\bf xxx\_make.inc:} Configuration files for different compilers and OS
+{\tt ( Linux\_g++\_make.inc , OSF1\_cxx\_make.inc \ldots )}. 
+These files are used to generate {\tt sophyamake.inc} 
+\end{itemize}
+
+
+
+\newpage
+\appendix
+\section{SOPHYA Exceptions}
+\index{Exception classes} \index{PThrowable} \index{PError} \index{PException}
+SOPHYA library defines a set of exceptions which are used 
+for signalling error conditions. The figure below shows a partial 
+class diagram for exception classes in SOPHYA.
+\begin{figure}[hbt]
+\dclsbb{PThrowable}{PError}
+\dclscc{PError}{AllocationError}
+\dclscc{PError}{NullPtrError}
+\dclscc{PError}{ForbiddenError}
+\dclscc{PError}{AssertionFailedError}
+\dclsbb{PThrowable}{PException}
+\dclscc{PException}{IOExc}
+\dclscc{PException}{SzMismatchError}
+\dclscc{PException}{RangeCheckError}
+\dclscc{PException}{ParmError}
+\dclscc{PException}{TypeMismatchExc}
+\dclscc{PException}{MathExc}
+\dclscc{PException}{CaughtSignalExc}
+\caption{partial class diagram for exception handling in Sophya}
+\end{figure}
+
+For simple programs, it is a good practice to handle 
+the exceptions at least at high level, in the {\tt main()} function. 
+The example below shows the exception handling and the usage 
+of Sophya persistence.
+ 
+\input{ex1.inc}
+
+\newpage
+\addcontentsline{toc}{section}{Index}
+\printindex 
+\end{document}
+ 
Index: /tags/V_Nov2007/SophyaLib/Manual/sophya_afaire.txt
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/sophya_afaire.txt	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/sophya_afaire.txt	(revision 3445)
@@ -0,0 +1,109 @@
+----------------------------
+version : cmv   8/8/2000 15h
+          Reza  9/8/2000 16h
+          Reza  1/9/2000 14h
+          cmv  22/9/2000 18h
+          rz+cmv 24/11/00 16h
+	  rz+cmv 16/3/01 18H (tag V_Fev2001)
+          Reza   13/8/2001
+	  Reza   21/01/2002  (tag V_Nov2001 effectue)
+----------------------------
+
+================ Zone echange de commentaires ====================
+     Modifs sur TArray ( constructeur de copie share = false )
+==================================================================
+
+>>>>>>> Module BaseTools
+
+=== Rendre inactif le flag SetTemp() ds NDataBlock<T>              **NEW 08/01** 
+
+=== NDataBlock<T>: Ajout flag (... ,bool zero=true) ds le createur pour
+               permettre de ne pas initialiser la zone memoire    ***NEW 01/02***
+
+=== PPersist : Ajouter lecture-ecriture de complex<r_4> complex<r_8> 
+               et de tableaux de complexes                        ***NEW 01/02***
+
+=== PPersist : Ajouter lecture-ecriture de bintable avec possibilite 
+               d'utilisation en swap                              ***NEW 01/02***
+
+=== Creation d'une nouvelle classe DataBlock<T> : partage de reference sur
+             sur tableau de type T* (autre que numerique)         ***NEW 01/02***
+             (+ Gestionnaire PPersist pour DataBlock<string>)
+
+>>>>>>> Module SysTools
+
+=== Ecrire un classe interface de getrusage();
+    Voir pourquoi la classe ResourceUsage ne marche pas correctement
+    sur Linux et Mac
+
+>>>>>>> Module TArray
+
+=== Constructeur de copie de TArray , ajout d'un flag bool pack    **NEW 08/01**
+    TArray<T>::TArray(const TArray<T>& a, bool share, bool pack = true);
+    (a reporter aussi ds TMatrix<T>, TVector<T>, Image<T>
+    flag pack TArray<T>::ReSize(const BaseArray& a, bool pack = true);
+
+=== Changement du codage des operations :                          **NEW 08/01**
+    C = A+B ; // ---> C = A; C+=B; en  C = A+B
+
+=== Ajout flag (... ,bool zero=true) ds le createur pour
+               permettre de ne pas initialiser la zone memoire    ***NEW 01/02***
+
+=== Creation (?) classes TinyMatrix TinyVector ?                  ***NEW 01/02***
+
+=== Mettre OMP dans TArray
+    Etat: travail en cours par Reza 
+          Tests et directives OMP fait ds programme Eval/Speed/tompC.c 
+                                                               tompCXX.cc
+          Ne peut etre fait qu'apres la modif typedef size_T 
+
+ 
+>>>>>>> Module NTools
+
+=== Classes FFTServer (FFTPackSever) -                            **NEW 08/01** 
+    Eviter la copie complete sur SubArray - 
+    voir TArray(const TArray<T>& a, bool share, bool pack = true) ci-dessus 
+
+=== Serveur de classes de calcul<T> (Fond,Sigma etc...) sur images:
+    creer serveur 1D, 2D voir 3D
+    (ImageStatServer<T>,VectorStatServer<T>,...)
+    Etat: a faire par reza + cmv
+
+=== Classe FFTServer
+    Correction bug ds FFTmayer
+    Etat: a faire par Reza
+
+>>>>>>> Module HiStats
+
+=== NTuple et XNtuple -> mettre partage de reference
+    Etat: A faire par Reza
+
+>>>>>>> Module SkyMap
+
+=== Verification de l'interface (constructeur de copie, = )
+    des classes local/full sky map
+    Etat: semble OK (Reza 03/2001)
+
+>>>>>>> Module Samba 
+
+=== Faire 'un bon' generateur de bruit 1/f (plutot f^alpha) en utilisant
+    la methode de 'filtrage numerique' - Voir Numerical Receipe
+    Etat: A faire Reza
+
+
+>>>>>>> Module FitsIOServer
+
+=== Y-a-t'il tout ce qu'on veut dans FitsIOServer ?
+    Etat: a faire cmv
+
+>>>>>>>> Module IFFTW
+
+=== Classes FFTServer (FFTWSeever) -                            **NEW 08/01** 
+    Eviter la copie complet sur SubArray - 
+    voir TArray(const TArray<T>& a, bool share, bool pack = true) ci-dessus 
+
+
+>>>>>>>> Module LinAlg
+
+=== Ajouter interface pour decomposition LU en utilisant LaPack
+    Etat: A faire par CMV + Reza
Index: /tags/V_Nov2007/SophyaLib/Manual/spiapp_afaire.txt
===================================================================
--- /tags/V_Nov2007/SophyaLib/Manual/spiapp_afaire.txt	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Manual/spiapp_afaire.txt	(revision 3445)
@@ -0,0 +1,50 @@
+c----------------------------
+version : cmv+rz    27/6/2001 (reunion Saclay)
+----------------------------
+
+================ Zone echange de commentaires ====================
+
+==================================================================
+
+- FunRand : createur avec histo (1D+2D)
+
+- if then else dans interpreteur piapp
+
+- piapp multithreads
+
+- facteur d'echelle sur les axes des graphes 3D
+
+- Possibilite de selection d'un drawer avec la souris
+
+- trace des stat (histos...) sous forme de drawer indept
+
+- Creer un objet GeneralFunction + Parametres
+
+- Rendre le GeneralFunction d'un fit manipulable dans spiapp
+
+- possibilite d'etendre l'interpreteur pour evaluer
+  des fcts : h(g(12,23) + f(1,2), t(2,3))
+
+-----------------------------------------------------------
+
+  Ajoute par Reza 21/12/2001 
+
+-----------------------------------------------------------
+
+- possibilite de definir des fonctions en C
+  deffx deffxy ...
+
+- Drawer pour 3DVectorField 
+
+- Drawer pour trace de r = f(theta) (coordonnees polaires)
+
+- Drawer pour trace de pixmap ou image avec colmap
+
+- Drawer 3D pour trace d'un ensemble de pixmap / image avec colmap
+
+- Trace d'axe en coordonnees polaires
+
+- EventHandler pour move/resize des drawers
+
+- Possibilite de tracer un colomap/lut ds PIImage/PIScDrawWdg/PI3DWdg 
+  (ajout a PIElDrawer)
Index: /tags/V_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.cc	(revision 3445)
@@ -0,0 +1,348 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/FSAppIrrSmpl.h	(revision 3445)
@@ -0,0 +1,178 @@
+#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>
+
+
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+#include "nbmath.h"
+#include "timing.h"
+#include "array.h"
+#include "fftservintf.h"
+#include "fftpserver.h"
+
+#include "toeplitzMatrix.h"
+
+
+////////////////////////////////////////////////////////////////////
+/*! 
+  \ingroup NTools
+  \class SOPHYA::FSApproximationIrregularSampling
+  \brief Signal interpolation/approximation using Fourier series with irregularly 
+  sampled data
+
+  \verbatim
+  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()
+
+  \endverbatim 
+  \sa SOPHYA::ToeplitzMatrix
+*/
+/////////////////////////////////////////////////////////////////////
+
+namespace SOPHYA {
+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_;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/Makefile	(revision 3445)
@@ -0,0 +1,716 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libNTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)FSAppIrrSmpl.o $(SOPHYAOBJP)cimage.o $(SOPHYAOBJP)cspline.o $(SOPHYAOBJP)datatypes.o $(SOPHYAOBJP)dates.o $(SOPHYAOBJP)difeq.o $(SOPHYAOBJP)dynccd.o $(SOPHYAOBJP)fct1dfit.o $(SOPHYAOBJP)fct2dfit.o $(SOPHYAOBJP)fftmserver.o $(SOPHYAOBJP)fftpserver.o $(SOPHYAOBJP)fftservintf.o $(SOPHYAOBJP)functab.o $(SOPHYAOBJP)generaldata.o $(SOPHYAOBJP)generalfit.o $(SOPHYAOBJP)generalfunc.o $(SOPHYAOBJP)imageop.o $(SOPHYAOBJP)integ.o $(SOPHYAOBJP)median.o $(SOPHYAOBJP)ntoolsinit.o $(SOPHYAOBJP)objfitter.o $(SOPHYAOBJP)perandom.o $(SOPHYAOBJP)poly.o $(SOPHYAOBJP)rk4cdifeq.o $(SOPHYAOBJP)simplesort.o $(SOPHYAOBJP)simplex.o $(SOPHYAOBJP)tabmath.o $(SOPHYAOBJP)toeplitzMatrix.o $(SOPHYAOBJP)datime.o $(SOPHYAOBJP)fftmayer_r4.o $(SOPHYAOBJP)fftmayer_r8.o $(SOPHYAOBJP)fftpackc.o $(SOPHYAOBJP)matxop.o $(SOPHYAOBJP)nbmath.o $(SOPHYAOBJP)nbtri.o
+	rm -f $(SOPHYALIBP)libNTools.a
+ 
+$(SOPHYALIBP)libNTools.a : $(SOPHYAOBJP)cimage.o $(SOPHYAOBJP)cspline.o $(SOPHYAOBJP)datatypes.o $(SOPHYAOBJP)dates.o $(SOPHYAOBJP)datime.o $(SOPHYAOBJP)difeq.o $(SOPHYAOBJP)dynccd.o $(SOPHYAOBJP)fct1dfit.o $(SOPHYAOBJP)fct2dfit.o $(SOPHYAOBJP)fftmayer_r4.o $(SOPHYAOBJP)fftmayer_r8.o $(SOPHYAOBJP)fftmserver.o $(SOPHYAOBJP)fftpackc.o $(SOPHYAOBJP)fftpserver.o $(SOPHYAOBJP)fftservintf.o $(SOPHYAOBJP)FSAppIrrSmpl.o $(SOPHYAOBJP)functab.o $(SOPHYAOBJP)generaldata.o $(SOPHYAOBJP)generalfit.o $(SOPHYAOBJP)generalfunc.o $(SOPHYAOBJP)integ.o $(SOPHYAOBJP)matxop.o $(SOPHYAOBJP)median.o $(SOPHYAOBJP)nbmath.o $(SOPHYAOBJP)nbtri.o $(SOPHYAOBJP)ntoolsinit.o $(SOPHYAOBJP)objfitter.o $(SOPHYAOBJP)perandom.o $(SOPHYAOBJP)poly.o $(SOPHYAOBJP)rk4cdifeq.o $(SOPHYAOBJP)simplesort.o $(SOPHYAOBJP)simplex.o $(SOPHYAOBJP)tabmath.o $(SOPHYAOBJP)toeplitzMatrix.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)FSAppIrrSmpl.o: FSAppIrrSmpl.cc \
+  $(SOPHYAINCP)sopnamsp.h FSAppIrrSmpl.h \
+  $(SOPHYAINCP)machdefs.h nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h fftservintf.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h fftpserver.h \
+  toeplitzMatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  FSAppIrrSmpl.cc
+ 
+$(SOPHYAOBJP)cimage.o: cimage.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cimage.cc
+ 
+$(SOPHYAOBJP)cspline.o: cspline.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nbtri.h cspline.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cspline.cc
+ 
+$(SOPHYAOBJP)datatypes.o: datatypes.cc $(SOPHYAINCP)sopnamsp.h \
+  datatypes.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatypes.cc
+ 
+$(SOPHYAOBJP)dates.o: dates.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h dates.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dates.cc
+ 
+$(SOPHYAOBJP)difeq.o: difeq.cc $(SOPHYAINCP)sopnamsp.h difeq.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  difeq.cc
+ 
+$(SOPHYAOBJP)dynccd.o: dynccd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fmath.h perandom.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)srandgen.h classfunc.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)fioarr.h dynccd.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ppersist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dynccd.cc
+ 
+$(SOPHYAOBJP)fct1dfit.o: fct1dfit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fct1dfit.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  nbconst.h tabmath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fct1dfit.cc
+ 
+$(SOPHYAOBJP)fct2dfit.o: fct2dfit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fct2dfit.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  nbconst.h tabmath.h simps2d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fct2dfit.cc
+ 
+$(SOPHYAOBJP)fftmserver.o: fftmserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftmserver.h \
+  fftservintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftmayer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftmserver.cc
+ 
+$(SOPHYAOBJP)fftpserver.o: fftpserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftpserver.h \
+  fftservintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftpackc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftpserver.cc
+ 
+$(SOPHYAOBJP)fftservintf.o: fftservintf.cc fftservintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftservintf.cc
+ 
+$(SOPHYAOBJP)functab.o: functab.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h functab.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)tarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  functab.cc
+ 
+$(SOPHYAOBJP)generaldata.o: generaldata.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h nbtri.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generaldata.cc
+ 
+$(SOPHYAOBJP)generalfit.o: generalfit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generalfit.cc
+ 
+$(SOPHYAOBJP)generalfunc.o: generalfunc.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generalfunc.cc
+ 
+$(SOPHYAOBJP)integ.o: integ.cc $(SOPHYAINCP)sopnamsp.h integ.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h classfunc.h \
+  generalfit.h $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  integ.cc
+ 
+$(SOPHYAOBJP)median.o: median.cc
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  median.cc
+ 
+$(SOPHYAOBJP)ntoolsinit.o: ntoolsinit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h poly.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h generaldata.h \
+  $(SOPHYAINCP)ntupintf.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h tabmath.h nbconst.h \
+  dates.h datime.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntoolsinit.cc
+ 
+$(SOPHYAOBJP)objfitter.o: objfitter.cc $(SOPHYAINCP)sopnamsp.h \
+  objfitter.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  objfitter.cc
+ 
+$(SOPHYAOBJP)perandom.o: perandom.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h perandom.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)srandgen.h classfunc.h pemath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  perandom.cc
+ 
+$(SOPHYAOBJP)poly.o: poly.cc $(SOPHYAINCP)machdefs.h poly.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h linfit.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)fioarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  poly.cc
+ 
+$(SOPHYAOBJP)rk4cdifeq.o: rk4cdifeq.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h rk4cdifeq.h difeq.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rk4cdifeq.cc
+ 
+$(SOPHYAOBJP)simplesort.o: simplesort.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h simplesort.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  simplesort.cc
+ 
+$(SOPHYAOBJP)simplex.o: simplex.cc $(SOPHYAINCP)sopnamsp.h \
+  simplex.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  simplex.cc
+ 
+$(SOPHYAOBJP)tabmath.o: tabmath.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h tabmath.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h nbconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tabmath.cc
+ 
+$(SOPHYAOBJP)toeplitzMatrix.o: toeplitzMatrix.cc \
+  $(SOPHYAINCP)sopnamsp.h toeplitzMatrix.h \
+  $(SOPHYAINCP)machdefs.h nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h fftservintf.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h fftpserver.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  toeplitzMatrix.cc
+ 
+$(SOPHYAOBJP)datime.o: datime.c $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h nbconst.h datime.h
+	$(CCOMPILE) -o $@  datime.c
+ 
+$(SOPHYAOBJP)fftmayer_r4.o: fftmayer_r4.c fftmayer.h \
+  $(SOPHYAINCP)machdefs.h trigtbl.h
+	$(CCOMPILE) -o $@  fftmayer_r4.c
+ 
+$(SOPHYAOBJP)fftmayer_r8.o: fftmayer_r8.c fftmayer.h \
+  $(SOPHYAINCP)machdefs.h trigtbl.h
+	$(CCOMPILE) -o $@  fftmayer_r8.c
+ 
+$(SOPHYAOBJP)fftpackc.o: fftpackc.c fftpackc.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  fftpackc.c
+ 
+$(SOPHYAOBJP)matxop.o: matxop.c matxop.h nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  matxop.c
+ 
+$(SOPHYAOBJP)nbmath.o: nbmath.c nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h matxop.h nbinteg.h \
+  nbtri.h
+	$(CCOMPILE) -o $@  nbmath.c
+ 
+$(SOPHYAOBJP)nbtri.o: nbtri.c nbtri.h $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  nbtri.c
+ 
Index: /tags/V_Nov2007/SophyaLib/NTools/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/Makefile.mgr	(revision 3445)
@@ -0,0 +1,458 @@
+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)functab.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)simplex.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)functab.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)simplex.o $(OBJ)tabmath.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)FSAppIrrSmpl.o: FSAppIrrSmpl.cc $(INC)sopnamsp.h \
+  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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)fioarr.h \
+  $(INC)tvector.h \
+  $(INC)datatype.h
+$(OBJ)cspline.o: cspline.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h nbtri.h cspline.h \
+  $(INC)pexceptions.h
+$(OBJ)datatypes.o: datatypes.cc $(INC)sopnamsp.h \
+  datatypes.h $(INC)machdefs.h
+$(OBJ)dates.o: dates.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)perrors.h \
+  $(INC)pexceptions.h dates.h
+$(OBJ)difeq.o: difeq.cc $(INC)sopnamsp.h 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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)ctimer.h
+$(OBJ)dynccd.o: dynccd.cc $(INC)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h \
+  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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)tvector.h fftmayer.h
+$(OBJ)fftpserver.o: fftpserver.cc $(INC)sopnamsp.h \
+  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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)tvector.h fftpackc.h
+$(OBJ)fftservintf.o: fftservintf.cc $(INC)sopnamsp.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)tvector.h
+$(OBJ)functab.o: functab.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)pexceptions.h functab.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h
+$(OBJ)generaldata.o: generaldata.cc $(INC)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h integ.h \
+  $(INC)machdefs.h \
+  $(INC)pexceptions.h classfunc.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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 \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h \
+  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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)pexceptions.h perandom.h \
+  $(INC)histos.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h poly.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)ctimer.h
+$(OBJ)simplesort.o: simplesort.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h simplesort.h peida.h \
+  $(INC)utils.h \
+  $(INC)perrors.h \
+  $(INC)pexceptions.h fmath.h
+$(OBJ)simplex.o: simplex.cc $(INC)sopnamsp.h simplex.h \
+  $(INC)machdefs.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h generalfit.h generaldata.h \
+  $(INC)ntupintf.h poly.h peida.h \
+  $(INC)utils.h \
+  $(INC)perrors.h fmath.h \
+  $(INC)ntuple.h \
+  $(INC)timing.h
+$(OBJ)tabmath.o: tabmath.cc $(INC)sopnamsp.h \
+  $(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_Nov2007/SophyaLib/NTools/cimage.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/cimage.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/cimage.cc	(revision 3445)
@@ -0,0 +1,217 @@
+//  Classes image heritant de TMatrix<T>
+//                       R.Ansari, C.Magneville 07/2000    
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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>()
+{ 
+  this->dobj = new Image<T>(obj, true);
+  this->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 (this->ownobj && this->dobj) delete this->dobj;
+  this->dobj = po; this->ownobj = false;
+} 
+
+template <class T>
+void FIO_Image<T>::ReadSelf(PInPersist& is)
+{
+  if (this->dobj == NULL) this->dobj = new Image<T>;
+  Image<T> * img = dynamic_cast<Image<T> * > (this->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 (this->dobj == NULL)   return;
+  Image<T> * img = dynamic_cast<Image<T> * > (this->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_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_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>
+#pragma define_template FIO_Image< complex<r_4> >
+#pragma define_template FIO_Image< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+namespace SOPHYA {
+template class Image<uint_2>;
+template class Image<int_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_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>;
+template class FIO_Image< complex<r_4> >;
+template class FIO_Image< complex<r_8> >;
+}
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/cimage.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/cimage.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/cimage.h	(revision 3445)
@@ -0,0 +1,144 @@
+// 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 this->NCols();}
+  //! Returns the image size along Y (corresponding to the number of lines)  
+  inline sa_size_t  YSize() const {return this->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; }
+
+  //! = : fill image with constant value \b x
+  inline  Image<T>&  operator = (T x) {SetT(x); return(*this);}
+
+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> * >(this->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_Nov2007/SophyaLib/NTools/classfunc.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/classfunc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/classfunc.h	(revision 3445)
@@ -0,0 +1,30 @@
+////////////////////////////////////////////////////////////////
+//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 interface definition for functions (double f(double)) viewed as classes
+class ClassFunc {
+public:
+  virtual ~ClassFunc(void) { }
+  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){}
+  virtual  double operator()(double x) { return f(x);}
+};
+
+}
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/cspline.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/cspline.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/cspline.cc	(revision 3445)
@@ -0,0 +1,407 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <iostream>
+
+
+#include "nbtri.h"
+#include "cspline.h"
+
+/*!
+  \class SOPHYA::CSpline
+  \ingroup NTools
+  Spline 3 smoother (interpolator) for 1-D data points (y = f(x)) 
+  \sa CSpline2
+*/
+
+/*!
+  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.
+*/
+CSpline::CSpline(int n,double* x,double* y,double yp1,double ypn
+                ,int natural,bool order)
+  : 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();
+
+}
+
+//!	Createur par defaut.
+CSpline::CSpline(double yp1,double ypn,int natural)
+  : Nel(0), corrupt_Y2(true), XY_Created(false), Natural(natural)
+  , YP1(yp1), YPn(ypn), X(NULL), Y(NULL), Y2(NULL), tmp(NULL)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! destructeur
+CSpline::~CSpline()
+{
+DelTab();
+}
+
+/*!
+  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.
+*/
+void CSpline::SetNewTab(int n,double* x,double* y,bool order,bool force)
+{
+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 ParmError(PExcLongMessage(""));
+    }
+  }
+} else { X = x; Y = y; }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! destruction des divers tableaux en tenant compte des allocations/connections
+void CSpline::DelTab()
+{
+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;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/*!
+  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]".
+*/
+void CSpline::SetBound1er(double yp1,double ypn)
+{
+if( yp1 == YP1 && ypn == YPn ) return;
+
+YP1 = yp1;
+YPn = ypn;
+
+corrupt_Y2 = true;
+}
+
+//! Pour calculer les tableaux de coeff permettant le calcul des interpolations spline.
+void CSpline::ComputeCSpline()
+{
+// 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;
+}
+
+//!	Interpolation spline en \b x
+double CSpline::CSplineInt(double 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 ParmError(PExcLongMessage(""));
+}
+
+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 ParmError(PExcLongMessage(""));
+}
+
+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;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::CSpline2
+  \ingroup NTools
+  Spline smoother (interpolator) for 2-D data points (y = f(x1,x2)) 
+  \sa CSpline
+*/
+
+/*!
+  Contructeur - Meme commentaire que pour CSpline avec:
+  \verbatim
+  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]
+  \endverbatim
+*/
+CSpline2::CSpline2(int n1,double* x1,int n2,double* x2,double* y
+                  ,int natural,bool order)
+  : 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();
+
+}
+
+//!	Createur par defaut.
+CSpline2::CSpline2(int natural)
+  : 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)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+CSpline2::~CSpline2()
+{
+DelTab();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//!	Voir commentaire meme methode de CSpline
+void CSpline2::SetNewTab(int n1,double* x1,int n2,double* x2,double* y
+                        ,bool order,bool force)
+{
+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 ParmError(PExcLongMessage("")); }
+    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 ParmError(PExcLongMessage("")); }
+    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;}
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//!	Voir commentaire meme methode de CSpline
+void CSpline2::ComputeCSpline()
+{
+// 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;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! Calcule la valeur interpole (spline) pour le point \b (x1,x2)
+double CSpline2::CSplineInt(double x1,double x2)
+{
+// 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);
+}
+
Index: /tags/V_Nov2007/SophyaLib/NTools/cspline.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/cspline.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/cspline.h	(revision 3445)
@@ -0,0 +1,127 @@
+#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.);
+
+//!  Pour changer le type de contraintes sur les derivees 2sd
+  inline void SetNaturalCSpline(int type = NaturalAll)
+                 { Natural = type;}
+
+//!  Pour liberer la place tampon qui ne sert que dans ComputeCSpline() et pas dans CSplineInt
+  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);
+
+//!  Pour changer le type de contraintes sur les derivees 2sd
+  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_Nov2007/SophyaLib/NTools/datatypes.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/datatypes.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/datatypes.cc	(revision 3445)
@@ -0,0 +1,83 @@
+// Type de donnees de base 
+//                E. Lesquoy , E. Aubourg 
+//                             R. Ansari 04/95
+
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/NTools/datatypes.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/datatypes.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/datatypes.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/dates.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/dates.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/dates.cc	(revision 3445)
@@ -0,0 +1,785 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <iostream>
+#include <time.h>
+#include <ctype.h>
+#include <math.h>
+#include "perrors.h"
+#include "dates.h"
+
+/*! 
+  \class TimeZone
+  \ingroup NTools
+  Management of time zones - This class is used with class Date.
+  \warning Unless necessary, DO NOT USE this class. 
+  \sa SOPHYA::TimeStamp
+
+  \verbatim
+  
+  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".
+  \endverbatim
+*/
+
+TimeZone* gTimeZone = NULL;
+
+
+/*!	
+  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...
+*/  
+TimeZone::TimeZone()
+{
+  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);
+}
+
+//!	Constructeur à partir du nom d'un fuseau horaire.
+TimeZone::TimeZone(const char* nom)
+{
+  SetZone(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).
+*/
+void TimeZone::SetZone(const char* nom)
+{
+  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 ParmError("TimeZone::SetZone() ");
+}
+
+//!	Teste si une date est en heure d'été (DST).
+int TimeZone::IsDst(const Date& date)
+{
+  Date dt = date;
+  if (dt.MM < 0 || dt.JJ < 0) throw ParmError(PExcLongMessage(""));
+  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;
+  }
+}
+
+/*!
+  Retourne la difference TL-GMT pour une date donnée,
+  en tenant compte de l'heure d'été éventuelle.
+*/
+int TimeZone::GetOffset(const Date& date)
+{
+  return IsDst(date) ? gmtOffset+dstOffset : gmtOffset;
+}
+
+
+
+/*! 
+  \class Date
+  \ingroup NTools
+  Date manipulation classe
+  \warning Unless necessary, DO NOT USE this class.
+  Use  SOPHYA::TimeStamp instead.
+
+  \verbatim
+  
+  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.
+
+*/
+//!	Retourne le nombre de jours dans le mois
+short Date::MonthDays(short mois, short annee)
+{
+  if (mois<1 || mois>12) throw ParmError(PExcLongMessage(""));
+  
+  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;
+}
+    
+//!  Retourne le nombre de jours dans l'année
+short Date::YearDays(short annee)
+{
+  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));
+}
+
+/*!
+  Retourne true si toute la date (jour
+  et mois et année) est indéterminée.
+*/
+bool Date::AllUndetDate() const
+{
+  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));
+}
+
+
+/*!
+  Retourne true si toute l'heure (heure
+  et minutes et secondes) est indéterminée.
+*/
+bool Date::AllUndetTime() const
+{
+  return ((hh == -1) && (mm == -1) && (ss == -1));
+}
+
+//Date::operator double() const
+
+//!	Jours écoulés depuis le 0 janvier 1901 0h TU
+double
+Date::GetDays() const
+{
+   if (UndetTime() && !AllUndetTime()) throw ParmError(PExcLongMessage(""));
+   if (UndetDate() && !AllUndetDate()) throw ParmError(PExcLongMessage(""));
+   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;
+}
+
+//!	Initialisation a partir jours écoulés depuis le 0 janvier 1901 0h TU
+void Date::Set(double t)
+{
+   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;
+}
+
+//!	Constructeur. Prend l'heure courante...
+Date::Date()
+: 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;
+}
+
+//!	Constructeur simple.
+Date::Date(int J, int M, int A, int h, int m, double s)
+: JJ(J), MM(M), AA(A), hh(h), mm(m), ss(s), timeZone(gTimeZone), nuit(0)
+{
+}
+
+//!	Constructeur à partir des jours écoulés depuis le 0 janvier 1901 0h TU
+Date::Date(double t)
+: timeZone(gTimeZone)
+{
+  Set(t);
+}
+
+//!	On change de fuseau horaire.
+void Date::SetTimeZone(TimeZone* tz)
+{
+  timeZone = tz;
+}
+
+/*!
+  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.
+*/
+Date::Date(const char* date, const char* heure, int tOpt)
+: timeZone(gTimeZone)
+{
+  Set(date,heure,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 ('??').
+*/
+Date::Date(string const& date, string const& heure, int tOpt)
+: timeZone(gTimeZone)
+{
+  Set(date,heure,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 ('??').
+*/
+void Date::Set(string const& date, string const& heure, int tOpt)
+{
+  Set(date.c_str(), heure == "" ? (char*)NULL : heure.c_str(), 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 ('??').
+*/
+void Date::Set(const char* date, const char* heure, int tOpt)
+{
+  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 ParmError(PExcLongMessage(""));
+      if (!isdigit(p[1]) && p[1] != '/') throw ParmError(PExcLongMessage(""));
+      JJ = atoi(p);
+      if (JJ <= 0) throw ParmError(PExcLongMessage(""));
+    }
+    
+    if (p[1] == '/') p += 2;
+    else if (p[2] == '/') p+= 3;
+    else throw ParmError(PExcLongMessage(""));
+
+    if (p[0] == '?' && (p[1] == '?' || p[1] == '/'))   MM = -1;
+    else {
+      if (!isdigit(p[0])) throw ParmError(PExcLongMessage(""));
+      if (!isdigit(p[1]) && p[1] != '/') throw ParmError(PExcLongMessage(""));
+      MM = atoi(p);
+      if (MM <= 0 || MM >12) throw ParmError(PExcLongMessage(""));
+    }
+
+    if (p[1] == '/') p += 2;
+    else if (p[2] == '/') p+= 3;
+    else throw ParmError(PExcLongMessage(""));
+
+    if (p[0] == '?')  AA = -1;
+    else {
+      if (!isdigit(p[0])) throw ParmError(PExcLongMessage(""));
+      if (!isdigit(p[1])) throw ParmError(PExcLongMessage(""));
+      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 ParmError(PExcLongMessage(""));
+    
+   } else if (strlen(date)==4) {      // Code EROS de date
+     if (date[0] == '?') AA = -1;
+     else {
+       if (!isdigit(date[0])) throw ParmError(PExcLongMessage(""));
+       AA = 1990 + date[0] - '0';
+     }
+     
+     if (date[1] == '?') MM = -1;
+     else {
+       if (!isalpha(date[1])) throw ParmError(PExcLongMessage(""));
+       if (islower(date[1]))
+         MM = date[1] - 'a' + 1;
+       else
+         MM = date[1] - 'A' + 1;
+       if (MM<1 || MM>12) throw ParmError(PExcLongMessage(""));
+     }
+     
+     if (date[2] == '?' && date[3] == '?') JJ = -1;
+     else {
+       if (!isdigit(date[2])) throw ParmError(PExcLongMessage(""));
+       if (!isdigit(date[3])) throw ParmError(PExcLongMessage(""));
+       JJ = atoi(date+2);
+     }
+     
+     if (AA > 0 && MM > 0 && JJ > 0 && JJ > MonthDays(MM,AA)) 
+       throw ParmError(PExcLongMessage(""));
+     nuit = 1;
+   } else throw ParmError(PExcLongMessage(""));   // 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 ParmError(PExcLongMessage(""));
+      if (!isdigit(p[1]) && p[1] != ':') throw ParmError(PExcLongMessage(""));
+      hh = atoi(p);
+    }
+
+    if (p[1] == ':') p += 2;
+    else if (p[2] == ':') p+= 3;
+    else throw ParmError(PExcLongMessage(""));
+
+    if (p[0] == '?' && (p[1] == '?' || p[1] == ':'))   mm = -1;
+    else {
+      if (!isdigit(p[0])) throw ParmError(PExcLongMessage(""));
+      if (!isdigit(p[1]) && p[1] != '/') throw ParmError(PExcLongMessage(""));
+      mm = atoi(p);
+    }
+
+    if (p[1] == ':') p += 2;
+    else if (p[2] == ':') p+= 3;
+    else throw ParmError(PExcLongMessage(""));
+
+    if (p[0] == '?')   ss = -1;
+    else {
+      if (!isdigit(p[0])) throw ParmError(PExcLongMessage(""));
+      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;
+}
+
+/*!
+  Récupère la date sous la forme d'une chaîne 'DD/MM/YYYY'
+  en tOpt = Date::kGMTTime ou Date::kLocalTime.
+*/
+void Date::GetDateStr(char* s, int tOpt) const
+{
+  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';
+  }
+}
+
+//!	Code EROS de la date.
+void Date::GetDateCode(char* s, int tOpt) const
+{
+  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 ParmError(PExcLongMessage(""));
+    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;
+}
+
+//!	Récupère l'heure sous la forme 'HH:MM:SS'
+void Date::GetTimeStr(char* s, int tOpt) const
+{
+  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] = '?';
+}
+
+//!	Récupèrera un jour le temps sidéral.
+void Date::GetSidTStr(char* s) const
+{
+  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;
+}
+
+//!	Code EROS de la date.
+string Date::DateCode(int tOpt) const
+{
+   char s[20];
+   GetDateCode(s,tOpt);
+   return s;
+}
+
+//!	Récupère l'heure sous la forme 'HH:MM:SS'
+string Date::TimeStr(int tOpt) const
+{
+   char s[20];
+   GetTimeStr(s,tOpt);
+   return s;
+}
+
+//!	Récupèrera un jour le temps sidéral.
+string Date::SidTStr() const
+{
+   char s[20];
+   GetSidTStr(s);
+   return s;
+}
+
+//!   Retourne le jour dans la semaine, 0-6 avec 0 = Date::jour_Lundi.
+int Date::DayOfWeek(int tOpt) const
+{
+  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;
+}
+
+/*!
+  Retourne la date correspondant au ieme joursem dans le mois 
+  correspondant (exemple, 2e dimanche de mars 1960).
+*/
+short Date::NthMonthDay(short i, short joursem, short mois, short annee)
+{
+   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;
+   }
+}
+
+//! Ajout un nombre \b dt en jours
+Date& Date::operator += (double dt)     
+{
+  int u = UndetTime();
+  Set(GetDays()+dt);
+  if (u) ss = hh = mm = -1;
+  return *this;
+}
+
+//!  retranche un intervalle de temps \b dt en jours
+Date& Date::operator -= (double dt)    
+{
+  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;
+}
+
+//!	Résultat en jours
+double operator - (Date const& a, Date const& b)
+{
+  if (a.UndetTime() != b.UndetTime()) throw ParmError(PExcLongMessage(""));
+  if (a.UndetDate() != b.UndetDate()) throw ParmError(PExcLongMessage(""));
+  return a.GetDays() - b.GetDays();
+}
+
+//!	On n'a pas égalite dès que des éléments déterminés sont différents
+bool operator == (Date const& a, Date const& b)
+{
+  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);
+}
+
+//!	Inégalité large. Pas de subtilités
+bool operator <= (Date const& a, Date const& b)
+{
+  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;
+}
+
+/*!
+  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
+*/
+bool operator < (Date const& a, Date const& b)
+{
+  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_Nov2007/SophyaLib/NTools/dates.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/dates.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/dates.h	(revision 3445)
@@ -0,0 +1,152 @@
+//   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>
+#include "pexceptions.h"
+
+// namespace SOPHYA {  
+
+class TimeZone;
+//! Dates, conversions, operations 
+// Classe generale de date et heure, operation, TU/TL ...
+class Date  {
+public:
+  //! Enumerations jours et mois
+  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};
+
+  // 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_Nov2007/SophyaLib/NTools/datime.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/datime.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/datime.c	(revision 3445)
@@ -0,0 +1,1315 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+
+#define DATIMEPRIVEE
+#include "strutil.h"
+#include "nbconst.h"
+#include "datime.h"
+
+
+/*       Fonctions de calcule de date et temps (Heure)       */
+/*! 
+  \ingroup NTools
+  \file datime.c
+  \brief Set of C functions and macros to manipulate date and time  + Sidereal time
+  and simple astronomical functions.
+
+  \warning  If possible, use class SOPHYA::TimeStamp in module BaseTools
+  for date/time computation.
+
+  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
+
+  \sa SOPHYA::TimeStamp
+*/
+
+/*
+++
+  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
+--
+*/
+/*!
+  \ingroup NTools
+   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)
+*/
+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;
+}
+
+/*!
+  \ingroup NTools
+  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 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 */
+/*!
+  \ingroup NTools
+  \brief Retourne le nombre de jours dans le mois m, annee a
+*/
+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]);
+}
+
+/*!
+  \ingroup NTools
+  Calcule le Nombre de jours ecoules depuis 0 Jan 1901. 
+  Si annee < 100  On considere annee = annee+1900  (1900-1999) 
+*/
+/* Nouvelle-Fonction */
+long JMAtoJ(JMA jma)
+{
+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);
+}
+
+/*!
+  \ingroup NTools
+  \brief retourne la date correspondant a \b j jours ecoules depuis le 0/1/1901
+*/
+/* Nouvelle-Fonction */
+JMA JtoJMA(long j)
+{
+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);
+}
+
+/*!
+  \ingroup NTools
+  \brief Cette fonction calcule le numero de jour de la semaine (Lundi=1 .. Dimanche=7) 
+*/
+/* Nouvelle-Fonction */
+int NumJour(JMA jma)
+{
+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);
+}
+
+/*!
+  \ingroup NTools
+  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
+*/
+JMA JApmmaatoJMA(int nj, int mm, int aa)
+{
+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);
+}
+
+/*!
+  \ingroup NTools
+  Cette fonction calcule le nombre d'heures en decimales pour \b hms. 
+  Heures/Minutes/Secondes peuvent etre +/- avec toutes les combinaisons possibles
+*/
+/* 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.);
+}
+
+
+/*!
+  \ingroup NTools
+  \brief Conversion en secondes de la structure HMS  "hms"
+*/
+/* 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);
+}
+
+/*!
+  \ingroup NTools
+  Calcule le nombre de secondes correspondant a "date,heure" 
+  a partir de l'origine 1er Janv 1990  0H00 ( Date entre 1930 - 2050 )
+*/
+/* 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)) );    
+}
+
+/*!
+  \ingroup NTools
+  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.
+*/
+/* 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);    
+}
+
+/*!
+  \ingroup NTools
+  \brief Conversion heures en decimales en structure HMS
+*/
+/* 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);
+}
+
+/*!
+  \ingroup NTools
+  Conversion degres decimaux en structure HMS (deg,min,sec)
+  Degres decimaux en D , M , Sec  Il y a un modulo 360.
+  la sortie est telle que -180 < deg <= 180.
+*/
+/* Nouvelle-Fonction */
+HMS DtoDMS(double h)
+{
+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);
+}
+
+/*!
+  \ingroup NTools
+  Conversion degres/heures decimaux en structure HMS (deg/heure,min,sec)
+  SANS modulo 360/24
+*/
+/* 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);
+}
+
+/*!
+  \ingroup NTools
+  \brief Cette fonction  donne le temps sideral moyen a greenwich a 0h UT 
+*/
+/* 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).
+--
+*/
+/*!
+  \ingroup NTools
+  Cette fonction calcule le temps sideral GMT a partir du temps
+  universel et de la date GMT.
+  \verbatim
+  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 
+  \endverbatim
+*/
+/* 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);
+}
+
+/*!
+  \ingroup NTools
+  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  */
+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);
+}
+
+/*!
+  \ingroup NTools
+  Fonction d'initialisation de conversion  de temps sideral et legal 
+  pour la ESO-Silla "SetTSolMOff() , SetTLegOff()".
+  \verbatim
+  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)
+  \endverbatim
+*/
+/* 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;
+}
+
+
+
+/*!
+  \ingroup NTools
+  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.;
+}
+
+/*!
+  \ingroup NTools
+  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;
+}
+
+
+/*!
+  \ingroup NTools
+  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);
+}
+
+/*!
+  \ingroup NTools
+  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);
+}
+
+/*!
+  \ingroup NTools
+  Valeur de l'eccentricite de l'orbite terrestre
+  a la date TU ``dateTU''.
+  Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10
+*/
+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);
+}
+
+/*!
+  \ingroup NTools
+  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);
+}
+
+/*! 
+  \ingroup NTools
+  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);
+}
+
+/*!
+  \ingroup NTools
+  Renvoie les coordonnees ecliptiques \b (l,b) a partir de
+  coordonnees equatoriales \b (a,d) a la date TU \b 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_Nov2007/SophyaLib/NTools/datime.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/datime.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/datime.h	(revision 3445)
@@ -0,0 +1,143 @@
+/*    ------ 1)  Declaration de structure temps et date  ----- */
+/*                            Reza 92/93                       */
+
+#ifndef DATIME_H_SEEN
+#define DATIME_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*! 
+  \ingroup NTools
+  \file datime.h
+  Set of C functions and macros to manipulate date and time + Sidereal time.
+  \sa datime.c
+  \warning : If possible, use class SOPHYA::TimeStamp
+*/
+/*! 
+  \ingroup NTools
+  \brief Structure JMA pour representer une date (Jour, Mois Annee) */
+typedef struct 
+  {
+  int Jour;
+  int Mois;
+  int Annee;
+  }  JMA ;
+
+/*! 
+  \ingroup NTools
+  \brief Structure HMS pour representer une heure (Heure, Minute Seconde) 
+*/
+typedef struct 
+  {
+  int  Heures;
+  int Minutes;
+  double Secondes;
+  } HMS ;
+
+/* \cond */
+/*   ----------    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
+
+/* \endcond */
+/*    ------ 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   */
+/*! \brief  Decodage de Chaine de forme  hh:mm:sec   ->  structure HMS   */
+#define  StrgtoHMS(s,h)  ( sscanf(s,"%d:%d:%lf", &(h.Heures),&(h.Minutes),&(h.Secondes)) )
+/*! \brief  structure HMS -> Chaine de forme  hh:mm:sec  */
+#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 ??????????????????????????????????????????????????????????????????????? */
+/*!  \brief Chaine de caracteres sous forme de dd/mm/aaaa -> structure JMA jma. */
+#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) ) 
+/*! \brief structure JMA -> Chaine de forme jj/mm/aa       */
+#define  JMAtoStrg(j,strg)  ( sprintf(strg,"%02d/%02d/%4d", j.Jour,j.Mois,j.Annee) )
+/*! \brief structure JMA -> Chaine de forme jj/mm/aa       */
+#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_Nov2007/SophyaLib/NTools/difeq.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/difeq.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/difeq.cc	(revision 3445)
@@ -0,0 +1,571 @@
+#include "sopnamsp.h"
+#include "difeq.h"
+#include "ctimer.h"
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::DiffEqSolver
+  \brief 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(...)
+
+  \warning statut EXPERIMENTAL , NON TESTE
+
+  \sa SOPHYA::DiffEqFunction
+  \sa SOPHYA::RK4DiffEq  SOPHYA::RK4CDiffEq 
+*/
+
+//!	Constructeur vide. 
+DiffEqSolver::DiffEqSolver()
+: mFunc(NULL), mOwnFunc(false),
+  mYStart(1), mXStart(0), mStep(0.01)
+{}
+
+//!  Constructeur général. L'équation est donnée sous forme de DiffEqFunction
+DiffEqSolver::DiffEqSolver(DiffEqFunction* f)
+: mFunc(f), mOwnFunc(false),
+  mYStart(mFunc->NFuncReal()), mXStart(0), mStep(0.01)
+{}
+
+/*!
+  Constructeur pour le cas particulier d'une équation du premier
+  ordre. Voir DiffEqFcn1. La fonction f correspond à l'équation
+  y' = f(y).
+*/
+DiffEqSolver::DiffEqSolver(DIFEQFCN1 f)
+: mFunc(new DiffEqFcn1(f)), mOwnFunc(true),
+  mYStart(mFunc->NFuncReal()), mXStart(0), mStep(0.01)
+{}
+
+DiffEqSolver::~DiffEqSolver()
+{
+  if (mOwnFunc) delete mFunc;
+}
+
+
+/*!
+  Permet de spécifier l'équation différentielle, sous la forme
+  d'une DiffEqFunction. Retourne l'objet DiffEqSolver : notation
+  chaînée possible
+*/
+DiffEqSolver&
+DiffEqSolver::Func(DiffEqFunction* f)
+{
+  if (mFunc && mOwnFunc) delete mFunc;
+  mFunc    = f;
+  mOwnFunc = false;
+  return *this;
+}
+
+/*!
+  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.
+*/
+DiffEqSolver&
+DiffEqSolver::Func(DIFEQFCN1 f)
+{
+  if (mFunc && mOwnFunc) delete mFunc;
+  mFunc    = new DiffEqFcn1(f);
+  mOwnFunc = true;
+  return *this;
+}
+
+/*!
+  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.
+*/
+DiffEqSolver&
+DiffEqSolver::Step(double step)
+{
+  mStep = step;
+  return *this;
+}
+
+
+/*!
+  Spécifie le point de départ de l'intégration de l'équadif.
+  Le vecteur \b 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. \b 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.
+*/
+DiffEqSolver&
+DiffEqSolver::StartV(Vector const& yi, double t)
+{
+  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;
+}
+
+/*!  
+  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.
+*/
+DiffEqSolver&
+DiffEqSolver::Start1(double y, double t)
+{
+  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;
+}
+
+
+/*!
+  Spécifie le point de départ de l'intégration de l'équadif.
+  Le tableau \b 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.
+*/
+DiffEqSolver&
+DiffEqSolver::Start(double const* yi, double t)
+{
+  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;
+}
+
+/*!
+  \fn virtual void DiffEqSolver::SolveArr(Matrix&  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.
+  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).
+*/
+
+
+/*!
+  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.
+*/
+void
+DiffEqSolver::SolveV(Vector& yf, double tf)
+{
+  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);
+}
+
+
+/*!
+  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.
+*/
+void
+DiffEqSolver::Solve1(double& yf, double tf)
+{
+  ASSERT(mFunc->NFunc() == 1);
+  double t;
+  Matrix m(1,mFunc->NFuncReal());
+  SolveArr(m, &t, tf, 1);
+  yf = m(0,0);
+}
+
+
+/*!
+  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.
+*/
+void
+DiffEqSolver::Solve(double* yf, double tf)
+{
+  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);
+}
+
+/*!
+  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.
+*/
+void
+DiffEqSolver::SolveArr1(double*  y, double* t, double tf, int n)
+
+{
+  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);
+}
+
+/*!
+  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.
+*/
+void
+DiffEqSolver::SolveArr2(double** y, double* t, double tf, int n)
+{
+   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);
+}
+
+
+/*!
+  \ingroup NTools 
+  \class SOPHYA::DiffEqFunction
+  
+  \brief 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.
+
+  \warning statut EXPERIMENTAL , NON TESTE
+
+  \sa SOPHYA::DiffEqSolver
+*/
+
+
+
+/*!
+  \fn 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).
+*/
+
+/*!
+  \fn 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.
+*/
+
+/*!
+  \fn 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.
+*/
+
+
+//++
+// virtual void AdjustStart(Vector& start, double tstart)
+//	Pour ajuster le vecteur de départ quand il y a des 
+//	fonctions à usage interne...
+//--
+
+
+
+/*! 
+  \ingroup NTools
+  \class SOPHYA::DiffEqFcn1
+  
+  \brief 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 <br>
+  <tt> typedef double(*DIFEQFCN1)(double); </tt> <br>
+  qui retourne y' en fonction de y.
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+
+//!	Constructeur. On fournit la fonction f tq y'=f(y)
+DiffEqFcn1::DiffEqFcn1(DIFEQFCN1 fcn)
+: DiffEqFunction(1), mFcn(fcn)
+{}
+
+
+//! Implementation de Compute qui va utiliser la fonction fournie au constructeur.
+void
+DiffEqFcn1::Compute(double& fp, double f)
+{
+   fp = (*mFcn)(f);
+}
+
+/*!
+  \ingroup NTools
+  \class   SOPHYA::DiffEqFcnT1
+
+  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
+  <tt>	typedef \tt double(*DIFEQFCNT1)(double, double); </tt>
+  qui retourne y' en fonction de y et t.
+
+  \verbatim
+  Note : le système résolu est alors en fait
+  y'[0] = fcn(y[0], y[1])
+  y'[1] = 1
+  \endverbatim
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+//! Constructeur. On fournit la fonction f tq y' = f(y,t)
+DiffEqFcnT1::DiffEqFcnT1(DIFEQFCNT1 fcn)
+: 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;
+}
+
+/*!
+  \ingroup NTools
+  \class   SOPHYA::DiffEqFcn2
+  
+  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
+  <tt>	typedef double(*DIFEQFCN2)(double, double); </tt>
+  qui retourne y'' en fonction de y' et y.
+  \verbatim
+  Note : le système résolu est en fait
+  y'[0] = y[1]
+  y'[1] = f(y[1], y[0])
+  \endverbatim
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+//!   Constructeur. On fournit la fonction f tq y''=f(y',y)
+DiffEqFcn2::DiffEqFcn2(DIFEQFCN2 fcn)
+: DiffEqFunction(2), mFcn(fcn)
+{}
+
+void
+DiffEqFcn2::ComputeV(Vector& fpi, Vector const& fi)
+{
+  fpi(0) = fi(1);
+  fpi(1) = (*mFcn)(fi(1), fi(0));
+}
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::DiffEqFcnT2
+  
+  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 <br>
+  <tt> typedef double(*DIFEQFCNT2)(double, double, double); </tt> <br>
+  qui retourne y'' en fonction de y', y et t.
+  \verbatim
+  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
+  \endverbatim
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+//!	Constructeur. On fournit la fonction f tq y'' = f(y',y,t)
+DiffEqFcnT2::DiffEqFcnT2(DIFEQFCNT2 fcn)
+: 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;
+}
+
+
+/*!
+  \ingroup NTools
+  \class  SOPHYA::DiffEqFcnV
+  
+  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 <br>
+  <tt> typedef void(*DIFEQFCNV)(Vector& y2, Vector const& y1, <br>
+  Vector const& y); </tt> <br>
+  qui retourne y'' en fonction de y' et y.
+  \verbatim
+  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])
+  \endverbatim
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+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);
+}
+
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::RK4DiffEq
+  
+  Classe de résolution d'équadif par la méthode de
+  Runge-Kutta d'ordre 4.
+  Voir DiffEqSolver pour les méthodes.
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+RK4DiffEq::RK4DiffEq()
+: DiffEqSolver(), k1(10), k2(10), k3(10), k4(10)
+{}
+
+//!	Constructeur général
+RK4DiffEq::RK4DiffEq(DiffEqFunction* f)
+: DiffEqSolver(f), k1(f->NFuncReal()), 
+  k2(f->NFuncReal()), k3(f->NFuncReal()), k4(f->NFuncReal())
+{}
+
+
+//!	Constructeur pour y' = f(y)
+RK4DiffEq::RK4DiffEq(DIFEQFCN1 f)
+: 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_Nov2007/SophyaLib/NTools/difeq.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/difeq.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/difeq.h	(revision 3445)
@@ -0,0 +1,234 @@
+// 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 v  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_Nov2007/SophyaLib/NTools/dynccd.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/dynccd.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/dynccd.cc	(revision 3445)
@@ -0,0 +1,192 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "fmath.h"
+#include "perandom.h"
+
+#include "cimage.h"
+
+#include "dynccd.h"
+
+/*! 
+  \class SOPHYA::DynCCD
+  \ingroup NTools
+  
+  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.
+
+  \sa SOPHYA::Image
+*/
+
+
+/* ............................................................ */
+/* :::::::::::::  methode de la classe  DynCCD :::::::::::::::: */
+/* ............................................................ */
+
+/* --Methode-- */
+//!  Creation d'un objet DynCCD ("typ" determine la methode de calcul du bruit)
+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-- */
+//!	Modification des parametres de la dynamique
+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;
+}
+
+//!	Renvoie la valeur du bruit pour "pixel" en ADU.
+/*!
+  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  
+*/
+/* --Methode-- */
+r_8 DynCCD::Noise(r_8 pixel) const
+{
+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      */
+/* --------------------------------------------------------------  */
+
+
+/* Nouvelle-Fonction */
+/*!
+  Construit et renvoie l'image du bruit pour l'image "*pim" 
+  
+  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                                       
+*/
+template <class T>
+Image<T> NoiseImage(Image<T> const & pim, DynCCD const & dynccd)
+
+{
+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 */
+//!	Calcule l'image du bruit et le rajoute a l'image originale
+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__)
+#if defined( __IBMCPP__ )
+namespace SOPHYA {
+#endif
+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&);
+#if defined( __IBMCPP__ )
+}
+#endif
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/dynccd.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/dynccd.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/dynccd.h	(revision 3445)
@@ -0,0 +1,65 @@
+/*  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 {
+
+
+//! Readout and photon noise calculation for images
+class DynCCD 
+{
+  public :
+  enum {kConstantNoise = 0, kPhotonNoise, kSigFondNoise, kSqrtADUNoise};
+
+  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
+
+
+//! Return an image corresponding to the noise described by \b dynccd
+template <class T>
+Image<T> NoiseImage(Image<T> const & pim, DynCCD const & dynccd);
+
+//! Add noise to the image
+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_Nov2007/SophyaLib/NTools/exclude
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/exclude	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/exclude	(revision 3445)
@@ -0,0 +1,1 @@
+imageop.cc
Index: /tags/V_Nov2007/SophyaLib/NTools/fct1dfit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fct1dfit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fct1dfit.cc	(revision 3445)
@@ -0,0 +1,477 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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_Nov2007/SophyaLib/NTools/fct1dfit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fct1dfit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fct1dfit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fct2dfit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fct2dfit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fct2dfit.cc	(revision 3445)
@@ -0,0 +1,1516 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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_Nov2007/SophyaLib/NTools/fct2dfit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fct2dfit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fct2dfit.h	(revision 3445)
@@ -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 integree 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_Nov2007/SophyaLib/NTools/fftmayer.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftmayer.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftmayer.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftmayer_r4.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftmayer_r4.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftmayer_r4.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftmayer_r8.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftmayer_r8.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftmayer_r8.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftmserver.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftmserver.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftmserver.cc	(revision 3445)
@@ -0,0 +1,399 @@
+#include "sopnamsp.h"
+#include "fftmserver.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/NTools/fftmserver.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftmserver.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftmserver.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftpackc.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftpackc.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftpackc.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftpackc.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftpackc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftpackc.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/fftpserver.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftpserver.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftpserver.cc	(revision 3445)
@@ -0,0 +1,315 @@
+#include "sopnamsp.h"
+#include "fftpserver.h"
+#include "fftpackc.h"
+
+#include <iostream>
+
+
+/*! 
+  \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
+*/
+
+
+//! Constructor - If preserve_input==true, input arrays will not be overwritten.
+FFTPackServer::FFTPackServer(bool preserve_input)
+   : FFTServerInterface("FFTPackServer using extended FFTPack (C-version) package")
+  , ckR4("FFTPackServer: ", true, true) , ckR8("FFTPackServer: ", true, true),
+  _preserve_input(preserve_input)
+{
+//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(_preserve_input) );
+}
+
+
+void FFTPackServer::FFTForward(TArray< complex<r_8> > & 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> > & in, TArray< complex<r_8> > & out)
+{
+  ckR8.CheckResize(in, out);
+  out = in;
+  fftb(out.Size(), out.Data());
+}
+
+
+void FFTPackServer::FFTForward(TArray< complex<r_4> > & 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> > & in, TArray< complex<r_4> > & out)
+{
+  ckR4.CheckResize(in, out);  
+  out = in;
+  fftb(out.Size(), out.Data());
+}
+
+void FFTPackServer::FFTForward(TArray< r_4 > & in, TArray< complex<r_4> > & out)
+{
+  ckR4.CheckResize(in, out);
+  bool share = (_preserve_input) ? false : true;
+  TArray< r_4 > inout(in, share);
+  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> > & in, TArray< r_4 > & out,
+				bool usoutsz)
+{
+  ckR4.CheckResize(in, out, usoutsz);    
+  ReShapetoReal(in, out, usoutsz);
+  fftb(out.Size(), out.Data());
+}
+
+
+void FFTPackServer::FFTForward(TArray< r_8 > & in, TArray< complex<r_8> > & out)
+{
+  ckR8.CheckResize(in, out);  
+  bool share = (_preserve_input) ? false : true;
+  TArray< r_8 > inout(in, share);
+  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> > & in, TArray< r_8 > & out,
+				bool usoutsz)
+{
+  ckR8.CheckResize(in, out, usoutsz);  
+  ReShapetoReal(in, out, usoutsz);
+  fftb(out.Size(), out.Data());
+}
+
+
+template <class T>
+void FFTPack_ReShapetoReal(TArray< complex<T> > const & ina, TArray< T >  & outa, bool usz)
+{
+  TVector< complex<T> > in(ina);
+  TVector< T > out(outa);
+  sa_size_t n = in.NElts();
+  sa_size_t ncs;
+  if (usz) {
+    if ( (out.NElts() != 2*n-1) && (out.NElts() != 2*n-2) )
+      throw SzMismatchError("FFTPack_ReShapetoReal(..., true) - Wrong output array size ");
+    ncs = out.NElts();
+  }
+  else {
+    T thr = FFTArrayChecker<T>::ZeroThreshold();
+    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, 
+				  bool usz)
+{
+  FFTPack_ReShapetoReal<r_8>(in, out, usz);
+}
+
+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,
+				  bool usz)
+{
+  FFTPack_ReShapetoReal<r_4>(in, out, usz);
+}
+
+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_Nov2007/SophyaLib/NTools/fftpserver.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftpserver.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftpserver.h	(revision 3445)
@@ -0,0 +1,81 @@
+//   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(bool preserve_input=true);
+  virtual ~FFTPackServer();
+
+  // Implementation de l'interface FFTServerInterface
+
+  virtual FFTServerInterface * Clone();
+
+  // Transforme unidimensionnel sur des double
+  virtual void FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+  virtual void FFTForward(TArray< r_8 > & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< r_8 > & out, 
+			   bool usoutsz=false);
+
+  // Transforme unidimensionnel sur des float
+  virtual void FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray< r_4 > & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > & 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, bool usz);
+  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, bool usz);
+  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;
+  bool _preserve_input; // if true, input arrays not overwritten
+
+};
+
+} // Fin du namespace
+
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/fftservintf.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftservintf.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftservintf.cc	(revision 3445)
@@ -0,0 +1,490 @@
+#include "fftservintf.h"
+
+namespace SOPHYA {
+
+//// VOIR GRAND BLABLA EXPLICATIF A LA FIN DU FICHIER
+
+/*!
+  \class 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> > &, 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> > &, 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 > &, 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.
+
+  In all cases, the input/output array sizes compatibility is checked.
+  if usoutsz == false, the size of the real array is selected based on the 
+  the imaginary part of the input complex array at the nyquist frequency.
+  size_out_real = 2*size_in_complex - ( 1 or 2)   
+ */
+void FFTServerInterface::FFTBackward(TArray< complex<r_8> > &, 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> > &, 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> > &, 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 > &, 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.
+
+  In all cases, the input/output array sizes compatibility is checked.
+  if usoutsz == false, the size of the real array is selected based on the 
+  the imaginary part of the input complex array at the nyquist frequency.
+  size_out_real = 2*size_in_complex - ( 1 or 2)   
+*/
+void FFTServerInterface::FFTBackward(TArray< complex<r_4> > &, TArray< r_4 > &, bool)
+{
+  throw NotAvailableOperation("FFTServer::FFTBackward(TArray r_4 ... ) Unsupported operation !");
+}
+
+/* --Methode-- */
+/*!
+  \class 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);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8 FFTArrayChecker< r_8 >::ZeroThreshold()
+{
+  return(1.e-39);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_4 FFTArrayChecker< r_4 >::ZeroThreshold()
+{
+  return(1.e-19);
+}
+
+/* --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 
+    T thr = ZeroThreshold();   // Seuil pour tester Imag(Nyquist) == 0 
+    sa_size_t sz[BASEARRAY_MAXNDIMS];
+    if (ndg1 > 1) {
+      T imnyq = in(in.Size(0)-1,0,0).imag();
+      // Rz+cmc/Nov07 : 
+      // Calcul de la taille SizeX/Sz[0]  paire/impaire en fonction de Imag(Nyquist)
+      sz[0] = ((imnyq < -thr)||(imnyq > thr)) ? 2*in.Size(0)-1 : 2*in.Size(0)-2;
+      if (sz[0] < 1) sz[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; 
+      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;
+      if (ncs < 1)  ncs = 1;
+      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
+
+} // FIN namespace SOPHYA 
+
+
+
+/**********************************************************************
+
+Memo uniquement destine aux programmeurs:    (cmv 03/05/04)
+-- cf programme de tests explicatif: cmvtfft.cc
+
+=====================================================================
+=====================================================================
+============== Transformees de Fourier et setNormalize ==============
+=====================================================================
+=====================================================================
+
+- si setNormalize(true):  invTF{TF{S}} = S
+- si setNormalize(false): invTF{TF{S}} = N * S
+
+=====================================================================
+=====================================================================
+============== Transformees de Fourier de signaux REELS =============
+=====================================================================
+=====================================================================
+
+-------
+--- FFT d'un signal REEL S ayant un nombre pair d'elements N=2p
+-------
+  taille de la FFT: Nfft = N/2 + 1 = p + 1
+  abscisses de la fft: | 0 | 1/N | 2/N | ..... | p/N=1/2 |
+                         ^continu                 ^frequence de Nyquist
+
+  ... Ex:  N=6 -> Nfft = 6/3+1 = 4
+
+  le signal a N elements reels, la fft a Nfft elements complexes
+    cad 2*Nfft reels = 2*(p+1) reels = 2p + 2 reels = N + 2 reels
+    soit 2 reels en trop:
+    ce sont les phases du continu et de la frequence de Nyquist
+
+  relations:
+    - si setNormalize(true)  : fac = N
+         setNormalize(false) : fac = 1/N
+    sum(i=0,N-1){S(i)^2}
+                        = fac* [[ 2* sum(j=0,Nfft-1){|TF{S}(j)|^2} 
+                                 - |TF{S}(0)|^2 - |TF{S}(Nfft-1)|^2 ]]
+    (On ne compte pas deux fois le continu et la freq de Nyquist)
+     
+
+-------
+--- FFT d'un signal REEL ayant un nombre impair d'elements N=2p+1
+-------
+  taille de la FFT: Nfft = N/2 + 1 = p + 1
+  abscisses de la fft: | 0 | 1/N | 2/N | ..... | p/N |
+                         ^continu                 
+                       (la frequence de Nyquist n'y est pas)
+
+  ... Ex:  N=7 -> Nfft = 7/3+1 = 4
+
+  le signal a N elements reels, la fft a Nfft elements complexes
+    cad 2*Nfft reels = 2*(p+1) reels = 2p + 2 reels = N + 1 reels
+    soit 1 reel en trop: c'est la phase du continu
+
+  relations:
+    - si setNormalize(true)  : fac = N
+         setNormalize(false) : fac = 1/N
+    sum(i=0,N-1){S(i)^2}
+                        = fac* [[ 2* sum(j=0,Nfft-1){|TF{S}(j)|^2} 
+                                 - |TF{S}(0)|^2 ]]
+    (On ne compte pas deux fois le continu)
+
+
+------------
+--- FFT-BACK d'un signal F=TF{S} ayant un nombre d'elements Nfft
+------------
+  Sback = invTF{TF{S}}
+
+  Remarque: Nfft a la meme valeur pour N=2p et N=2p+1
+            donc Nfft conduit a 2 possibilites:
+                 { N = 2*(Nfft-1)  signal back avec nombre pair d'elements
+                 { N = 2*Nfft-1    signal back avec nombre impair d'elements
+
+  Pour savoir quel est la longueur N du signal TF^(-1){F} on regarde
+    si F(Nfft-1) est reel ou complexe
+       (la frequence de Nyquist d'un signal reel est reelle)
+
+    - Si F(Nfft-1) reel      cad  Im{F(Nfft-1)}=0:  N = 2*(Nfft-1)
+    - Si F(Nfft-1) complexe  cad  Im{F(Nfft-1)}#0:  N = 2*Nfft-1
+
+  Si setNormalize(true):  invTF{TF{S}} = S
+     setNormalize(false): invTF{TF{S}} = N * S
+
+=========================================================================
+=========================================================================
+============== Transformees de Fourier de signaux COMPLEXES =============
+=========================================================================
+=========================================================================
+
+-------
+--- FFT d'un signal COMPLEXE S ayant un nombre d'elements N
+-------
+  taille de la FFT: Nfft = N
+  abscisses de la fft: | 0 | 1/N | 2/N | ..... | (N-1)/N |
+                         ^continu
+
+  Frequence de Nyquist:
+    si N est pair: la frequence de Nyquist est l'absicce d'un des bins
+      abscisses de TF{S}: Nfft = N = 2p
+      | 0 | 1/N | 2/N | ... | (N/2)/N=p/N=0.5 | ... | (N-1)/N |
+                                     ^frequence de Nyquist
+    si N est impair: la frequence de Nyquist N'est PAS l'absicce d'un des bins
+      abscisses de TF{S}: Nfft = N = 2p+1
+      | 0 | 1/N | 2/N | ... | (N/2)/N=p/N | ((N+1)/2)/N=(p+1)/N  | ... | (N-1)/N |
+
+  ... Ex: N = 2p =6  ->  Nfft = 2p = 6
+      abscisses de TF{S}: | 0 | 1/6 | 2/6 | 3/6=0.5 | 4/6 | 5/6 |
+  ... Ex: N = 2p+1 = 7   ->  Nfft = 2p+1 = 7
+      abscisses de TF{S}: | 0 | 1/7 | 2/7 | 3/7 | 4/7 | 5/7 | 6/7 |
+
+  relations:
+    - si setNormalize(true)  : fac = N
+         setNormalize(false) : fac = 1/N
+    sum(i=0,N-1){S(i)^2} = fac* [[ sum(j=0,Nfft-1){|TF{S}(j)|^2} ]]
+
+------------
+--- FFT-BACK d'un signal F=TF{S} ayant un nombre d'elements Nfft
+------------
+  taille du signal: N = Nfft
+
+  Si setNormalize(true):  invTF{TF{S}} = S
+     setNormalize(false): invTF{TF{S}} = N * S
+
+**********************************************************************/
Index: /tags/V_Nov2007/SophyaLib/NTools/fftservintf.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fftservintf.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fftservintf.h	(revision 3445)
@@ -0,0 +1,82 @@
+//   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<r_4> & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray<r_8> & in, TArray< complex<r_8> > & out); 
+  virtual void FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+
+  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray<r_4> & out,bool usoutsz=false);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray<r_8> & out,bool usoutsz=false);
+  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
+
+ 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_Nov2007/SophyaLib/NTools/fmath.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/fmath.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/fmath.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/functab.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/functab.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/functab.cc	(revision 3445)
@@ -0,0 +1,125 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <math.h>
+#include <string.h>
+#include <string>
+
+#include "pexceptions.h"
+#include "functab.h"
+
+/*!
+  \class SOPHYA::FuncTab
+  \ingroup NTools
+  Function tabulation
+*/
+
+/* --Methode-- */
+//! Constructor
+/*!
+  \param func : function to be tabulated
+  \param ntab : number of tabulated points
+  \param xmin xmax : tabulate from xmin to max
+  \verbatim
+  - Tabul[1] contient func(xmin), Tabul[NTab] contient func(xmax)
+  - ATTENTION: Tabul[i]   contient func(xmin + (i-1)*Dx)
+               Tabul[i+1] contient func(xmin + i*Dx)
+  - Tabul[0] et Tabul[NTab+1] servent pour interpoler rapidement
+    Par defaut Tabul[0] contient Tabul[1] (=func(xmin))
+               Tabul[NTab+1] contient Tabul[NTab] (=func(xmax))
+    Ces valeurs peuvent etre changees avec les methodes SetLimVal
+    Si la fonction existe pour x<xmin et x>xmax alors le mieux est
+       d'utiliser la methode SetLimVal(void):
+            Tabul[0]      = func(xmin-dx)
+            Tabul[NTab+1] = func(xmax+dx)
+    Si la fonction n'existe pas pour x<xmin et x>xmax utiliser
+            la methode SetLimVal(val0,valn):
+            Tabul[0]      = val0
+            Tabul[NTab+1] = valn
+  \endverbatim
+
+ */
+FuncTab::FuncTab(double (*func)(double const),uint_4 ntab,r_8 xmin,r_8 xmax)
+{
+  cout<<"func="<<func<<endl;
+  if(ntab<=1) ntab = 10;
+  if(xmin>=xmax) {xmin=0.; xmax=1.;}
+  NTab = ntab;
+  XMin = xmin;
+  XMax = xmax;
+  Func = func;
+  Dx = (r_8)(XMax-XMin)/(r_8)(NTab-1);
+  Tabul = new r_8[NTab+2];
+  for(int_4 i=0;i<NTab+2;i++) Tabul[i] = 0.;
+  PInterpL = PInterpP[0] = PInterpP[1] = NULL;
+  if(!Tabul) return;
+  for(int_4 i=0;i<NTab;i++) Tabul[i+1] = func(XMin + i*Dx);
+  Tabul[0] = Tabul[1];
+  Tabul[NTab+1] = Tabul[NTab];
+}
+
+/* --Methode-- */
+//! Destructor
+FuncTab::~FuncTab(void)
+{
+  if(Tabul) {delete [] Tabul; Tabul=NULL;}
+  if(PInterpL) {delete [] PInterpL; PInterpL=NULL;}
+}
+
+/* --Methode-- */
+//! Set automatically values for the index [0] and [NTab+1]
+/*! Set automatically values for the index [0] and [NTab+1]
+  That is needed for fast interpolation
+  Value are set for xmin-dx and xmax+dx
+ */
+void FuncTab::SetLimVal(void)
+{
+  Tabul[0] = Func(XMin-Dx);
+  Tabul[NTab+1] = Func(XMax+Dx);
+}
+
+
+/* --Methode-- */
+//! Give values for the index [0] and [NTab+1]
+/*! Set automatically values for the index [0] and [NTab+1]
+  That is needed for fast interpolation
+ */
+void FuncTab::SetLimVal(r_8 val0,r_8 valn)
+{
+  Tabul[0] = val0;
+  Tabul[NTab+1] = valn;
+}
+
+/* --Methode-- */
+//! Construc table for linear and parabolic interpolation
+/*!
+  \param typ : 0=nearest tabulated value, 1=linear, 2=parabolic
+  \warning For speed consideration, no protection is done
+           in the corresponding Value?() inline routine.
+ */
+void FuncTab::SetInterp(uint_2 typ)
+{
+  if(typ==1) {  // Linear Interpolation between two consecutive values
+
+    if(PInterpL) delete [] PInterpL;
+    PInterpL = new r_8[NTab+2];
+    for(int_4 i=0;i<NTab+1;i++)
+      PInterpL[i] = (Tabul[i+1]-Tabul[i])/Dx;
+    PInterpL[NTab+1] = 0.;
+
+  } else if(typ==2) {
+
+    if(PInterpP[0]) delete [] PInterpP[0];
+    if(PInterpP[1]) delete [] PInterpP[1];
+    PInterpP[0] = new r_8[NTab+2];
+    PInterpP[1] = new r_8[NTab+2];
+    for(int_4 i=1;i<=NTab;i++) {
+      PInterpP[0][i] = (Tabul[i+1]+Tabul[i-1]-2.*Tabul[i])/(2.*Dx*Dx);
+      PInterpP[1][i] = (Tabul[i+1]-Tabul[i-1])/(2.*Dx);
+    }
+    PInterpP[0][0]=PInterpP[0][NTab+1]=PInterpP[1][0]=PInterpP[1][NTab+1]=0.;
+
+  }
+}
Index: /tags/V_Nov2007/SophyaLib/NTools/functab.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/functab.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/functab.h	(revision 3445)
@@ -0,0 +1,56 @@
+#ifndef FUNCTAB_SEEN
+#define FUNCTAB_SEEN
+
+#include "machdefs.h"
+#include "tvector.h"
+#include "tarray.h"
+
+namespace SOPHYA {
+
+class FuncTab {
+public:
+  FuncTab(double (*func)(double const),uint_4 nbin,r_8 xmin,r_8 xmax);
+  virtual ~FuncTab(void);
+
+  //! Give values for the index [0] and [NTab+1]
+  void SetLimVal(void);
+  void SetLimVal(r_8 val0,r_8 valn);
+
+  //! Interpolation type
+  void SetInterp(uint_2 typ=0);
+
+  //! L'index de la valeur tabulee la plus proche de x (entre 1 et NTab)
+  inline uint_4 IndexNear(r_8 x)
+    {uint_4 i=(uint_4)((x-XMin)/Dx+0.5) +1; return (i>NTab)? NTab: i;}
+  //! L'index de la valeur tabulee juste inferieure a x (entre 1 et NTab)
+  inline uint_4 IndexLow(r_8 x)
+    {uint_4 i=(uint_4)((x-XMin)/Dx) +1; return (i>NTab)? NTab: i;}
+
+  //! L'abscisse pour la valeur i de l'index
+  inline r_8 X(uint_4 i) {return XMin+(i-1)*Dx;}
+
+  //! Le valeur tabulee la plus proche de x
+  inline r_8 Value(r_8 x) {return Tabul[IndexNear(x)];}
+
+  //! L'interpolation lineaire dans le bin (attention no-protection for time saving)
+  inline r_8 ValueL(r_8 x)
+    {uint_4 i=IndexLow(x);
+     return Tabul[i]+PInterpL[i]*(x-X(i));}
+
+  //! L'interpolation parabolique (attention no-protection for time saving)
+  inline r_8 ValueP(r_8 x)
+  {uint_4 i=IndexLow(x); x -= X(i);
+     return Tabul[i]+PInterpP[0][i]*x*x+PInterpP[1][i]*x;}
+
+protected:
+  double (*Func)(double const);
+  uint_4 NTab;
+  r_8 XMin,XMax,Dx;
+  r_8 *Tabul;
+  r_8 *PInterpL;
+  r_8 *PInterpP[2];
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/generaldata.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generaldata.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generaldata.cc	(revision 3445)
@@ -0,0 +1,1193 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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"
+
+namespace SOPHYA {
+
+//================================================================
+// GeneralFitData
+//================================================================
+
+/*!
+  \class 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(uint_4 nVar, uint_4 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_4 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++;
+   }
+ }
+
+}
+
+/*!
+  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)
+{
+}
+
+/*!
+  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.
+*/
+void GeneralFitData::Alloc(uint_4 nVar, uint_4 ndatalloc, uint_2 errx)
+{
+Delete();
+if(nVar<=0 || ndatalloc<=0) return;
+
+mNVar = nVar;
+mNDataAlloc = ndatalloc;
+
+try {
+  mXP = new r_8[nVar*ndatalloc]; memset(mXP,0,nVar*ndatalloc*sizeof(r_8));
+  if(errx) {
+    mErrXP = new r_8[nVar*ndatalloc]; memset(mErrXP,0,nVar*ndatalloc*sizeof(r_8));
+    mOk_EXP = errx;
+  }
+  mF = new r_8[ndatalloc]; memset(mF,0,ndatalloc*sizeof(r_8));
+  mErr = new r_8[ndatalloc]; memset(mErr,0,ndatalloc*sizeof(r_8));
+  mOK = new uint_2[ndatalloc]; memset(mOK,0,ndatalloc*sizeof(uint_2));
+  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; mOk_EXP = 0;}
+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_4 ptr)
+{
+ if(ptr<0 || ptr>=mNDataAlloc) return;
+ mNData = ptr;
+ mNDataGood = 0;
+ if(ptr==0) return;
+ for(int_4 i=0;i<mNData;i++) if(mOK[i]) mNDataGood++;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Operateur gd1 = gd2
+*/
+GeneralFitData& GeneralFitData::operator = (const GeneralFitData& g)
+{
+ if(this == &g) return *this;
+
+ Alloc(g.mNVar,g.mNDataAlloc,g.mOk_EXP);
+ mNData = g.mNData;
+ mNDataGood = g.mNDataGood;
+
+ if(g.mXP) memcpy(mXP,g.mXP,mNVar*mNDataAlloc*sizeof(r_8));
+ if(g.mErrXP) memcpy(mErrXP,g.mErrXP,mNVar*mNDataAlloc*sizeof(r_8));
+ if(g.mF) memcpy(mF,g.mF,mNDataAlloc*sizeof(r_8));
+ if(g.mErr) memcpy(mErr,g.mErr,mNDataAlloc*sizeof(r_8));
+ if(g.mOK) memcpy(mOK,g.mOK,mNDataAlloc*sizeof(uint_2));
+
+ return *this;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour tuer un point
+*/
+void GeneralFitData::KillData(int_4 i)
+{
+ if(i<0 || i>=mNData) return;
+
+ if( ! mOK[i] ) return;
+ mOK[i] = 0;
+ mNDataGood--;
+}
+
+/*!
+  Pour tuer une serie de points
+*/
+void GeneralFitData::KillData(int_4 i1,int_4 i2)
+{
+ if(i1<0 || i1>=mNData) return;
+ if(i2<0 || i2>=mNData) return;
+ if(i1>i2) return;
+
+ for(int_4 i=i1;i<=i2;i++) KillData(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour re-valider le point numero i ([0,NData]).
+*/
+void GeneralFitData::ValidData(int_4 i)
+{
+ if(i<0 || i>=mNData) return;
+
+ if( mOK[i] ) return;
+ if( mErr[i]<=0. ) return;
+ if(mOk_EXP) {
+   for(int_4 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_4 i1,int_4 i2)
+{
+ if(i1<0 || i1>=mNData) return;
+ if(i2<0 || i2>=mNData) return;
+ if(i1>i2) return;
+
+ for(int_4 i=i1;i<=i2;i++) ValidData(i);
+}
+
+/*!
+  Pour re-valider tous les points.
+*/
+void GeneralFitData::ValidData()
+{
+ for(int_4 i=0;i<mNData;i++) ValidData(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour redefinir un point a \f$ {x,[errx] ; f,err} \f$
+*/
+void GeneralFitData::RedefineData1(int_4 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_4 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_4 i,double* xp,double f,double err,double* errxp)
+{
+ if(i<0 || i>=mNData) return;
+ bool ok = true;
+
+ int_4 ip = mNVar*i;
+ for(int_4 j=0;j<mNVar;j++) mXP[ip+j] = xp[j];
+ if(mOk_EXP) {
+   if(errxp) {
+     for(int_4 j=0;j<mNVar;j++)
+       {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
+   } else {
+     for(int_4 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)
+{
+ if(mNData >= mNDataAlloc)
+   {cout<<"GeneralFitData::AddData Error: no space left"<<endl;; return;}
+
+ bool ok = true;
+
+ int_4 ip = mNVar*mNData;
+ for(int_4 i=0;i<mNVar;i++) mXP[ip+i] = xp[i];
+ if(mOk_EXP) {
+   if(errxp) {
+     for(int_4 j=0;j<mNVar;j++)
+       {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
+   } else {
+     for(int_4 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_4 i=0;i<mNVar;i++) BuffVar[i] = (double) xp[i];}
+ if(errxp) for(int_4 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_4 nData
+            , double* x, double* f, double *err, double *errx)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData1 Error: no space left"<<endl;; return;}
+
+ for(int_4 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_4 nData
+            , float* x, float* f, float* err, float *errx)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData1 Error: no space left"<<endl;; return;}
+
+ for(int_4 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_4 nData, double* x, double* y, double* f
+                             ,double *err,double *errx,double *erry)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData2 Error: no space left"<<endl;; return;}
+
+ for(int_4 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_4 nData, float* x, float* y, float* f
+                             ,float *err,float *errx,float *erry)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData2 Error: no space left"<<endl;; return;}
+
+ for(int_4 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_4 nData,double** xp, double *f
+                            , double *err, double** errxp)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData Error: no space left"<<endl;; return;}
+
+ if(mOk_EXP && !errxp) {for(int_4 j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
+
+ for(int_4 i=0;i<nData;i++) {
+   {for(int_4 j=0;j<mNVar;j++) BuffVar[j] = *(xp[j]+i);}
+   if(mOk_EXP && errxp)
+     {for(int_4 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_4 nData,float** xp, float *f
+                            , float *err, float** errxp)
+{
+ if(nData<=0) return;
+ if(mNData+nData>mNDataAlloc)
+   {cout<<"GeneralFitData::SetData Error: no space left"<<endl;; return;}
+
+ if(mOk_EXP && !errxp) {for(int_4 j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
+
+ for(int_4 i=0;i<nData;i++) {
+   {for(int_4 j=0;j<mNVar;j++) BuffVar[j] = (double) *(xp[j]+i);}
+   if(mOk_EXP && errxp)
+     {for(int_4 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_4 i) const
+{
+ if(i<0 || i>=mNData) return;
+
+ cout<<" "<<i<<" F( ";
+ {for(int_4 j=0;j<mNVar;j++) cout<<" "<<Absc(j,i);}
+ if(mOk_EXP) {
+   cout<<"  ;  ";
+   for(int_4 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_4 i1,int_4 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_4 i=i1;i<=i2;i++) PrintData(i);
+ cout<<flush;
+}
+
+/*!
+  Impression de tous les points
+*/
+void GeneralFitData::PrintData() const
+{
+  if(mNData<=0) return;
+
+ 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_4 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_4 GeneralFitData::GetMnMx(int_4 var,int_4& imin,int_4& imax) const
+{
+imin = imax = -1;
+int_4 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_4 ntest = 0;
+for(int_4 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_4 GeneralFitData::GetMnMx(int_4 var,double& min,double& max) const
+{
+min = 1.; max = -1.;
+int_4 imin,imax;
+int_4 ntest = GetMnMx(var,imin,imax);
+if(ntest<=0) return ntest;
+int_4 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_4 GeneralFitData::GetMeanSigma(int_4 var,double& mean,double& sigma,double min,double max) const
+{
+mean = sigma = 0.;
+int_4 ix = var/10;
+var = var%10;
+if(var<0 || var>3) return -1;
+if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
+int_4 ntest = 0;
+for(int_4 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_4 GeneralFitData::GetMoMeMed(int_4 var,double& mode,double& mean,double& median,
+                               double min,double max,double coeff) const
+{
+mode = mean = median = 0.;
+if(mNData<=0) return -1;
+int_4 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_4 ntest = 0;
+for(int_4 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_4 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_4 GeneralFitData::GetMode(int_4 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_4 varx,Poly& pol,int_4 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_4 ntest = 0;
+for(int_4 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_4 varx,int_4 vary,Poly2& pol,int_4 degre1,int_4 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_4 ntest = 0;
+for(int_4 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_4 n, r_8* ret)   const
+{
+int_4 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_4 n, r_4* ret)   const
+{
+if (ret == NULL) ret = BuffVarR4;
+double *buff = new double[2*mNVar+3];
+GetVec(n,buff);
+for(int_4 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)
+*/
+sa_size_t 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)
+*/
+sa_size_t GeneralFitData::NbColumns() const
+{
+return(2*NVar()+3);
+}
+
+//! Pour interface NTuple
+r_8 * GeneralFitData::GetLineD(sa_size_t n) const
+{
+return(GetVec(n,NULL));
+}
+
+//! Pour interface NTuple
+r_8 GeneralFitData::GetCell(sa_size_t n, sa_size_t 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(sa_size_t n, string const & nom) const
+{
+sa_size_t k = ColumnIndex(nom);
+return(GetCell(n,k));
+}
+
+/*!
+  Retourne le minimum et le maximum de la variable `k' (pour interface NTuple).
+*/
+void GeneralFitData::GetMinMax(sa_size_t k, double& min, double& max)  const
+{
+int_4 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
+{
+sa_size_t k = ColumnIndex(nom);
+GetMinMax(k,min,max);
+}
+
+//! Pour interface NTuple
+sa_size_t GeneralFitData::ColumnIndex(string const & nom)  const
+{
+char str[64]; int_4 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(sa_size_t 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_4 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 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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,dobj->mOk_EXP);
+dobj->mNData = ndata;
+dobj->mNDataGood = ndatagood;
+
+// Lecture des datas
+is.GetLine(strg, 255);
+int_4 blen = dobj->mNVar + 3;
+if(dobj->mOk_EXP) blen += dobj->mNVar;
+double *buff = new double[blen];
+for(int_4 i=0;i<dobj->mNData;i++) {
+  is.Get(buff, blen);
+  int_4 ip = i*dobj->mNVar;
+  {for(int_4 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_4 j=0;j<dobj->mNVar;j++)
+                        dobj->mErrXP[ip+j] = buff[dobj->mNVar+3+j];}
+}
+delete [] buff;
+
+return;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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_4 blen = dobj->mNVar + 3;
+if(dobj->mOk_EXP) blen += dobj->mNVar;
+double *buff = new double[blen];
+for(int_4 i=0;i<dobj->mNData;i++) {
+  {for(int_4 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_4 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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/NTools/generaldata.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generaldata.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generaldata.h	(revision 3445)
@@ -0,0 +1,204 @@
+// 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>
+#include "pexceptions.h"
+#include "ppersist.h"
+#include "ntupintf.h"
+#include "poly.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+template <class T>  class FitsHandler;
+
+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>;
+  friend class FitsHandler<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(uint_4 nVar, uint_4 nDataAlloc, uint_2 errx=0);
+  GeneralFitData(const GeneralFitData& data, bool clean=false);
+  GeneralFitData();
+  virtual ~GeneralFitData();
+
+  void SetDataPtr(int_4 ptr = 0);
+
+  void KillData(int_4 i);
+  void KillData(int_4 i1,int_4 i2);
+
+  void ValidData(int_4 i);
+  void ValidData(int_4 i1,int_4 i2);
+  void ValidData();
+
+  void RedefineData1(int_4 i,double x,double f,double err=Def_ErrF,double errx=Def_ErrX);
+  void RedefineData2(int_4 i,double x,double y,double f,double err=Def_ErrF
+                    ,double errx=Def_ErrX,double erry=Def_ErrX);
+  void RedefineData(int_4 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_4 nData,double* x,double* f,double *err=NULL,double *errx=NULL);
+  void SetData1(int_4 nData,float* x,float* f,float* err=NULL,float *errx=NULL);
+  void SetData2(int_4 nData,double* x,double* y,double* f,double *err=NULL
+               ,double *errx=NULL,double *erry=NULL);
+  void SetData2(int_4 nData,float* x,float* y,float* f,float* err=NULL
+               ,float *errx=NULL,float *erry=NULL);
+  void SetData(int_4 nData,double** xp,double *f,double *err=NULL,double** errxp=NULL);
+  void SetData(int_4 nData,float** xp,float* f,float* err=NULL,float** errxp=NULL);
+
+  void PrintStatus() const;
+  void PrintData(int_4 i) const;
+  void PrintData(int_4 i1,int_4 i2) const;
+  void PrintData() const;
+  void Show(ostream& os) const;
+  inline void Show() const {Show(cout);}
+
+  //! Operator equal
+  GeneralFitData& operator = (const GeneralFitData& g);
+
+  //! Retourne la place restante dans la structure (nombre de donnees que l'on peut encore stoquer).
+  inline int_4 GetSpaceFree() const { return mNDataAlloc - mNData; }
+  //! Retourne le nombre de variables Xi
+  inline int_4 NVar()       const {return mNVar;}
+  //! Retourne le nombre de donnees
+  inline int_4 NData()      const {return mNData;}
+  //! Retourne le nombre de bonnes donnees (utilisees pour le fit)
+  inline int_4 NDataGood()  const {return mNDataGood;}
+  //! Retourne la place maximale allouee pour les donnees
+  inline int_4 NDataAlloc() const {return mNDataAlloc;}
+
+  //! Retourne 1 si point valide, sinon 0
+  inline unsigned short IsValid(int_4 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_4 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_4 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_4 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_4 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_4 j,int_4 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_4 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_4 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_4 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_4 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_4 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_4 j,int_4 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_4 i) const
+                {if(i>=0 && i<mNData) return mErr[i]; else return 0.;}
+
+  r_8* GetVec(int_4 n, r_8* ret=NULL) const;
+  r_4* GetVecR4(int_4 n, r_4* ret=NULL) const;
+  int_4 GetMnMx(int_4 var,int_4& imin,int_4& imax) const;
+  int_4 GetMnMx(int_4 var,double& min,double& max) const;
+  int_4 GetMeanSigma(int_4 var,double& mean,double& sigma,double min=1.,double max=-1.) const;
+  int_4 GetMoMeMed(int_4 var,double& mode,double& mean,double& median,
+                 double min=1.,double max=-1.,double coeff=0.8) const;
+  int_4 GetMode(int_4 var,double& mode,double min=1.,double max=-1.,double coeff=0.8) const;
+  double PolFit(int_4 varx,Poly& pol,int_4 degre,bool ey=true,double xc=0.) const;
+  double PolFit(int_4 varx,int_4 vary,Poly2& pol,int_4 degre1,int_4 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 sa_size_t     NbLines() const;
+  virtual sa_size_t     NbColumns() const;
+  virtual r_8 *         GetLineD(sa_size_t n) const;
+  virtual r_8		GetCell(sa_size_t n, sa_size_t k) const;
+  virtual r_8		GetCell(sa_size_t n, string const & nom) const;
+  virtual void		GetMinMax(sa_size_t k, double& min, double& max) const; 
+  virtual void		GetMinMax(string const & nom, double& min, double& max) const;
+  virtual sa_size_t     ColumnIndex(string const & nom) const;
+  virtual string        ColumnName(sa_size_t 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 Alloc(uint_4 nVar, uint_4 nDataAlloc, uint_2 errx=0);
+  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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<GeneralFitData>
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/generalfit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generalfit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generalfit.cc	(revision 3445)
@@ -0,0 +1,1604 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <string.h>
+#include <string>
+
+#include "pexceptions.h"
+#include "generalfit.h"
+#include "sopemtx.h"
+
+#define EPS_FIT_MIN 1.e-8
+
+//================================================================
+// 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];
+}
+
+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
+
+}
+
+/*!
+  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
+
+}
+
+//
+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 NullPtrError("GeneralFit::WriteStep()");
+}
+
+/*!
+  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_Nov2007/SophyaLib/NTools/generalfit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generalfit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generalfit.h	(revision 3445)
@@ -0,0 +1,206 @@
+// 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"
+#include "generalfunc.h"
+
+namespace SOPHYA {
+
+//================================================================
+// GeneralXi2
+//================================================================
+
+//! 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_Nov2007/SophyaLib/NTools/generalfunc.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generalfunc.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generalfunc.cc	(revision 3445)
@@ -0,0 +1,171 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <string.h>
+#include <string>
+
+#include "pexceptions.h"
+#include "generalfunc.h"
+
+//================================================================
+// 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)
+{
+ if(nVar==0 || nPar==0)
+   throw SzMismatchError("GeneralFunction::GeneralFunction_Error: nVar==0 || nPar==0 !");
+ deltaParm = new double[nPar];
+ tmpParm   = new double[nPar];
+}
+
+GeneralFunction::~GeneralFunction()
+{
+ if(deltaParm != NULL) delete[] deltaParm;
+ if(tmpParm != NULL) 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)
+{
+ if(numPar<0 || numPar >= mNPar)
+   throw SzMismatchError("GeneralFunction::SetDeltaParm_Error: 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);
+}
+
Index: /tags/V_Nov2007/SophyaLib/NTools/generalfunc.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/generalfunc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/generalfunc.h	(revision 3445)
@@ -0,0 +1,62 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef GENERALFUNC_SEEN
+#define GENERALFUNC_SEEN
+
+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*);
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/genericfunc.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/genericfunc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/genericfunc.h	(revision 3445)
@@ -0,0 +1,45 @@
+#ifndef GENERICFUNC_H
+#define GENERICFUNC_H
+
+#include "pexceptions.h"
+#include "classfunc.h"
+#include <vector>
+
+namespace SOPHYA {
+
+//! Abstract interface definition for functions viewed as classes
+  class GenericFunc : public ClassFunc {
+public:
+  GenericFunc(void) { }
+  virtual ~GenericFunc(void) { }
+
+  virtual double operator()(double x) {
+    cout<<"GenericFunc::operator(double) not implemented"<<endl;
+    throw NotAvailableOperation("GenericFunc::operator(double) not implemented");
+  }
+
+  virtual double operator()(double x,double y) {
+    cout<<"GenericFunc::operator(double,double) not implemented"<<endl;
+    throw NotAvailableOperation("GenericFunc::operator(double,double) not implemented");
+  }
+
+  virtual double operator()(double x,double y,double z) {
+    cout<<"GenericFunc::operator(double,double,double) not implemented"<<endl;
+    throw NotAvailableOperation("GenericFunc::operator(double,double,double) not implemented");
+  }
+
+  virtual double operator()(double* x) {
+    cout<<"GenericFunc::operator(double*) not implemented"<<endl;
+    throw NotAvailableOperation("GenericFunc::operator(double*) not implemented");
+  }
+
+  virtual double operator()(vector<double>& x) {
+    cout<<"GenericFunc::operator(vector<double>&) not implemented"<<endl;
+    throw NotAvailableOperation("GenericFunc::operator(vector<double>&) not implemented");
+  }
+
+};
+
+}  // Fin namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/history_eros
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/history_eros	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/history_eros	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/imageop.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/imageop.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/imageop.cc	(revision 3445)
@@ -0,0 +1,1315 @@
+#include "sopnamsp.h"
+#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 RangeCheckError("imageop.cc - CHECKIMG2") ;  \
+      if (!(_img_).ImagePtr()) throw NullPtrError("imageop.cc - CHECKIMG2")
+#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_Nov2007/SophyaLib/NTools/imageop.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/imageop.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/imageop.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/integ.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/integ.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/integ.cc	(revision 3445)
@@ -0,0 +1,481 @@
+#include "sopnamsp.h"
+#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)
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::Integrator
+
+  \brief Classe abstraite d'intégration numérique 1D.
+
+  On fournit une fonction double f(double) au constructeur, ou
+  une classe-fonction (ClassFuc) 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.
+
+  \sa TrpzInteg GLInteg
+*/
+
+//!  Constructeur par défaut. L'objet n'est pas utilisable en l'état.
+Integrator::Integrator()
+: mFunc(NULL), mClFun(NULL), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+//! Constructeur à partir d'une classe-fonction, et des bornes d'intégration.
+Integrator::Integrator(ClassFunc & f, double xmin, double xmax)
+: mFunc(NULL), mClFun(&f), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{}
+
+//! Constructeur à partir de la fonction double->double, et des bornes d'intégration.
+Integrator::Integrator(FUNC f, double xmin, double xmax)
+: mFunc(f), mClFun(NULL), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{}
+
+
+/*!
+  Constructeur a partir d'une classe-fonction 
+  sans spécifier les bornes. Elles sont positionnées
+  à [0,1], et on pourra les modifier plus tard.
+*/
+Integrator::Integrator(ClassFunc & f)
+: mFunc(NULL), mClFun(&f), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+/*!
+  Constructeur sans spécifier les bornes. Elles sont positionnées
+  à [0,1], et on pourra les modifier plus tard.
+*/
+Integrator::Integrator(FUNC f)
+: mFunc(f), mClFun(NULL), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+/*!
+  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.
+*/
+Integrator::Integrator(GeneralFunction* gff, double* par, double xmin, double xmax)
+: mFunc(NULL), mClFun(NULL), mGFF(gff), mGFFParm(par),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{
+  DBASSERT(gff->NVar() == 1);
+}
+
+/*!
+  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.
+*/
+Integrator::Integrator(GeneralFunction* gff, double* par)
+: mFunc(NULL), mClFun(NULL), mGFF(gff), mGFFParm(par),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{
+  DBASSERT(gff->NVar() == 1);
+}
+
+Integrator::~Integrator()
+{
+}
+
+
+/*! 
+  \brief Spécifie le nombre de pas pour l'intégration numérique.
+  
+  La signification peut dépendre de la méthode d'intégration.
+*/
+Integrator& 
+Integrator::NStep(int n)
+{
+  mNStep = n;
+  mDX = mReqPrec = -1;
+  StepsChanged();
+  return *this;
+}
+
+/*! 
+  \brief Spécifie le nombre de pas pour l'intégration numérique.
+  
+  La signification peut dépendre de la méthode d'intégration.
+*/
+Integrator& 
+Integrator::DX(double d)
+{
+  mDX = d;
+  mNStep = -1;
+  mReqPrec = -1.;
+  StepsChanged();
+  return *this;
+}
+
+/*!
+  \brief 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.
+*/
+Integrator& 
+Integrator::ReqPrec(double p)
+{
+  DBASSERT( !"Pas encore implemente !");
+  mReqPrec = p;
+  mDX = mNStep = -1;
+  StepsChanged();
+  return *this;
+}
+
+//! Spécifie les bornes de l'intégrale.
+Integrator& 
+Integrator::Limits(double xmin, double xmax)
+{
+  mXMin = xmin;
+  mXMax = xmax;
+  LimitsChanged();
+  return *this;
+}
+
+//! Spécifie la fonction à intégrer, sous forme double f(double).
+Integrator& 
+Integrator::SetFunc(ClassFunc & f)
+{
+  mFunc = NULL;
+  mClFun = &f;
+  mGFFParm = NULL;
+  mFunc = NULL;
+  FuncChanged();
+  return *this;
+}
+
+//! Spécifie la fonction à intégrer, sous forme double f(double).
+Integrator& 
+Integrator::SetFunc(FUNC f)
+{
+  mFunc = f;
+  mClFun = NULL;
+  mGFFParm = NULL;
+  mFunc = NULL;
+  FuncChanged();
+  return *this;
+}
+
+/*!
+  \brief Spécifie la fonction à intégrer, sous forme de GeneralFunction 
+  à une variable, et les paramètres sont fournis.
+*/
+Integrator& 
+Integrator::SetFunc(GeneralFunction* gff, double* par)
+{
+  mGFF = gff;
+  mGFFParm = par;
+  mFunc = NULL;
+  DBASSERT(gff->NVar() == 1);
+  FuncChanged();
+  return *this;
+}
+
+double
+Integrator::FVal(double x) const
+{
+  DBASSERT( mFunc || mClFun || (mGFF && mGFFParm) );
+  if (mFunc) return mFunc(x);
+  else return mClFun ? (*mClFun)(x) : mGFF->Value(&x, mGFFParm); 
+}
+
+double
+Integrator::ValueBetween(double xmin, double xmax)
+{
+  Limits(xmin,xmax);
+  return Value();
+}
+
+void
+Integrator::Print(int lp)
+{
+ cout<<"Integrator between "<<mXMin<<" and "<<mXMax
+     <<" in "<<mNStep<<" steps"<<endl;
+ if(lp>1) cout<<"mFunc="<<mFunc<<"mClFun="<<mClFun<<"mGFF="<<mGFF
+              <<"mReqPrec="<<mReqPrec<<"mDX="<<mDX<<endl;
+}
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::TrpzInteg
+
+  \brief Implementation de Integrator par la methode des trapezes.
+  
+  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.
+  
+  \sa SOPHYA::Integrator
+*/
+
+
+TrpzInteg::TrpzInteg()
+{}
+
+TrpzInteg::TrpzInteg(ClassFunc & f, double xmin, double xmax)
+: Integrator(f, xmin, xmax)
+{}
+
+TrpzInteg::TrpzInteg(FUNC f, double xmin, double xmax)
+: Integrator(f, xmin, xmax)
+{}
+
+TrpzInteg::TrpzInteg(ClassFunc & f)
+: Integrator(f)
+{}
+
+TrpzInteg::TrpzInteg(FUNC 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()
+{}
+
+//! Return the value of the integral.
+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;
+}
+
+
+
+/*!
+  \ingroup NTools
+  \class SOPHYA::GLInteg
+  
+  \brief Implementation de Integrator par la methode de Gauss-Legendre.
+
+  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 (monome le + haut x^(2*n-1).
+  Impossible de demander une précision donnée.
+
+  \sa SOPHYA::Integrator
+
+  \warning statut EXPERIMENTAL , NON TESTE
+*/
+
+
+
+GLInteg::GLInteg()
+: mXPos(NULL), mWeights(NULL)
+{}
+
+
+GLInteg::GLInteg(ClassFunc & f, double xmin, double xmax)
+: Integrator(f, xmin, xmax), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+GLInteg::GLInteg(FUNC f, double xmin, double xmax)
+: Integrator(f, xmin, xmax), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+GLInteg::GLInteg(ClassFunc & f)
+: Integrator(f), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+GLInteg::GLInteg(FUNC 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()
+{
+ if(mXPos)    delete[] mXPos;     mXPos    = NULL;
+ if(mWeights) delete[] mWeights;  mWeights = NULL;
+}
+
+void
+GLInteg::InvalWeights()
+{
+ if(mXPos)    delete[] mXPos;     mXPos    = NULL;
+ if(mWeights) delete[] mWeights;  mWeights = NULL;
+}
+
+
+void
+GLInteg::LimitsChanged()
+{
+ ComputeBounds();
+}
+
+void
+GLInteg::StepsChanged()
+{
+ ComputeBounds();
+}
+
+GLInteg&
+GLInteg::AddBound(double x)
+{
+ if (x<=mXMin || x>=mXMax) throw RangeCheckError("GLInteg::AddBound()") ; 
+ // 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;
+}
+
+
+//! Definit l'ordre de la methode d'integration Gauus-Legendre
+GLInteg&
+GLInteg::SetOrder(int order)
+{
+ mOrder = order;
+ InvalWeights();
+ return *this;
+}
+
+
+//! Retourne la valeur de l'integrale
+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 = 5.0e-12;
+
+   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];
+   }
+
+}
+
+//! Imprime l'ordre et la valeur des poids sur cout
+void
+GLInteg::Print(int lp)
+{
+ Integrator::Print(lp);
+ cout<<"GLInteg order="<<mOrder<<endl;
+ if(lp>0 && mOrder>0) {
+   for(int i=0;i<mOrder;i++)
+     cout<<" ("<<mXPos[i]<<","<<mWeights[i]<<")";
+   cout<<endl;
+ }
+}
Index: /tags/V_Nov2007/SophyaLib/NTools/integ.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/integ.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/integ.h	(revision 3445)
@@ -0,0 +1,115 @@
+// 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);
+
+  Integrator();
+  Integrator(ClassFunc &, double xmin, double xmax);
+  Integrator(ClassFunc &);
+
+  Integrator(FUNC, double xmin, double xmax);
+  Integrator(FUNC);
+
+  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& SetFunc(ClassFunc &);
+  virtual Integrator& SetFunc(FUNC);
+  virtual Integrator& SetFunc(GeneralFunction*, double* par);
+
+  virtual inline  int GetNStep(void) {return mNStep;}
+  virtual void Print(int lp=0);
+
+protected:
+  FUNC             mFunc;
+  ClassFunc *      mClFun;
+  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(ClassFunc  &, double xmin, double xmax);
+  TrpzInteg(ClassFunc  &);
+  TrpzInteg(FUNC, double xmin, double xmax);
+  TrpzInteg(FUNC);
+  TrpzInteg(GeneralFunction*, double* par, double xmin, double xmax);
+  TrpzInteg(GeneralFunction*, double* par);
+
+  ~TrpzInteg();
+
+  virtual double Value();
+};
+
+class GLInteg : public Integrator {
+public:
+  GLInteg();
+  GLInteg(ClassFunc  &, double xmin, double xmax);
+  GLInteg(ClassFunc  &);
+  GLInteg(FUNC, double xmin, double xmax);
+  GLInteg(FUNC);
+  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);
+  virtual inline  int GetOrder(void) {return mOrder;}
+  virtual void Print(int lp=0);
+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_Nov2007/SophyaLib/NTools/linfit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/linfit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/linfit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/matxop.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/matxop.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/matxop.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/matxop.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/matxop.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/matxop.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/median.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/median.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/median.cc	(revision 3445)
@@ -0,0 +1,26 @@
+#if 0
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/NTools/median.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/median.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/median.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/nbconst.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbconst.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbconst.h	(revision 3445)
@@ -0,0 +1,83 @@
+/* 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 S4Pi   (double) (3.5449077018110318)   /*!< sqrt(4*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_Nov2007/SophyaLib/NTools/nbinteg.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbinteg.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbinteg.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/nbmath.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbmath.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbmath.c	(revision 3445)
@@ -0,0 +1,2811 @@
+#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);
+}
+
+/*=========================================== cmv 22/11/04 ===*/
+/*
+++
+double log_factoriel(unsigned int n)
+
+	Compute the neperian log of n!
+--
+*/
+double log_factoriel(unsigned int n)
+{
+  unsigned int i;
+  double sum=0.;
+  if(n<2) return sum;
+  for(i=n;i>1;i--) sum += log((double)i);
+  return sum;
+}
+
+/*
+++
+double log_stirling(unsigned int n)
+
+	Compute the neperian log of the Stirling approx of n!
+--
+*/
+double log_stirling(unsigned int n)
+/*
+Approx: n! ~ sqrt(2Pi n) n^n exp(-n) = sqrt(2Pi) n^(n+1/2) exp(-n)
+        log(n!) ~ (n+1/2) log(n) -n + 1/2 log(2Pi)
+(ordre 0: log(n!) ~ n (log(n)-1)
+*/
+{
+  if(n<1) return 0.;
+  return (n+0.5)*log(n) - n + Hln2pi;
+}
+
+/*
+++
+double log_gosper(unsigned int n);
+
+	Compute the neperian log of the Gosper approx of n!
+--
+*/
+double log_gosper(unsigned int n)
+/*
+Approx: n! ~ sqrt( (2n+1/3) Pi ) n^n exp(-n)
+        log(n!) ~ 1/2 log( (2n+1/3) Pi ) + n log(n) -n
+*/
+{
+  if(n<1) return 0.;
+  return 0.5*log((2.*n+1./3.)*M_PI) + n*log(n) -n;
+}
+
+/*
+++
+double give_log_factoriel(unsigned int n);
+
+	Compute the neperian log of the approx of n!
+--
+*/
+static short give_log_factoriel_OK = 0;
+#define give_log_factoriel_LIM 21
+static double give_log_factoriel_TAB[give_log_factoriel_LIM];
+double give_log_factoriel(unsigned int n)
+{
+  int i;
+  if(give_log_factoriel_OK==0) {
+    give_log_factoriel_OK=1;
+    for(i=0;i<give_log_factoriel_LIM;i++)
+      give_log_factoriel_TAB[i]=log_factoriel(i);
+  }
+
+  if(n<give_log_factoriel_LIM) return give_log_factoriel_TAB[n];
+  return log_gosper(n);
+}
+#undef give_log_factoriel_LIM
Index: /tags/V_Nov2007/SophyaLib/NTools/nbmath.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbmath.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbmath.h	(revision 3445)
@@ -0,0 +1,101 @@
+/* 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);
+
+double log_factoriel(unsigned int n);
+double log_stirling(unsigned int n);
+double log_gosper(unsigned int n);
+double give_log_factoriel(unsigned int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/nbrandom.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbrandom.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbrandom.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/nbtri.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbtri.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbtri.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/nbtri.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/nbtri.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/nbtri.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/ntools.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/ntools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/ntools.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/ntoolsinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/ntoolsinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/ntoolsinit.cc	(revision 3445)
@@ -0,0 +1,86 @@
+// Classe d'initialisation du module NTools
+
+#include "sopnamsp.h"
+#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
+*/
+
+int NToolsInitiator::FgInit = 0;
+
+// Module version number 1.5, Jul 06
+#define MOD_VERS   1.5 
+
+/*!
+  \class SOPHYA::NToolsInitiator
+  \ingroup NTools
+  \brief NTools module initializer.
+
+   This module contains various tools for Sophya, in particular numerical algorithms
+   such as :
+   - Non linear fitting (parameter determination) : GeneralFit , MinZSimplex
+   - FFT (FFTServerInterface, FFTPackServer)
+   - Spline interpolation
+   - Numerical integration and differential equations
+   - Date/time manipulation and some usual astronomical quantities (datime.c .h)
+*/
+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;
+
+  SophyaInitiator::RegisterModule("NTools", MOD_VERS);  // Module name and version number registration
+}
+
+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_Nov2007/SophyaLib/NTools/ntoolsinit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/ntoolsinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/ntoolsinit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/objfitter.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/objfitter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/objfitter.cc	(revision 3445)
@@ -0,0 +1,487 @@
+#include "sopnamsp.h"
+#include "objfitter.h"
+
+//===========================================================================
+//===========================================================================
+//=========================== ObjectFitter ==================================
+//===========================================================================
+//===========================================================================
+
+//============================= Matrix et Vector ============================
+TMatrix<uint_2>
+ObjectFitter::FitResidus(TMatrix<uint_2> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<uint_2>::FitResidus(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<int_2>
+ObjectFitter::FitResidus(TMatrix<int_2> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_2>::FitResidus(mtx,gfit,xorg,yorg,dx,dy) );}
+
+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<int_8>
+ObjectFitter::FitResidus(TMatrix<int_8> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_8>::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<uint_2>
+ObjectFitter::FitFunction(TMatrix<uint_2> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<uint_2>::FitFunction(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<int_2>
+ObjectFitter::FitFunction(TMatrix<int_2> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_2>::FitFunction(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<int_8>
+ObjectFitter::FitFunction(TMatrix<int_8> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_8>::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<uint_2>
+ObjectFitter::FitResidus(TVector<uint_2> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<uint_2>::FitResidus(vec,gfit,xorg,dx) );}
+
+TVector<int_2>
+ObjectFitter::FitResidus(TVector<int_2> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<int_2>::FitResidus(vec,gfit,xorg,dx) );}
+
+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<int_8>
+ObjectFitter::FitResidus(TVector<int_8> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<int_8>::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_2>
+ObjectFitter::FitFunction(TVector<int_2> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<int_2>::FitFunction(vec,gfit,xorg,dx) );}
+
+TVector<uint_2>
+ObjectFitter::FitFunction(TVector<uint_2> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<uint_2>::FitFunction(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<int_8>
+ObjectFitter::FitFunction(TVector<int_8> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<int_8>::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<uint_2>
+#pragma define_template ArrayFitter<int_2>
+#pragma define_template ArrayFitter<int_4>
+#pragma define_template ArrayFitter<int_8>
+#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)
+namespace SOPHYA {
+template class ArrayFitter<uint_2>;
+template class ArrayFitter<int_2>;
+template class ArrayFitter<int_4>;
+template class ArrayFitter<int_8>;
+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_Nov2007/SophyaLib/NTools/objfitter.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/objfitter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/objfitter.h	(revision 3445)
@@ -0,0 +1,166 @@
+// 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<uint_2> FitResidus(TMatrix<uint_2> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<int_2> FitResidus(TMatrix<int_2> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  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<int_8> FitResidus(TMatrix<int_8> 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<uint_2> FitFunction(TMatrix<uint_2> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<int_2> FitFunction(TMatrix<int_2> 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<int_8> FitFunction(TMatrix<int_8> 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<uint_2> FitResidus(TVector<uint_2> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<int_2> FitResidus(TVector<int_2> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<int_4> FitResidus(TVector<int_4> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<int_8> FitResidus(TVector<int_8> 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<uint_2> FitFunction(TVector<uint_2> const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+  static TVector<int_2> FitFunction(TVector<int_2> 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<int_8> FitFunction(TVector<int_8> 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_Nov2007/SophyaLib/NTools/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/objlist.list	(revision 3445)
@@ -0,0 +1,34 @@
+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
+FSAppIrrSmpl.o
+functab.o
+generaldata.o
+generalfit.o
+generalfunc.o
+integ.o
+matxop.o
+median.o
+nbmath.o
+nbtri.o
+ntoolsinit.o
+objfitter.o
+perandom.o
+poly.o
+rk4cdifeq.o
+simplesort.o
+simplex.o
+tabmath.o
+toeplitzMatrix.o
Index: /tags/V_Nov2007/SophyaLib/NTools/pclassids.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/pclassids.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/pclassids.h	(revision 3445)
@@ -0,0 +1,56 @@
+// 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_HistoErr = 0x0204,
+   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_Nov2007/SophyaLib/NTools/peida.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/peida.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/peida.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/pemath.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/pemath.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/pemath.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/perandom.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/perandom.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/perandom.cc	(revision 3445)
@@ -0,0 +1,318 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "perandom.h"
+#include "pemath.h"
+#include <iostream>
+
+
+////////////////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FunRan
+  \ingroup NTools
+  Classe for generating random variables from 1D function
+*/
+
+
+/********* Methode *********/
+/*! Creator from a function.
+\verbatim
+ - if pdf==true: f est une densite de probabilite (PDF)
+                 non necessairement normalisee
+   if pdf==false: f est  une fonction de distribution (DF).
+                  non necessairement normalisee
+ - Le tirage aleatoire est fait sur un histogramme
+   Histo(xMin,xMax,nBin) (voir convention dans Histo).
+ - Chaque bin de l'histogramme contient la valeur de la PDF
+   (ou de la DF) au centre du bin: h(i)=f(BinCenter(i))
+ - Les valeurs retournees sont les valeurs du centre des bins
+   pour le tirage non interpole et toutes les valeurs
+   entre [xmin,xmax] pour le tirage interpole
+ - La pdf doit etre interpretee comme etant nulle
+   pour des x<=xmin et x>=xmax
+ - Dans le bin "i" entre [x1,x2[ et de centre x0, h(i)=pdf(x0).
+   Pour le tirage interpole, la DF est approximee par un segment
+   et pdf(x0) est l'exces de proba entre x1 et x2:
+   bin 0 entre [xmin,BinHighEdge(0)[ :
+               la pdf va de 0 a pdf(BinCenter(0))
+   bin 1 entre [BinLowEdge(1),BinHighEdge(1)[:
+               la pdf va de pdf(BinCenter(0)) a pdf(BinCenter(1))
+   ...
+   bin n-1 entre [BinLowEdge(n-1),xmax[:
+               la pdf va de pdf(BinCenter(n-2)) a pdf(BinCenter(n-1))
+\endverbatim
+*/
+FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin, bool pdf)
+  : Histo(xMin,xMax,nBin)
+{
+ if(nBin<=1)
+   throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
+ for(int_4 i=0;i<nBin;i++) (*this)(i) = f(BinCenter(i));
+ create_DF(pdf);
+}
+
+/********* Methode *********/
+/*! Creator from a ClassFunc
+See FunRan::FunRan(FunRan::Func...) for further comments.
+*/
+FunRan::FunRan(ClassFunc& f, r_8 xMin, r_8 xMax, int_4 nBin, bool pdf)
+  : Histo(xMin,xMax,nBin)
+{
+ if(nBin<=1)
+   throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
+ for(int_4 i=0;i<nBin;i++) (*this)(i) = f(BinCenter(i));
+ create_DF(pdf);
+}
+
+/********* Methode *********/
+/*! Creator from an table.
+If pdf=true, tab is a probability density fonction (not necessary normalised).
+If pdf=false, tab is a distribution function (not necessarly normalized to 1).
+The return random values will be between 0 and nBin-1.
+See FunRan::FunRan(FunRan::Func...) for further comments.
+*/
+FunRan::FunRan(r_8 *tab, int_4 nBin, bool pdf)
+: Histo(-0.5,nBin-0.5,nBin)
+{
+ if(nBin<=1)
+   throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
+ for(int_4 i=0;i<nBin;i++) (*this)(i) = tab[i];
+ create_DF(pdf);
+}
+
+/********* Methode *********/
+/*! Creator from an table.
+If pdf=true, tab is a probability density fonction (not necessary normalised).
+If pdf=false, tab is a distribution function (not necessarly normalized to 1).
+The content of tab is identified has the content of
+an Histogram define by Histo(xMin,xMax,nBin).
+See FunRan::FunRan(FunRan::Func...) for further comments.
+*/
+FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax, bool pdf)
+: Histo(xMin,xMax,nBin)
+{
+ if(nBin<=1)
+   throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
+ for(int_4 i=0;i<nBin;i++) (*this)(i) = tab[i];
+ create_DF(pdf);
+}
+
+/********* Methode *********/
+/*! Creator from an histogram
+If pdf=true, h is a probability density fonction (not necessary normalised).
+If pdf=false, h is a distribution function (not necessarly normalized to 1).
+See FunRan::FunRan(FunRan::Func...) for further comments.
+*/
+FunRan::FunRan(Histo &h, bool pdf)
+  : Histo(h)
+{
+ if(mBins<=1)
+   throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
+ create_DF(pdf);
+}
+
+/********* Methode *********/
+/*! Creator by copy */
+FunRan::FunRan(const FunRan& fh)
+  : Histo(fh)
+{
+}
+
+/********* Methode *********/
+/*! Creator by default */
+FunRan::FunRan(void)
+{
+}
+
+/********* Methode *********/
+void FunRan::create_DF(bool pdf)
+// Creation (si necessaire) et normalisation de la DF
+{
+  // On fabrique la FD si necessaire
+  if(pdf)
+    for(int_4 i=1;i<mBins;i++) (*this)(i) += (*this)(i-1);
+
+  // On normalise la FD
+  if((*this)(mBins-1)<=0.) {
+    cout<<"FunRan::FunRan(Histo) not a distribution function last bin is <=0"<<endl;
+    throw RangeCheckError("FunRan::FunRan(Histo) not a distribution function last bin is <=0");
+  }
+ for(int_4 i=0;i<mBins;i++) (*this)(i) /= (*this)(mBins-1);
+}
+
+/********* Methode *********/
+/*! Tirage avec retour du numero de bin entre 0 et mBins-1.
+It returns the first bin whose content is greater or equal
+to the random uniform number (in [0,1[)
+*/
+int_4 FunRan::BinRandom()
+{
+ // recherche du premier bin plus grand ou egal a z
+ r_8 z=drand01();
+ for(int_4 i=0;i<mBins;i++) if(z<(*this)(i)) return i;
+ return mBins-1;
+}
+
+/********* Methode *********/
+/*! Tirage avec retour abscisse du bin non interpole. */
+r_8 FunRan::Random()
+{
+ r_8 z=drand01();
+ int ibin = mBins-1;
+ for(int_4 i=0;i<mBins;i++) if(z<(*this)(i)) {ibin=i; break;}
+ return BinCenter(ibin);
+}
+
+/********* Methode *********/
+/*! Tirage avec retour abscisse du bin interpole. */
+r_8 FunRan::RandomInterp(void)
+{
+ r_8 z=drand01();
+ int ibin = mBins-1;
+ r_8 z1=0., z2;
+ for(int_4 i=0;i<mBins;i++) {
+   z2 = (*this)(i);
+   if(z<z2) {ibin=i; break;}
+   z1 = z2;
+ }
+
+ // l'algorithme garanti que "z2-z1 != 0" et "z1<z2"
+ return BinLowEdge(ibin) + (z-z1)/(z2-z1)*binWidth;
+ 
+}
+
+////////////////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FunRan2D
+  \ingroup NTools
+  Classe for generating random variables from 2D function
+*/
+
+/********* Methode *********/
+/*! Creator for random from a table */
+FunRan2D::FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY)
+{
+  // 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;
+}
+
+/********* Methode *********/
+/*! Creator for random from a table */
+FunRan2D::FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY)
+{
+  // 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;
+}
+
+/********* Methode *********/
+/*! Destructor */
+FunRan2D::~FunRan2D()
+{
+  for (int_4 i=nx-1; i>=0; i--)
+    delete ranY[i];
+    
+  delete[] ranY;
+  
+  delete ranX;
+}
+
+/********* Methode *********/
+/*! Tirage avec retour du numeros de bin. */
+void FunRan2D::BinRandom(int_4& x, int_4& y)
+{
+  x = ranX->BinRandom();
+  y = ranY[x]->BinRandom();
+}
+
+/********* Methode *********/
+/*! Tirage avec retour abscisse et ordonnee du bin interpole. */
+void FunRan2D::Random(r_8& x, r_8& y)
+{
+  x = ranX->Random();
+  int_4 i = int_4(ceil(x));
+  y = ranY[i]->Random();
+}
+
+
+
+/////////////////////////////////////////////////////////////////
+/*
+**** Remarques sur complex< r_8 > ComplexGaussRan(double sig) ****
+
+--- variables gaussiennes x,y independantes
+x gaussien: pdf f(x) = 1/(sqrt(2Pi) Sx) exp(-(x-Mx)^2/(2 Sx^2))
+y gaussien: pdf f(y) = 1/(sqrt(2Pi) Sy) exp(-(y-My)^2/(2 Sy^2))
+x,y independants --> pdf f(x,y) = f(x) f(y)
+On a:
+  <x>   = Integrate[x*f(x)]   = Mx
+  <x^2> = Integrate[x^2*f(x)] = Mx^2 + Sx^2
+
+--- On cherche la pdf g(r,t) du module et de la phase
+  x = r cos(t) ,  y = r sin(t)
+  r=sqrt(x^2+y^2 , t=atan2(y,x)
+  (r,t) --> (x,y): le Jacobien = r
+
+  g(r,t) = r f(x,y) = r f(x) f(y)
+         = r/(2Pi Sx Sy) exp(-(x-Mx)^2/(2 Sx^2)) exp(-(y-My)^2/(2 Sy^2))
+
+- Le cas general est complique
+  (cf D.Pelat cours DEA "bruits et signaux" section 4.5)
+
+- Cas ou "Mx = My = 0" et "Sx = Sy = S"
+  c'est la pdf du module et de la phase d'un nombre complexe
+     dont les parties reelles et imaginaires sont independantes
+     et sont distribuees selon des gaussiennes de variance S^2
+  g(r,t) = r/(2Pi S^2) exp(-r^2/(2 S^2))
+  La distribution de "r" est donc:
+    g(r) = Integrate[g(r,t),{t,0,2Pi}]
+         = r/S^2 exp(-r^2/(2 S^2))
+  La distribution de "t" est donc:
+    g(t) = Integrate[g(r,t),{r,0,Infinity}]
+         = 1 / 2Pi  (distribution uniforme sur [0,2Pi[)
+  Les variables aleatoires r,t sont independantes:
+    g(r,t) = g(r) g(t)
+On a:
+  <r>   = Integrate[r*g(r)]   = sqrt(PI/2)*S
+  <r^2> = Integrate[r^2*g(r)] = 2*S^2
+  <r^3> = Integrate[r^3*g(r)] = 3*sqrt(PI/2)*S^3
+  <r^4> = Integrate[r^4*g(r)] = 8*S^4
+
+- Attention:
+La variable complexe "c = x+iy = r*exp(i*t)" ainsi definie verifie:
+              <|c|^2> = <c c*> = <x^2+y^2> = <r^2> = 2 S^2
+Si on veut generer une variable complexe gaussienne telle que
+     <c c*> = s^2 alors il faut prendre S = s/sqrt(2) comme argument
+
+*/
Index: /tags/V_Nov2007/SophyaLib/NTools/perandom.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/perandom.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/perandom.h	(revision 3445)
@@ -0,0 +1,70 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Nombres aleatoires pour Peida.
+//   NON CE N'EST PAS MON CODE ... 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 <math.h>
+#include "histos.h"
+#include "srandgen.h"
+#include "classfunc.h"
+#include <complex>
+
+namespace SOPHYA {  
+
+class FunRan : public Histo {
+public:
+  typedef r_8 (*Func)(r_8);
+  FunRan(ClassFunc& f, r_8 xMin=0.0, r_8 xMax=1.0, int_4 nBin=100, bool pdf=true);
+  FunRan(Func f, r_8 xMin=0.0, r_8 xMax=1.0, int_4 nBin=100, bool pdf=true);
+  FunRan(r_8 *tab, int_4 nBin, bool pdf=true);
+  FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax, bool pdf=true);
+  FunRan(Histo &h, bool pdf=true);
+  FunRan(const FunRan& fh);
+  FunRan(void);
+
+  int_4 BinRandom(void);
+  r_8 Random(void);
+  r_8 RandomInterp(void);
+protected:
+  void create_DF(bool pdf);
+};
+
+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;
+};
+
+
+/*!
+  \ingroup NTools
+  \brief Returns a random complex number such that real and imaginary parts are gaussians with variance sig^2
+*/
+inline complex< r_8 > ComplexGaussRan(double sig=1.)
+  {return complex< r_8 >(GauRnd(0.,sig),GauRnd(0.,sig));}
+
+/*!
+  \ingroup NTools
+  \brief Returns the module of a random complex number generated by ComplexGaussRan
+*/
+inline double ModComplexGaussRan(double sig=1.)
+  {double r=-log(1.-drand01()); return sig*sqrt(2.*r);}
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/poly.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/poly.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/poly.cc	(revision 3445)
@@ -0,0 +1,800 @@
+#include "machdefs.h"
+#include "poly.h"
+#include "linfit.h"
+#include "fioarr.h"
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/*!
+  \class Poly
+  \ingroup NTools
+  One dimensional polynomials class.
+  \warning status EXPERIMENTAL - not fully tested.
+*/
+
+//! Constructor
+/*! Create a 1D polynomial of degre \b degre */
+Poly::Poly(int degre)
+: TVector<r_8>(degre+1), dirty(0), deg(0)
+{
+}
+
+//! Constructor by copy
+Poly::Poly(Poly const& a)
+:TVector<r_8>(a), dirty(a.dirty), deg(a.deg)
+{
+}
+
+//! 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 ParmError("Poly::Roots()") ;
+    }
+}
+
+
+//! 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) ParmError("Poly::Root1() deg!= 1") ;
+
+  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 SzMismatchError("Poly::Root2() deg != 2") ;
+
+  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 SzMismatchError("Poly::Fit() ");
+
+  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 SzMismatchError("Poly::Fit() ");
+  if (n != (int)erry2.NElts()) throw SzMismatchError("Poly::Fit() ") ;
+
+  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 RangeCheckError("Poly::power() n<0 ");
+  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
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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 Poly2
+  \ingroup NTools
+  Two dimensional polynomials class.
+  \warning status EXPERIMENTAL - not fully tested.
+*/
+
+//! 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)
+{
+}
+
+//! 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];
+}
+
+//! 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)
+{
+}
+
+//! 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 SzMismatchError("Poly2::Fit() - 1");
+  if (n != (int)z.NElts()) throw SzMismatchError("Poly2::Fit() - 2");
+
+  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 SzMismatchError("Poly2::Fit() - 3");
+  if (n != (int)z.NElts()) throw SzMismatchError("Poly2::Fit() - 4");
+  if (n != (int)errz2.NElts()) throw SzMismatchError("Poly2::Fit() - 5");
+
+  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 SzMismatchError("Poly2::Fit() - 6");
+  if (n != (int)z.NElts()) throw SzMismatchError("Poly2::Fit() - 7");
+
+  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 SzMismatchError("Poly2::Fit() - 8");
+  if (n != (int)z.NElts()) throw SzMismatchError("Poly2::Fit() - 9");
+  if (n != (int)errz2.NElts()) throw SzMismatchError("Poly2::Fit() - 10");
+
+  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 RangeCheckError("Poly2::power(n<0) ");
+  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
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/NTools/poly.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/poly.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/poly.h	(revision 3445)
@@ -0,0 +1,281 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: poly.h,v 1.11 2004-03-15 16:46:56 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 RangeCheckError("Poly2::IndCoef()");
+    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 RangeCheckError("Poly2::Coef() ");
+    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_Nov2007/SophyaLib/NTools/rk4cdifeq.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/rk4cdifeq.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/rk4cdifeq.cc	(revision 3445)
@@ -0,0 +1,194 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "rk4cdifeq.h"
+#include "ctimer.h"
+#include <iostream>
+
+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_Nov2007/SophyaLib/NTools/rk4cdifeq.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/rk4cdifeq.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/rk4cdifeq.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/NTools/simplesort.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/simplesort.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/simplesort.cc	(revision 3445)
@@ -0,0 +1,62 @@
+//
+// $Id: simplesort.cc,v 1.4 2004-09-10 09:53:00 cmv Exp $
+//
+
+#include "sopnamsp.h"
+#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])
+{
+}
+			
+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_Nov2007/SophyaLib/NTools/simplesort.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/simplesort.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/simplesort.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/simplex.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/simplex.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/simplex.cc	(revision 3445)
@@ -0,0 +1,538 @@
+#include "sopnamsp.h"
+#include "simplex.h"
+#include "ntuple.h"
+#include <math.h>
+
+#include "timing.h"
+
+//---------------------------------------------------------------
+//-------------------  Classe   MinZFunction  -------------------
+//---------------------------------------------------------------
+// Interface de classe de function multivariable pour le SimplexMinmizer
+/*!
+  \class SOPHYA::MinZFunction
+  \ingroup NTools
+  Interface definition for a function object f(x[]) for which MinZSimplex can 
+  search the minimum.
+  The pure virtual method Value() should be implemented by the derived classes.
+*/
+
+MinZFunction::MinZFunction(unsigned int nvar)
+  : mNVar(nvar)
+{
+}
+
+MinZFunction::~MinZFunction()
+{
+}
+
+//---------------------------------------------------------------
+//-------------------  Classe   MinZFuncXi2  --------------------
+//---------------------------------------------------------------
+/*!
+  \class SOPHYA::MinZXi2
+  \ingroup NTools
+  Implements the MinZFunction interface using a xi2 calculator 
+  \sa GeneralXi2 GeneralFitData
+*/
+MinZFuncXi2::MinZFuncXi2(GeneralXi2* gxi2, GeneralFitData* gd)
+  : mGXi2(gxi2) , mGData(gd), MinZFunction(gxi2->NPar())
+{
+}
+
+MinZFuncXi2::~MinZFuncXi2()
+{
+}
+
+double MinZFuncXi2::Value(double const xp[])
+{
+  int ndataused;
+  return mGXi2->Value(*mGData, const_cast<double *>(xp), ndataused);
+}
+
+//---------------------------------------------------------------
+//-------------------  Classe  MinZTestFunc   -------------------
+//---------------------------------------------------------------
+class MinZTestFunc : public  MinZFunction {
+public:
+  MinZTestFunc(int sel);
+  virtual double Value(double const xp[]);
+  string  ToString();
+  Vector  OptParms();
+protected:
+  static int ISelToNvar(int isel);
+  int mSel;
+};
+
+int MinZTestFunc::ISelToNvar(int isel)
+{
+  if (isel == 0) return 1;
+  if (isel == 1) return 1;
+  else if (isel == 2) return 1;
+  else if (isel == 3) return 2;
+  else if (isel == 4) return 3;
+  else return 1;
+}
+
+MinZTestFunc::MinZTestFunc(int sel)
+  : MinZFunction(ISelToNvar(sel)) 
+{
+  if ((sel < 0) || (sel > 4)) sel = 0;
+  mSel = sel;
+}
+
+string MinZTestFunc::ToString()
+{
+  string rs;
+  if (mSel == 0) {
+    rs = "-x+(x-2)^2"; 
+  }
+  else if (mSel == 1) {
+    rs = "0.1*x^2-3exp(-(x-2)^2)-5*exp(-0.5*(x+3)^2)";
+  }
+  else if (mSel == 2) {
+    rs = "0.1*x^2-3exp(-(x-2)^2)+5*exp(-0.5*(x+3)^2)";
+  }
+  else if (mSel == 3) {
+    rs = "1.3*(x-50.35)^2+25*(y+3.14)^2";
+  }
+  else if (mSel == 4) {
+    rs = "(x-2.2)^2+2.*(y+3.6)^2+3.*(z-1.1)^2";
+  }
+  else rs = "????";
+  return  rs;
+}
+
+Vector MinZTestFunc::OptParms()
+{
+  Vector xx;
+  if (mSel == 0) {
+    Vector rv(1);
+    rv = 2.5;
+    return rv;
+  }
+  else if (mSel == 1) {
+    Vector rv(1);
+    rv = -2.883;
+    return rv;
+  }
+  else if (mSel == 2) {
+    Vector rv(1);
+    rv = 1.812;
+    return rv;
+  }
+  else if (mSel == 3) {
+    Vector rv(2);
+    rv(0) = 50.35;
+    rv(1) = -3.14;
+    return rv;
+  }
+  else if (mSel == 4) {
+    Vector rv(3);
+    rv(0) = 2.2;
+    rv(1) = -3.6;
+    rv(2) = 1.1;
+    return rv;
+  }
+  else xx = 0.;
+  return xx ;
+}
+
+
+double MinZTestFunc::Value(double const xp[])
+{
+  double retval = 0;
+  if (mSel == 0) {
+    double x = xp[0];
+    retval = -x+(x-2.)*(x-2.);
+  }
+  else if ((mSel == 1) || (mSel == 2)) {
+    double x = xp[0];
+    retval = 0.1*x*x;
+    x = xp[0]-2.;
+    x = x*x;
+    retval -= 3*exp(-x);
+    x = xp[0]+3.;
+    x = 0.5*x*x;
+    if (mSel == 1) retval -= 5*exp(-x);
+    else retval += 5*exp(-x);
+  }
+  else if (mSel == 3) {
+    double x = xp[0]-50.35;
+    double y = xp[1]+3.14;
+    retval = 1.3*x*x+25.*y*y;
+  }
+  else if (mSel == 4) {
+    double x = xp[0]-2.2;
+    double y = xp[1]+3.6;
+    double z = xp[2]-1.1;
+    retval = x*x+2.*y*y+3.*z*z;
+  }
+  else retval = 0.;
+  return retval;
+}
+
+//---------------------------------------------------------------
+//-------------------  Classe   MinZSimplex  --------------------
+//---------------------------------------------------------------
+string __Vec2Str4MinZ_AutoTest(Vector& xx) 
+{
+  string rs;
+  char buff[32];
+  for(int i=0; i<xx.Size(); i++) {
+    sprintf(buff," %g " , xx(i));
+    rs += buff;
+  }
+  return rs;
+}
+
+/*!
+  \class SOPHYA::MinZSimplex
+  \ingroup NTools
+  This class implements non linear minimization (optimization)
+  in a multidimensional space following the \b Simplex method.
+  A \b Simplex is a geometrical figure made of N+1 points in a
+  N-dimensional space. (triangle in a plane, tetrahedron in 3-d space).
+  The minimization method implemented in this class is based on the 
+  algorithm described in "Numerical Recipes, Chapter X". 
+
+  The algorithm has been slightly enhanced :
+  - More complex convergence / stop test 
+  - A new transformation of the simplex has been included (ExpandHigh)
+
+  For each step, on of the following geometrical transform is performed
+  on the Simplex figure:
+  - Reflection : reflection away from the high point (expansion by factor Alpha)
+  - ReflecExpand : reflection way from the high point and expansion by factor Beta2
+  - ContractHigh : Contraction along the high point (factor Beta)
+  - ContractLow : Contraction toward the low point (factor Beta2)
+  - ExpandHigh : Expansion along the high point
+
+  \sa GeneralFit
+
+  The following sample code shows a usage example:
+  \code
+  include "simplex.h"
+  ...
+  // Define our function to be minimized:
+  class MySFunc : public MinZFunction {
+  public:
+    MySFunc() : MinZFunction(2) {}
+    virtual double Value(double const xp[]) 
+    { return (xp[0]*xp[0]+2*xp[1]*xp[1]); }
+  };
+
+  ... 
+
+  MySFunc mysf;
+  MinZSimplex simplex(&mysf);
+  // Guess the center and step for constructing the initial simplex
+  Vector x0(2); x0 = 1.;
+  Vector step(2); step = 2.;
+  simplex.SetInitialPoint(x0);
+  simplex.SetInitialStep(step);
+  Vector oparm(2);
+  int rc = simplex.Minimize(oparm);
+  if (rc != 0) {
+    string srt; 
+    int sr = simplex.StopReason(srt);
+    cout << " Convergence Pb, StopReason= " << sr << " : " << srt << endl;
+    }
+  else {
+    cout << " Converged: NStep= " << simplex.NbIter() 
+         << " OParm= " << oparm << endl;
+    }
+  \endcode
+*/
+
+/*!
+  \brief Auto test function
+  \param tsel : select autotest (0,1,2,3,4)  , tsel<0 -> all
+  \param prtlev : printlevel 
+*/
+int MinZSimplex::AutoTest(int tsel, int prtlev)
+{
+  int rc = 0;
+  cout << " --- MinZSimplex::AutoTest() --- TSel= " << tsel << " PrtLev=" << prtlev << endl;
+  for(int i=0; i<5; i++) {
+    if ((tsel >= 0) && (tsel != i))  continue; 
+    cout << " ======= Test avec ISel= " << i;
+    Vector xx;
+    MinZTestFunc mzf(i);
+    cout << " - Func= " << mzf.ToString() << endl;
+    Vector rv = mzf.OptParms();
+    xx = rv;
+    for(int j=0; j<2; j++) {
+      double vi = 50.*(j-0.5);
+      for(int k=0; k<2; k++) {
+	double vs = (k == 0) ? 1. : 10. ;
+	cout << "--[" << j << "," << k 
+	     << "] Initialisation avec IniPoint= " << vi << " IniStep= " << vs << endl;
+	MinZSimplex simplex(&mzf);
+	xx = vi;
+	simplex.SetInitialPoint(xx);
+	xx = vs;
+	simplex.SetInitialStep(xx);
+	simplex.SetPrtLevel(prtlev);
+	int rcs = simplex.Minimize(xx);
+	Vector diff = rv-xx;
+	double d2 = diff.Norm2();
+	cout << " Rc(simplex.Minimize() = " << rc << " NIter= " 
+	     << simplex.NbIter() << " ===> Distance^2= " << d2
+	     << "\nConverged to " <<  __Vec2Str4MinZ_AutoTest(xx) 
+	     << "  Best Value= " << __Vec2Str4MinZ_AutoTest(rv) 
+	     << "  Diff = " << __Vec2Str4MinZ_AutoTest(diff) << endl;
+	if ((rcs > 5) || (d2 > 0.5))  rc ++;
+      }
+    }
+  }
+  cout << " --- MinZSimplex::AutoTest() --- Rc=" << rc << " -- END ----- " << endl;
+  return rc;
+}
+
+//! Constructor from pointer to MinZFunction object 
+MinZSimplex::MinZSimplex(MinZFunction *mzf)
+  : mZF(mzf) , mPoint0(mZF->NVar()) , mStep0(mZF->NVar())
+{
+  SetMaxIter();
+  SetControls();
+  Vector xx(NDim());
+  xx = 0.;
+  SetInitialPoint(xx);
+  xx = 1.0;
+  SetInitialStep(xx);
+  SetStopTolerance();
+  mIter = -1;
+  mStop = -1;
+  SetPrtLevel();
+}
+
+MinZSimplex::~MinZSimplex()
+{
+}
+
+//! Perform the minimization 
+/*!
+  Return 0 if success
+  \param fpoint : vector containing the optimal point 
+  
+  Convergence test :
+  \verbatim
+  On minimise f(x) f=mZF->Value() , 
+              f_max = max(f) sur simplex , f_min = min(f) sur simplex 
+              fm = (abs(f_max)+abs(f_min))
+              [Delta f] = abs(f_max-f_min)
+              [Delta f/f]simplex = 2.*Delta f / fm
+              fm2 = (abs(f_max)+abs(f_max(iter-1)))
+              [Delta f_max/f_max]iter = [f_max(iter-1)-f_max]/fm2 
+  Test d'arret :  
+   fm < mTol0                                                       OU 
+   [Delta f/f]simplex              < mTol1   mRep1 fois de suite    OU 
+   [Delta f_max/f_max]iter         < mTol2   mRep2 fois de suite  
+*/
+int MinZSimplex::Minimize(Vector& fpoint)
+{
+  // vector< TVector<r_8> > splx;
+  Vector splx[100];
+  Vector Y(NDim()+1);
+  // On calcule le simplex initial
+  // N = NDim, N+1 points (pp) ds l'espace a N dimensions
+  // Point0, Point0 + Step0(i) e_i  
+  Vector pp,ppc;
+  pp = mPoint0;
+  //ppc = pp;
+  //splx.push_back(ppc);
+  splx[0] = pp;
+  int i,j,k;
+  for(i=0; i<NDim(); i++) {
+    Vector pps;
+    pps = mPoint0;
+    pps(i) += mStep0(i);
+    //splx.push_back(pps);    
+    splx[i+1] = pps;
+  }
+  int mpts = NDim()+1;
+  // calcul des valeurs de la fonction sur les sommets
+  for(i=0; i<mpts; i++) 
+    Y(i) = Value(splx[i]); 
+
+  int iter = 0;
+  mIter = iter;
+  mStop = 0;
+
+  int nbugrtol2 = 0;
+  bool stop = false, stop0=false;      
+  int rc = 0;
+  int ilo, ihi, inhi;
+  int move = 0;
+  char* smov[6] = { "None", "Reflection", "ReflecExpand", "ContractHigh", "ContractLow", "ExpandHigh" };
+  int movcnt[6] = {0,0,0,0,0,0};
+
+  int nrep1=0, nrep2=0;
+  FindMinMax12(Y, ilo, ihi, inhi);
+  double yhilast = Y(ihi);
+  yhilast += fabs(yhilast); 
+
+  while (!stop) {  // 
+    FindMinMax12(Y, ilo, ihi, inhi);
+    double ymean = (fabs(Y(ihi))+fabs(Y(ilo)));
+    if (ymean < mTol0) { stop0 = true; ymean = mTol0; }
+    double rtol1 = 2.*fabs(Y(ihi)-Y(ilo))/ymean;
+    double ym2 = (fabs(yhilast)+fabs(Y(ihi)));
+    if (ym2 < mTol0) ym2 = mTol0; 
+    double rtol2 = 2.*(yhilast-Y(ihi))/ym2;
+    yhilast = Y(ihi);
+    if (rtol2 < 0.) {
+      if (move != 40) { 
+	cout << " !!!! MinZSimplex::Minimize() BUG RTol2< 0. --> Chs " << endl;
+	nbugrtol2++;
+      }
+      else nrep2 = 0;
+      rtol2 = -rtol2;
+    }
+    if (PrtLevel() > 1)  
+      cout << "--MinZSimplex::Minimize() - Iter=" << iter
+	   << " Move= " << move << " (" <<  smov[move/10] << ")" << endl;
+    if (PrtLevel() > 2)  
+      cout << "..ILO=" << ilo << " IHI=" << ihi << " INHI=" << inhi
+	   << " Y(ILO)=" << Y(ilo) << " Y(IHI)=" << Y(ihi) << "\n"
+	   << "...YMean_Abs=" << ymean <<  " RTOL1=" << rtol1 << " RTOL2=" << rtol2 <<  endl;
+    if (PrtLevel() > 3) {
+      for(i=0; i<mpts; i++) {
+	cout << "....Simplex[" << i << "]= "; 
+	for(j=0; j<NDim(); j++) cout << splx[i](j) << " , ";
+	cout << " Y=Value= " << Y(i) << endl;
+      }
+    }
+    if (rtol1 < mTol1) nrep1++;
+    else nrep1 = 0;
+    if (rtol2 < mTol2) nrep2++;
+    else nrep2 = 0;
+    
+    if (stop0) { mStop = 1; rc = 0; stop = true; break; }
+    if (nrep1 > mRep1) { mStop = 2; rc = 0; stop = true; break; }
+    if (nrep2 > mRep2) { mStop = 3; rc = 0; stop = true; break; }
+    if (iter > MaxIter() ) { mStop = 0, rc = iter;  break; }
+    iter++;
+    if (iter > 0)  movcnt[move/10]++;  
+
+    // Next iteration, on modifie le simplex
+    // Calcul du centre de gravite su simplex, hors le point le + haut
+    Vector pbar(NDim());
+    pbar = 0.;
+    for(i=0; i<mpts; i++) {
+      if (i == ihi)  continue;
+      pbar += splx[i];
+    }
+    pbar /= (double)NDim();
+    // On calcule le sommet oppose a point IHI (le + haut)
+    Vector pr, prr;
+    double YPR, YPRR;
+    pr = (1.+Alpha())*pbar-Alpha()*splx[ihi];
+    YPR = Value(pr);
+    if (YPR < Y(ilo)) {   // Amelioaration par rapport au meilleur point,
+      // on va plus loin d'un facteur gamma
+      prr = Gamma()*pr+(1.-Gamma())*pbar;
+      YPRR = Value(prr);
+      if (YPRR < Y(ilo)) {  // On remplace le IHI par YPRR 
+	splx[ihi] = prr;
+	Y(ihi) = YPRR;
+	move = 20;
+      }
+      else {  // sinon, on remplace par YPR
+	splx[ihi] = pr;
+	Y(ihi) = YPR;
+	move = 10;
+      }
+    }
+    else {  // Moins bon que le meilleur point .. 
+      if (YPR > Y(inhi)) {  // Plus mauvais que le second plus haut (INHI)
+	if (YPR < Y(ihi)) {   // Mais meilleur que le plus haut (IHI)
+	  splx[ihi] = pr;     // On remplace donc le plus haut
+	  Y(ihi) = YPR;		
+	  move = 11;
+	}
+	else { // Plus mauvais que le plus mauvais IHI 
+	  // on tente avec un point intermediaire 
+	  prr = Beta()*splx[ihi]+(1.-Beta())*pbar;
+	  YPRR = Value(prr);
+	  if (YPRR < Y(ihi)) {   // Le point intermediaire ameliore les choses
+	    splx[ihi] = prr;     // On remplace donc le point le + haut
+	    Y(ihi) = YPRR;
+	    move = 30;
+	  }
+	  else {  
+	    // On tente aussi de rester du meme cote, mais aller plus loin 
+	    prr = Gamma2()*splx[ihi]+(1.-Gamma2())*pbar;
+	    YPRR = Value(prr);
+	    if (YPRR < Y(ihi)) {   // Le point intermediaire ameliore les choses
+	      splx[ihi] = prr;     // On remplace donc le point le + haut
+	      Y(ihi) = YPRR;
+	      move = 50;
+	    }
+	    else { 
+	    // Rien n'y fait, on contracte autour du meilleur point 
+	      for(i=0; i<mpts; i++) {
+		if (i == ilo)  continue;
+		splx[i] = Beta2()*splx[i]+(1.-Beta())*splx[ilo];
+		Y(i) = Value(splx[i]);
+		move = 40;
+	      } 
+	    }
+	  }
+	}
+      }
+      else {  // Meilleur que le IHI et le INHI
+	splx[ihi] = pr;     // On remplace le plus haut
+	Y(ihi) = YPR;	
+	move = 12;
+      }
+    }			 
+  }   // Fin de la boucle while principale
+
+  fpoint = splx[ilo];
+  mIter = iter;
+
+  if (PrtLevel() > 0) {
+    string sr;
+    StopReason(sr);
+    cout << "-----MinZSimplex::Minimize()/Ended - NIter=" << iter 
+	 << " Moves[0..5]= " << movcnt[0] << "," << movcnt[1] << "," 
+	 << movcnt[2] << "," << movcnt[3] << "," 
+	 << movcnt[4] << "," << movcnt[5] 
+	 << "\n..MinZSimplex Stop=" << StopReason() << " -> " << sr << endl;
+    
+    if (nbugrtol2 > 0)  cout << "MinZSimplex::Minimize()/Warning - nbugrtol2= " << nbugrtol2 << endl;
+  }
+  return rc;
+}
+
+//! Return the stop reason and fills the corresponding string description
+int MinZSimplex::StopReason(string& s)
+{
+  char* sr[5] = { "NoConverg, MaxIterReached", "OK, fm<Tol0", "OK, Df/f<Tol1", 
+		  "OK, [Df/f max]Iter<Tol2" "Error - Wrong StopReason" };
+  int stop = mStop;
+  if ((stop < 0) || (stop > 3)) stop = 4;
+  s = sr[stop];
+  return mStop;
+}
+
+int MinZSimplex::FindMinMax12(Vector& fval, int& ilo, int& ihi, int& inhi)
+{
+  ilo = 0;
+  if (fval(0) > fval(1)) { ihi = 0;  inhi = 1; }
+  else { ihi = 1;  inhi = 0; }
+  
+  for(int k=0; k<fval.Size(); k++) {
+    if (fval(k) < fval(ilo))  ilo = k;
+    if (fval(k) > fval(ihi)) {
+      inhi = ihi;
+      ihi = k;
+    }
+    else if (fval(k) > fval(inhi)) {
+      if (k != ihi)  inhi = k;  // ce test n'est peut-etre pas necessaire ???
+    }
+  }
+  return ilo;
+}
Index: /tags/V_Nov2007/SophyaLib/NTools/simplex.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/simplex.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/simplex.h	(revision 3445)
@@ -0,0 +1,151 @@
+#ifndef SIMPLEX_SEEN
+#define SIMPLEX_SEEN
+
+#include "machdefs.h"
+#include "tvector.h"
+#include "generalfit.h"
+#include <string>
+#include <vector>
+
+// ---------------------------------------------------------------
+//             (C) UPS-LAL  R. Ansari , Aout 2004 
+// ---------------------------------------------------------------
+// Classe de minimisation (optimisation) non lineaire dans
+// un espace multidimensionnel suivant la methode des simplex.
+// Simplex : Figure geometrique formee de N+1 sommets (points) 
+//  (points) dans un espace a N dimension 
+// La methode d'optimisation codee ici dans la classe MinZSimplex 
+// est basee sur celle decrite dans Numerical Recipes ,
+// Chapitre X, Minimization or Maximization of Functions 
+// L'algorithme est ameliore sur deux aspects :
+//  - Test d'arret plus complexe 
+//  - Ajout d'une transformation du simplex  (ExpandHigh)
+//    Reflection,ReflecExpand,ContractHigh,ContractLow+ExpandHigh 
+// ----------------------------------------------------------------
+
+using namespace std;
+
+namespace SOPHYA {
+
+//! Interface definition for multivariable function (used by SimplexMinmizer)
+class MinZFunction {
+public:
+  //! Constructor with nVar defining the number of variables
+  MinZFunction(unsigned int nVar); 
+  virtual ~MinZFunction();
+  //! Returns the value of the function for the point defined by xp[]
+  virtual double Value(double const xp[])=0;
+  //! Returns the number of variables (dimension of xp[]) in method Value()
+  inline int     NVar() const {return mNVar;}  
+protected:
+  const int mNVar;  //!< nombre de variables f(x,y,z,...)  
+};
+
+//!  Wrapper class implementing MinZFunction for a GeneralXi2 associated with a GeneralFitData
+class MinZFuncXi2 : public MinZFunction {
+public: 
+  MinZFuncXi2(GeneralXi2* gxi2, GeneralFitData* gd);
+  virtual ~MinZFuncXi2(); 
+  virtual double Value(double const xp[]);
+protected:
+  GeneralXi2 *mGXi2;
+  GeneralFitData *mGData;
+};
+
+//! Class implementing the Simplex minimisation method 
+class MinZSimplex {
+public:
+  static int     AutoTest(int tsel=-1, int prtlev=0);
+
+                 MinZSimplex(MinZFunction *mzf);
+  virtual        ~MinZSimplex();
+
+  //! Return the parameter space dimension 
+  inline int     NDim() { return mZF->NVar(); }
+  // Simplex initial 
+  //! Defines the initial point (center of simplex figure)
+  inline void    SetInitialPoint(Vector& point) { mPoint0 = point; }
+  //! Defines the step along each dimension to construct the simplex from initial point
+  inline void    SetInitialStep(Vector& step) { mStep0 = step; }
+
+  //! Set the info/debug print level  
+  inline void    SetPrtLevel(int lev=0) { mPrt = lev; }
+  //! Return the current print level
+  inline int     PrtLevel() { return mPrt; }
+
+  //! Set the maximum number of iteration
+  inline void    SetMaxIter(int max = 100000) { mMaxIter = max; }
+  //! Return the current  max iter 
+  inline int     MaxIter() { return mMaxIter; }
+  //! Return the number of iterations performed
+  inline int     NbIter() { return mIter; }
+  //! Return the stop reason
+  inline int     StopReason() { return mStop; }
+  //! Return the stop reason and a description string (\b s)
+         int     StopReason(string& s);
+
+  // On minimise f(x) f=mZF->Value() , 
+  //             f_max = max(f) sur simplex , f_min = min(f) sur simplex 
+  //             fm = (abs(f_max)+abs(f_min))
+  //             [Delta f] = abs(f_max-f_min)
+  //             [Delta f/f]simplex = 2.*Delta f / fm
+  //             fm2 = (abs(f_max)+abs(f_max(iter-1)))
+  //             [Delta f_max/f_max]iter = [f_max(iter-1)-f_max]/fm2 
+  // Test d'arret :  
+  //  fm < mTol0                                                       OU 
+  //  [Delta f/f]simplex              < mTol1   mRep1 fois de suite    OU 
+  //  [Delta f_max/f_max]iter         < mTol2   mRep2 fois de suite 
+
+  //! Define the tolerances for the various convergence tests
+  inline void    SetStopTolerance(double tol0=1.e-39, double tol1 = 1.e-3, int rep1=5, 
+				  double tol2=1.e-4, int rep2=5)   
+                 { mTol0 = tol0; mTol1 = tol1; mRep1 = rep1; mTol2 = tol2, mRep2 = rep2; }
+
+  // Controle des facteurs de deformation du simplex:
+  // Alpha  = Facteur d'homothetie pour la reflexion simple (Reflection)
+  // Gamma  = Facteur d'homothetie pour la reflexion+expansion (ReflecExpand)
+  // Beta   = Facteur d'homothetie pour la contraction pour le sommet haut f_max (ContractHigh)
+  // Beta2  = Facteur d'homothetie pour la contraction vers le sommet bas f_min (ContractLow)
+  // Gamma2 = Facteur d'homothetie pour la l'extension pour le sommet haut ExpandHigh
+
+  //! Define the similarity (homothetic) factors for the different simplex transformations
+  inline void    SetControls(double alpha=1., double beta=0.5, double beta2=0.5, 
+			     double gamma=2.0, double gamma2=2.0)
+                 { mAlpha = alpha; mBeta = beta; mBeta2 = beta2;  mGamma = gamma; mGamma2 = gamma2;}  
+
+  //! Return the the homothetic factor for Reflection
+  inline double  Alpha() { return mAlpha; }
+  //! Return the the homothetic factor for ContractHigh (contraction away from high point)
+  inline double  Beta() { return mBeta; }
+  //! Return the the homothetic factor for ContractLow (contraction toward the low point)
+  inline double  Beta2() { return mBeta2; }
+  //! Return the the homothetic factor for ReflecExpand (reflection+expansion)
+  inline double  Gamma() { return mGamma; }
+  //! Return the the homothetic factor for ExpandHigh (expansion along high point)
+  inline double  Gamma2() { return mGamma2; }
+
+  // Fonction de minimisation - Rc=0, OK, convergence , Rc>0, Non convergence 
+  // Voir StopReason(string& s)
+  virtual int    Minimize(Vector& fpoint);
+  
+protected:
+  int            FindMinMax12(Vector& fval, int& ilo, int& ihi, int& inhi);
+  inline double  Value(Vector& point) { return mZF->Value(point.Data()); }
+  
+  MinZFunction* mZF;
+  int mMaxIter, mIter;
+  int mStop;
+  int mPrt;
+
+  Vector mPoint0;
+  Vector mStep0;
+  //  vector< Vector > simplex0;
+  //  vector< Vector > simplex_cur;
+  double mAlpha, mBeta, mBeta2, mGamma, mGamma2;
+  double mTol0, mTol1, mTol2;
+  int mRep1,mRep2;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/simps2d.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/simps2d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/simps2d.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/slinparbuff.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/slinparbuff.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/slinparbuff.h	(revision 3445)
@@ -0,0 +1,397 @@
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/NTools/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/smakefile	(revision 3445)
@@ -0,0 +1,716 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libNTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)FSAppIrrSmpl.o $(SOPHYAOBJP)cimage.o $(SOPHYAOBJP)cspline.o $(SOPHYAOBJP)datatypes.o $(SOPHYAOBJP)dates.o $(SOPHYAOBJP)difeq.o $(SOPHYAOBJP)dynccd.o $(SOPHYAOBJP)fct1dfit.o $(SOPHYAOBJP)fct2dfit.o $(SOPHYAOBJP)fftmserver.o $(SOPHYAOBJP)fftpserver.o $(SOPHYAOBJP)fftservintf.o $(SOPHYAOBJP)functab.o $(SOPHYAOBJP)generaldata.o $(SOPHYAOBJP)generalfit.o $(SOPHYAOBJP)generalfunc.o $(SOPHYAOBJP)imageop.o $(SOPHYAOBJP)integ.o $(SOPHYAOBJP)median.o $(SOPHYAOBJP)ntoolsinit.o $(SOPHYAOBJP)objfitter.o $(SOPHYAOBJP)perandom.o $(SOPHYAOBJP)poly.o $(SOPHYAOBJP)rk4cdifeq.o $(SOPHYAOBJP)simplesort.o $(SOPHYAOBJP)simplex.o $(SOPHYAOBJP)tabmath.o $(SOPHYAOBJP)toeplitzMatrix.o $(SOPHYAOBJP)datime.o $(SOPHYAOBJP)fftmayer_r4.o $(SOPHYAOBJP)fftmayer_r8.o $(SOPHYAOBJP)fftpackc.o $(SOPHYAOBJP)matxop.o $(SOPHYAOBJP)nbmath.o $(SOPHYAOBJP)nbtri.o
+	rm -f $(SOPHYALIBP)libNTools.a
+ 
+$(SOPHYALIBP)libNTools.a : $(SOPHYAOBJP)cimage.o $(SOPHYAOBJP)cspline.o $(SOPHYAOBJP)datatypes.o $(SOPHYAOBJP)dates.o $(SOPHYAOBJP)datime.o $(SOPHYAOBJP)difeq.o $(SOPHYAOBJP)dynccd.o $(SOPHYAOBJP)fct1dfit.o $(SOPHYAOBJP)fct2dfit.o $(SOPHYAOBJP)fftmayer_r4.o $(SOPHYAOBJP)fftmayer_r8.o $(SOPHYAOBJP)fftmserver.o $(SOPHYAOBJP)fftpackc.o $(SOPHYAOBJP)fftpserver.o $(SOPHYAOBJP)fftservintf.o $(SOPHYAOBJP)FSAppIrrSmpl.o $(SOPHYAOBJP)functab.o $(SOPHYAOBJP)generaldata.o $(SOPHYAOBJP)generalfit.o $(SOPHYAOBJP)generalfunc.o $(SOPHYAOBJP)integ.o $(SOPHYAOBJP)matxop.o $(SOPHYAOBJP)median.o $(SOPHYAOBJP)nbmath.o $(SOPHYAOBJP)nbtri.o $(SOPHYAOBJP)ntoolsinit.o $(SOPHYAOBJP)objfitter.o $(SOPHYAOBJP)perandom.o $(SOPHYAOBJP)poly.o $(SOPHYAOBJP)rk4cdifeq.o $(SOPHYAOBJP)simplesort.o $(SOPHYAOBJP)simplex.o $(SOPHYAOBJP)tabmath.o $(SOPHYAOBJP)toeplitzMatrix.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)FSAppIrrSmpl.o: FSAppIrrSmpl.cc \
+  $(SOPHYAINCP)sopnamsp.h FSAppIrrSmpl.h \
+  $(SOPHYAINCP)machdefs.h nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h fftservintf.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h fftpserver.h \
+  toeplitzMatrix.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  FSAppIrrSmpl.cc
+ 
+$(SOPHYAOBJP)cimage.o: cimage.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cimage.cc
+ 
+$(SOPHYAOBJP)cspline.o: cspline.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nbtri.h cspline.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cspline.cc
+ 
+$(SOPHYAOBJP)datatypes.o: datatypes.cc $(SOPHYAINCP)sopnamsp.h \
+  datatypes.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datatypes.cc
+ 
+$(SOPHYAOBJP)dates.o: dates.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h dates.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dates.cc
+ 
+$(SOPHYAOBJP)difeq.o: difeq.cc $(SOPHYAINCP)sopnamsp.h difeq.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  difeq.cc
+ 
+$(SOPHYAOBJP)dynccd.o: dynccd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fmath.h perandom.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)srandgen.h classfunc.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)fioarr.h dynccd.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ppersist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  dynccd.cc
+ 
+$(SOPHYAOBJP)fct1dfit.o: fct1dfit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fct1dfit.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  nbconst.h tabmath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fct1dfit.cc
+ 
+$(SOPHYAOBJP)fct2dfit.o: fct2dfit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h fct2dfit.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  nbconst.h tabmath.h simps2d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fct2dfit.cc
+ 
+$(SOPHYAOBJP)fftmserver.o: fftmserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftmserver.h \
+  fftservintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftmayer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftmserver.cc
+ 
+$(SOPHYAOBJP)fftpserver.o: fftpserver.cc \
+  $(SOPHYAINCP)sopnamsp.h fftpserver.h \
+  fftservintf.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h fftpackc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftpserver.cc
+ 
+$(SOPHYAOBJP)fftservintf.o: fftservintf.cc fftservintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fftservintf.cc
+ 
+$(SOPHYAOBJP)functab.o: functab.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h functab.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)tarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  functab.cc
+ 
+$(SOPHYAOBJP)generaldata.o: generaldata.cc \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h nbtri.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generaldata.cc
+ 
+$(SOPHYAOBJP)generalfit.o: generalfit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generalfit.cc
+ 
+$(SOPHYAOBJP)generalfunc.o: generalfunc.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  generalfunc.cc
+ 
+$(SOPHYAOBJP)integ.o: integ.cc $(SOPHYAINCP)sopnamsp.h integ.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h classfunc.h \
+  generalfit.h $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  integ.cc
+ 
+$(SOPHYAOBJP)median.o: median.cc
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  median.cc
+ 
+$(SOPHYAOBJP)ntoolsinit.o: ntoolsinit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h poly.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h generaldata.h \
+  $(SOPHYAINCP)ntupintf.h cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h tabmath.h nbconst.h \
+  dates.h datime.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ntoolsinit.cc
+ 
+$(SOPHYAOBJP)objfitter.o: objfitter.cc $(SOPHYAINCP)sopnamsp.h \
+  objfitter.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  objfitter.cc
+ 
+$(SOPHYAOBJP)perandom.o: perandom.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h perandom.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)srandgen.h classfunc.h pemath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  perandom.cc
+ 
+$(SOPHYAOBJP)poly.o: poly.cc $(SOPHYAINCP)machdefs.h poly.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h linfit.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)fioarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  poly.cc
+ 
+$(SOPHYAOBJP)rk4cdifeq.o: rk4cdifeq.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h rk4cdifeq.h difeq.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rk4cdifeq.cc
+ 
+$(SOPHYAOBJP)simplesort.o: simplesort.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h simplesort.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  simplesort.cc
+ 
+$(SOPHYAOBJP)simplex.o: simplex.cc $(SOPHYAINCP)sopnamsp.h \
+  simplex.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h generalfit.h \
+  $(SOPHYAINCP)pexceptions.h generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)ntupintf.h poly.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h fmath.h \
+  $(SOPHYAINCP)anydataobj.h generalfunc.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  simplex.cc
+ 
+$(SOPHYAOBJP)tabmath.o: tabmath.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h tabmath.h peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pexceptions.h fmath.h nbconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tabmath.cc
+ 
+$(SOPHYAOBJP)toeplitzMatrix.o: toeplitzMatrix.cc \
+  $(SOPHYAINCP)sopnamsp.h toeplitzMatrix.h \
+  $(SOPHYAINCP)machdefs.h nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h fftservintf.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h fftpserver.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  toeplitzMatrix.cc
+ 
+$(SOPHYAOBJP)datime.o: datime.c $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h nbconst.h datime.h
+	$(CCOMPILE) -o $@  datime.c
+ 
+$(SOPHYAOBJP)fftmayer_r4.o: fftmayer_r4.c fftmayer.h \
+  $(SOPHYAINCP)machdefs.h trigtbl.h
+	$(CCOMPILE) -o $@  fftmayer_r4.c
+ 
+$(SOPHYAOBJP)fftmayer_r8.o: fftmayer_r8.c fftmayer.h \
+  $(SOPHYAINCP)machdefs.h trigtbl.h
+	$(CCOMPILE) -o $@  fftmayer_r8.c
+ 
+$(SOPHYAOBJP)fftpackc.o: fftpackc.c fftpackc.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  fftpackc.c
+ 
+$(SOPHYAOBJP)matxop.o: matxop.c matxop.h nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  matxop.c
+ 
+$(SOPHYAOBJP)nbmath.o: nbmath.c nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h matxop.h nbinteg.h \
+  nbtri.h
+	$(CCOMPILE) -o $@  nbmath.c
+ 
+$(SOPHYAOBJP)nbtri.o: nbtri.c nbtri.h $(SOPHYAINCP)machdefs.h
+	$(CCOMPILE) -o $@  nbtri.c
+ 
Index: /tags/V_Nov2007/SophyaLib/NTools/swapbytes.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/swapbytes.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/swapbytes.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/tabmath.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/tabmath.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/tabmath.cc	(revision 3445)
@@ -0,0 +1,42 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/NTools/tabmath.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/tabmath.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/tabmath.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/NTools/toeplitzMatrix.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/toeplitzMatrix.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/toeplitzMatrix.cc	(revision 3445)
@@ -0,0 +1,811 @@
+
+#include "sopnamsp.h"
+#include "toeplitzMatrix.h"
+#include "timing.h"   
+
+/*!
+  \class SOPHYA::Toeplitz
+  \ingroup NTools
+  Class for describing a real Toeplitz or complex matrix.
+  Symmetic (/hermitian) or not.
+  Conjugate gradient system solver (for symmetric or hermitian matrices
+  only)
+  Toeplitz matrices have  constant values along negative slope diagonals.
+  A general toeplitz nxn matrix is defined by 2n-1 values and a symmetric
+  (/hermitian) by n values. 
+  General toeplitz matrix form :     
+\verbatim
+  a_0   b_1   b_2   ...     b_n-1
+  a1   a0   b1   b2  ... 
+  a2   a1   a0   b1   ...
+   .....
+   .....
+  a_n-1  ....                a0
+\endverbatim
+*/
+
+
+Toeplitz::Toeplitz() : hermitian_(false)
+  {
+    fftIntfPtr_=new FFTPackServer(true);  // true -> on ne surecrit pas les input
+    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(true); // true -> on ne surecrit pas les input
+    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_Nov2007/SophyaLib/NTools/toeplitzMatrix.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/toeplitzMatrix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/toeplitzMatrix.h	(revision 3445)
@@ -0,0 +1,181 @@
+#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>
+
+#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)
+
+namespace SOPHYA {
+
+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;
+}
+
+
+// Reza+CMV du 3/7/2006 : on a instancie le FFTPackServer avec le flag preserveinput=true
+// On peut donc faire en principe les const_cast sans danger 
+inline void transformeeFourier(const TVector<complex<double> >& v, TVector< complex<double> >& tv) const
+{
+  fftIntfPtr_-> FFTForward(const_cast<TVector<complex<double> > & >(v), tv);
+} 
+inline void transformeeFourier(const TVector<double>& v, TVector< complex<double> >& tv) const
+{
+  fftIntfPtr_-> FFTForward(const_cast<TVector<double> & >(v), tv);
+} 
+
+
+inline void transformeeInverseFourier(const TVector<complex<double> >& tv, TVector<complex<double> >& v) const
+{
+  int n= tv.Size();
+  fftIntfPtr_-> FFTBackward(const_cast<TVector<complex<double> > & >(tv), v);
+  v/=n;
+} 
+inline void transformeeInverseFourier(const TVector<complex<double> >& tv, TVector<double>& v) const
+{
+  int n= tv.Size();
+  fftIntfPtr_-> FFTBackward(const_cast< TVector<complex<double> > & >(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
+
+
+}  // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/NTools/trigtbl.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/NTools/trigtbl.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/NTools/trigtbl.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SUtils/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/Makefile	(revision 3445)
@@ -0,0 +1,31 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSUtils.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datacards.o $(SOPHYAOBJP)strutilxx.o $(SOPHYAOBJP)utils.o $(SOPHYAOBJP)strutil.o
+	rm -f $(SOPHYALIBP)libSUtils.a
+ 
+$(SOPHYALIBP)libSUtils.a : $(SOPHYAOBJP)datacards.o $(SOPHYAOBJP)strutil.o $(SOPHYAOBJP)strutilxx.o $(SOPHYAOBJP)utils.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)datacards.o: datacards.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h datacards.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacards.cc
+ 
+$(SOPHYAOBJP)strutilxx.o: strutilxx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h strutilxx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  strutilxx.cc
+ 
+$(SOPHYAOBJP)utils.o: utils.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utils.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utils.cc
+ 
+$(SOPHYAOBJP)strutil.o: strutil.c strutil.h
+	$(CCOMPILE) -o $@  strutil.c
+ 
Index: /tags/V_Nov2007/SophyaLib/SUtils/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaLib/SUtils/datacards.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/datacards.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/datacards.cc	(revision 3445)
@@ -0,0 +1,378 @@
+//
+// $Id: datacards.cc,v 1.10 2004-09-10 09:54:48 cmv Exp $
+//
+//
+// Eric Aubourg, R. Ansari 1995-2000
+//               PEIDA (EROS) - SOPHYA
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "datacards.h"
+#include "pexceptions.h"
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#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_Nov2007/SophyaLib/SUtils/datacards.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/datacards.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/datacards.h	(revision 3445)
@@ -0,0 +1,105 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: datacards.h,v 1.5 2006-07-07 11:16:02 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:
+  /*! \cond 
+    Card structure - for internal use by DataCard 
+  */
+   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); }
+   };
+  /*! \endcond */
+   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_Nov2007/SophyaLib/SUtils/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/objlist.list	(revision 3445)
@@ -0,0 +1,4 @@
+datacards.o
+strutil.o
+strutilxx.o
+utils.o
Index: /tags/V_Nov2007/SophyaLib/SUtils/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/SUtils/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/smakefile	(revision 3445)
@@ -0,0 +1,31 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSUtils.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)datacards.o $(SOPHYAOBJP)strutilxx.o $(SOPHYAOBJP)utils.o $(SOPHYAOBJP)strutil.o
+	rm -f $(SOPHYALIBP)libSUtils.a
+ 
+$(SOPHYALIBP)libSUtils.a : $(SOPHYAOBJP)datacards.o $(SOPHYAOBJP)strutil.o $(SOPHYAOBJP)strutilxx.o $(SOPHYAOBJP)utils.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)datacards.o: datacards.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h datacards.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacards.cc
+ 
+$(SOPHYAOBJP)strutilxx.o: strutilxx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h strutilxx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  strutilxx.cc
+ 
+$(SOPHYAOBJP)utils.o: utils.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utils.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utils.cc
+ 
+$(SOPHYAOBJP)strutil.o: strutil.c strutil.h
+	$(CCOMPILE) -o $@  strutil.c
+ 
Index: /tags/V_Nov2007/SophyaLib/SUtils/strutil.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/strutil.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/strutil.c	(revision 3445)
@@ -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_Nov2007/SophyaLib/SUtils/strutil.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/strutil.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/strutil.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SUtils/strutilxx.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/strutilxx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/strutilxx.cc	(revision 3445)
@@ -0,0 +1,80 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include "strutilxx.h"
+
+
+/* methode */
+void FillVStringFrString(string const & 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;
+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 = "";
+    }
+  }
+}
+// Ajout du dernier mot eventuellement - Pas de separateur a la fin - 
+if(dum.size() > 0)  vs.push_back(dum);
+}
+
+/* methode */
+void SplitStringToVString(string const & s,vector<string>& vs,char separator)
+// Split the string "s" into a string vector "vs"
+// - Separator is "separator"
+// - If the separator is not a space (' '), the space is considered
+//   as a dummy character:
+// - If ',' is the separator, "1, 2  ,3 ,    4  " == "1,2,3,4"
+// - If ',' is the separator, "1, 2 3 ,    4  " == "1,23,4"
+// - Fill "vs" at the end: NO RESET IS DONE
+// - If ',' is the separator, ",,," is c
+// That routine is much more rapid than FillVStringFrString altouch less general
+//           (ex no '\' gestion is done)
+{
+ uint_4 ls = s.size();
+ if(ls<=0) return;
+ bool sep_non_blanc = (separator==' ')? false: true;
+ char *str = new char[ls+2];
+
+ uint_4 i=0, lstr=0;
+ while(i<ls) {
+   // le caractere n'est ni un blanc ni un separateur
+   if(s[i]!=separator && s[i]!=' ') {
+     str[lstr] = s[i]; lstr++;
+   }
+   // Condition de remplissage du vecteur
+   if(s[i]==separator || i==ls-1) {
+     if(lstr>0) {str[lstr]='\0'; vs.push_back(str); lstr=0;}
+   }
+   i++;
+ }
+
+ delete [] str;
+ return;
+}
Index: /tags/V_Nov2007/SophyaLib/SUtils/strutilxx.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/strutilxx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/strutilxx.h	(revision 3445)
@@ -0,0 +1,11 @@
+#ifndef STRUTILXX_H_SEEN
+#define STRUTILXX_H_SEEN
+
+#include "machdefs.h"
+#include <vector>
+#include <string>
+
+void FillVStringFrString(string const & s,vector<string>& vs,char sep = ' ');
+void SplitStringToVString(string const & s,vector<string>& vs,char separator=' ');
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SUtils/sutils.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/sutils.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/sutils.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SUtils/utils.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/utils.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/utils.cc	(revision 3445)
@@ -0,0 +1,113 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: utils.cc,v 1.2 2004-09-10 09:54:49 cmv Exp $
+//
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/SUtils/utils.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SUtils/utils.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SUtils/utils.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/Makefile	(revision 3445)
@@ -0,0 +1,208 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSamba.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)alm.o $(SOPHYAOBJP)bruit.o $(SOPHYAOBJP)circle.o $(SOPHYAOBJP)datacirclefake.o $(SOPHYAOBJP)harmspher.o $(SOPHYAOBJP)lambdaBuilder.o $(SOPHYAOBJP)mlobe.o $(SOPHYAOBJP)sambainit.o $(SOPHYAOBJP)scan.o $(SOPHYAOBJP)sphericaltransformserver.o
+	rm -f $(SOPHYALIBP)libSamba.a
+ 
+$(SOPHYALIBP)libSamba.a : $(SOPHYAOBJP)alm.o $(SOPHYAOBJP)bruit.o $(SOPHYAOBJP)circle.o $(SOPHYAOBJP)datacirclefake.o $(SOPHYAOBJP)harmspher.o $(SOPHYAOBJP)lambdaBuilder.o $(SOPHYAOBJP)mlobe.o $(SOPHYAOBJP)sambainit.o $(SOPHYAOBJP)scan.o $(SOPHYAOBJP)sphericaltransformserver.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)alm.o: alm.cc $(SOPHYAINCP)sopnamsp.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  alm.cc
+ 
+$(SOPHYAOBJP)bruit.o: bruit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)fmath.h bruit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  bruit.cc
+ 
+$(SOPHYAOBJP)circle.o: circle.cc $(SOPHYAINCP)sopnamsp.h \
+  circle.h $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)utilgeom.h geometry.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  circle.cc
+ 
+$(SOPHYAOBJP)datacirclefake.o: datacirclefake.cc \
+  $(SOPHYAINCP)sopnamsp.h datacirclefake.h \
+  datacirclebase.h circle.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)utilgeom.h geometry.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacirclefake.cc
+ 
+$(SOPHYAOBJP)harmspher.o: harmspher.cc $(SOPHYAINCP)machdefs.h \
+  harmspher.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  harmspher.cc
+ 
+$(SOPHYAOBJP)lambdaBuilder.o: lambdaBuilder.cc \
+  $(SOPHYAINCP)sopnamsp.h lambdaBuilder.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)nbconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lambdaBuilder.cc
+ 
+$(SOPHYAOBJP)mlobe.o: mlobe.cc $(SOPHYAINCP)sopnamsp.h mlobe.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mlobe.cc
+ 
+$(SOPHYAOBJP)sambainit.o: sambainit.cc $(SOPHYAINCP)sopnamsp.h \
+  sambainit.h $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sambainit.cc
+ 
+$(SOPHYAOBJP)scan.o: scan.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h scan.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scan.cc
+ 
+$(SOPHYAOBJP)sphericaltransformserver.o: sphericaltransformserver.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  sphericaltransformserver.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)tvector.h lambdaBuilder.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphericaltransformserver.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/Samba/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/Makefile.mgr	(revision 3445)
@@ -0,0 +1,168 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSamba.a
+clean:
+	rm -f $(OBJ)alm.o $(OBJ)bruit.o $(OBJ)circle.o $(OBJ)datacirclefake.o $(OBJ)harmspher.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)harmspher.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 $(INC)sopnamsp.h \
+ 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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.h \
+ $(INC)utilarr.h
+$(OBJ)bruit.o: bruit.cc \
+ $(INC)sopnamsp.h \
+ $(INC)fmath.h bruit.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)machdefs.h
+$(OBJ)circle.o: circle.cc \
+ $(INC)sopnamsp.h circle.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)machdefs.h \
+ $(INC)utilgeom.h \
+ $(INC)unitvector.h geometry.h
+$(OBJ)datacirclefake.o: datacirclefake.cc \
+ $(INC)sopnamsp.h \
+ datacirclefake.h datacirclebase.h circle.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)machdefs.h \
+ $(INC)utilgeom.h \
+ $(INC)unitvector.h geometry.h
+$(OBJ)harmspher.o: harmspher.cc \
+ $(INC)machdefs.h harmspher.h
+$(OBJ)lambdaBuilder.o: lambdaBuilder.cc \
+ $(INC)sopnamsp.h 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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 \
+ $(INC)sopnamsp.h mlobe.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)machdefs.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 \
+ $(INC)sopnamsp.h sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)machdefs.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h
+$(OBJ)scan.o: scan.cc $(INC)sopnamsp.h \
+ $(INC)machdefs.h scan.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)ndatablock.h \
+ $(INC)fiondblock.h \
+ $(INC)smathconst.h
+$(OBJ)sphericaltransformserver.o: sphericaltransformserver.cc \
+ $(INC)sopnamsp.h \
+ $(INC)machdefs.h \
+ sphericaltransformserver.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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_Nov2007/SophyaLib/Samba/alm.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/alm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/alm.cc	(revision 3445)
@@ -0,0 +1,89 @@
+#include "sopnamsp.h"
+#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);
+  this->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 SOPHYA::Alm<r_8>;
+template class SOPHYA::Alm<r_4>;
+#endif
Index: /tags/V_Nov2007/SophyaLib/Samba/alm.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/alm.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/alm.h	(revision 3445)
@@ -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 "srandgen.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(sa_size_t 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(sa_size_t nlmax) {this->ReSizeRow(nlmax+1);}
+inline sa_size_t Lmax() const {return this->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(sa_size_t mmax) : nmmax_(mmax)   { bm_.ReSize( (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(sa_size_t mmax) 
+  {
+    nmmax_= mmax;
+    bm_.ReSize(2* nmmax_+1);
+  }
+//inline sa_size_t Size() const {return 2*nmmax_+1;};
+inline T& operator()(sa_size_t m) {return bm_( adr_i(m));};
+inline T const& operator()(sa_size_t m) const {return *(bm_.Begin()+ adr_i(m));};
+/*! return the current value of the maximum absolute value of the index */
+inline sa_size_t Mmax() const 
+   {
+     return 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 sa_size_t adr_i(sa_size_t i) const 
+{
+  return (i+nmmax_);
+}
+
+
+
+ sa_size_t nmmax_;
+ NDataBlock<T> bm_;
+
+  };
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/Samba/bruit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/bruit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/bruit.cc	(revision 3445)
@@ -0,0 +1,679 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "sopnamsp.h"
+#include "fmath.h"
+
+#include "bruit.h"
+#include "srandgen.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 srandgen.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 srandgen.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 srandgen.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 srandgen.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 srandgen.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 srandgen.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_Nov2007/SophyaLib/Samba/bruit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/bruit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/bruit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/circle.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/circle.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/circle.cc	(revision 3445)
@@ -0,0 +1,311 @@
+#include <math.h>
+#include "sopnamsp.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_Nov2007/SophyaLib/Samba/circle.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/circle.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/circle.h	(revision 3445)
@@ -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>
+#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_Nov2007/SophyaLib/Samba/datacirclebase.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/datacirclebase.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/datacirclebase.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/datacirclefake.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/datacirclefake.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/datacirclefake.cc	(revision 3445)
@@ -0,0 +1,50 @@
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaLib/Samba/datacirclefake.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/datacirclefake.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/datacirclefake.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/geometry.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/geometry.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/geometry.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/harmspher.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/harmspher.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/harmspher.cc	(revision 3445)
@@ -0,0 +1,155 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "machdefs.h"
+#include <iostream>
+#include <float.h>
+#include <math.h>
+#include "harmspher.h"
+
+using namespace std;
+
+/*
+----------------------------------------------------------------
+ ----- Calcul des fonctions de Legendre Plm(cos(Theta)) ------ 
+----------------------------------------------------------------
+       (partie theta des harmoniques spheriques)
+
+ HarmSph_array(int lmax,int m,double cost,double *Plm)
+ HarmSph_array_teta(int lmax,int m,double teta,double *Plm)
+
+ - Input:
+     lmax, m and teta or cos(teta)    (lmax>=m)
+     array Plm with size at least "lmax-m+1"
+     (calling with HarmSph_array_teta for small teta is more accurate)
+
+ - Action:
+     compute Psph for fixed "m" and all "l" from "m" to "lmax"
+
+ - Return array: Psph(l,m)
+     index Psph(l,m) = Plm[l-m]
+
+ - Return value:
+     Psph(lmax,m) = Plm[lmax-m]
+
+ - Rappel:    x = cos(teta)
+   Polynomes de Legendre associes: P(l,m)
+   Polynomes de Legendre pour les harmoniques spheriques: Psph(l,m)
+                (souvent appelles lambda_lm)
+      Psph(l,m) = sqrt((2l+1)/4Pi) * sqrt((l-m)!/(l+m)!) * P(l,m)
+----------------------------------------------------------------
+*/
+
+double HarmSph_array_teta(int lmax,int m,double teta,double *xlm)
+{
+ // Debug level
+ const int lp=0;
+ // Si une valeur finale est <10^EXPO_MINI on retourne zero
+ const double EXPO_MINI = DBL_MIN_10_EXP +5;
+ // Si une valeur dans la reccurence est <FACTMINI on renormalise
+ const double FACTMINI = 1.e-50;
+
+ if(m<0 || m>lmax) {
+   cout<<"HarmSph_array_Error: bad arguments lmax="<<lmax<<" m="<<m<<endl;
+   return(0.);
+ }
+
+ double x = cos(teta);
+ if(lp) cout<<"HarmSph_array_teta: x="<<x<<" lmax="<<lmax<<" m="<<m<<endl;
+
+ /* ---- calcul Psph(0,0) = 1/sqrt(4Pi) */
+ xlm[0] = M_2_SQRTPI/4.;
+ if(m==0 && lmax==0) return xlm[0];
+
+ /* ---- calcul Psph(m,m):
+ Recurrence:
+   P(l,m) = (-1)^m * (2m-1)!! * (1-x^2)^(m/2)
+   Psph(m+1,m+1) = -Psph(m,m) * sin(teta)*sqrt((2m+3)/(2m+2))
+   ou Psph(m,m) = - Psph(m-1,m-1) * sin(teta)*sqrt((2m+1)/2m)
+   et Psph(0,0) = 1/sqrt(4Pi)
+ Pb: pour m grand et sin(teta) petit sin(teta)^m devient
+     plus petit que la limite machine (1e-300) et on obtient zero
+ */
+ double expos = 0.;
+ if(m>0) {          // Psph(0,0) == xlm[0]
+   //double st = sqrt((1.-x)*(1.+x));
+   double st = fabs(sin(teta));
+   for(int i=1;i<=m;i++) {
+     xlm[0] *= -sqrt(((double)i+0.5)/(double)i) *st;
+     double fxlm = fabs(xlm[0]);
+     if(fxlm<FACTMINI && fxlm>0.) {
+       if(lp>1) cout<<i<<" renorm: xlm[0]="<<xlm[0]<<" e="<<log10(fxlm);
+       xlm[0] = (xlm[0]>0.)? 1.: -1.;
+       expos += log10(fxlm);
+       if(lp>1) cout<<" --> "<<xlm[0]<<", expos="<<expos<<endl;
+     }
+   }
+ }
+ if(lp) cout<<"End computing Pmm="<<xlm[0]<<", expos="<<expos<<endl;
+
+ /* ---- calcul Psph(m+1,m):
+ Formule:
+   P(m+1,m) = cos(teta)*sqrt(2m+1)*P(m,m)
+   Psph(m+1,m) = cos(teta)*sqrt(2m+3)*Psph(m,m)
+ En fait cela s'integre sans probleme dans la recurrence generale ci-dessous
+ */
+ /* ---- calcul de Psph(l,m)  pour l>m+1 :
+ Recurrence:
+   P(l,m)  = [ (2l-1)*x * P(l-1,m) - (l-1+m) * P(l-2,m) ] / (l-m)
+   Psph(l,m) = sqrt((4*l^2-1)/(l^2-m^2))
+             * [ cos(teta) * Psph(l-1,m)
+               - sqrt(((l-1)^2-m^2)/(4*(l-1)^2-1)) * Psph(l-2,m) ]
+   Psph(l,m) = sqrt((2l-1)*(2l+1)/((l-m)*(l+m)))
+             * [ cos(teta) * Psph(l-1,m)
+               - sqrt((l-m-1)*(l-1+m)/((2l-3)*(2l-1))) * Psph(l-2,m) ]
+
+ */
+ if(lmax>m) {
+   const double expo_factmini = log10(FACTMINI);
+   double factmaxi = 1./FACTMINI;
+   double pm2=0., pm1=xlm[0], b_rec=0.;
+   for(int ll=m+1;ll<=lmax;ll++) {
+     int il = ll-m;
+     double a_rec = sqrt( (2.*ll-1.)*(2.*ll+1.)/((ll-m)*(ll+m)) );
+     xlm[il] = a_rec*(x*pm1-b_rec*pm2);
+     double fxlm = fabs(xlm[il]);
+     // Par construction "expos" est negatif ou nul (car FACTMINI<1)
+     if(expos<0. && fxlm>factmaxi) {
+       // On renormalise par factmaxi si on a encore de la reserve d'exposant
+       double fact,efact;
+       if(expos<expo_factmini) {
+         fact  = factmaxi;
+         efact = -expo_factmini;
+         expos += efact;
+       } else {
+         fact = pow(10.,expos);
+         efact = expos;
+         expos = 0.;
+         if(lp>1) cout<<"!! expos==0 !!"<<endl;
+       }
+       if(lp>1) cout<<ll<<" renorm: xlm["<<il<<"]="<<xlm[il]<<", expos="<<expos<<endl;
+       for(int i=0;i<=ll-m;i++) xlm[i] /= fact;
+     }
+     pm2 = xlm[il-1];
+     pm1 = xlm[il];
+     b_rec = 1./a_rec;
+   }
+ }
+
+ if(lp) cout<<"Return: Final expos="<<expos<<endl;
+ if(expos!=0.) {
+   for(int i=0;i<=lmax-m;i++) {
+     double fxml=fabs(xlm[i]);
+     if(lp>1) cout<<"     xlm["<<i<<"]="<<xlm[i];
+     if(fxml>0.) {
+       double e = log10(fxml);
+       if(lp>1) cout<<" (e="<<e<<")";
+       if(expos+e<EXPO_MINI) xlm[i] = 0.;
+       else if(expos>EXPO_MINI) xlm[i] *= pow(10.,expos);
+       else xlm[i] = pow(10.,expos+e);
+     }
+     if(lp>1) cout<<" ---> "<<xlm[i]<<endl;
+   }
+ }
+ return xlm[lmax-m];
+
+}
Index: /tags/V_Nov2007/SophyaLib/Samba/harmspher.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/harmspher.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/harmspher.h	(revision 3445)
@@ -0,0 +1,12 @@
+#ifndef HARMSPHER_SEEN
+#define HARMSPHER_SEEN
+
+double HarmSph_array_teta(int lmax,int m,double teta,double *xlm);
+
+inline double HarmSph_array(int lmax,int m,double x,double *xlm)
+  {
+  if(x>1.) x=1.; else if(x<-1.) x=-1.;
+  return HarmSph_array_teta(lmax,m,acos(x),xlm);
+  }
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/Samba/lambdaBuilder.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/lambdaBuilder.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/lambdaBuilder.cc	(revision 3445)
@@ -0,0 +1,476 @@
+#include "sopnamsp.h"
+#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)
+   {
+     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.) );
+
+       }
+   }
+
+/*!
+  \brief : Specialized/optimized static function for fast spherical harmonic transform.
+  Computes bm(m) = Sum_l>=m [ lambda(l,m) * alm(l,m) ] 
+  See SphericalTransformServer<T>::GenerateFromAlm(map, pixsize, alm)
+*/
+void LambdaLMBuilder::ComputeBmFrAlm(r_8 theta,int_4 lmax, int_4 mmax, 
+				     const Alm<r_8>& alm, Bm< complex<r_8> >& bm)
+{
+  updateArrayRecurrence(lmax);
+  r_8 cth = cos(theta);
+  r_8 sth = sin(theta);
+  
+  r_8 bignorm2 = 1.e268; // = 1e-20*1.d288
+  
+  r_8 lam_mm = 1. / sqrt(4.*Pi) *bignorm2;
+  register r_8 lam_0, lam_1, lam_2;
+
+  int_4 l, m, k;
+
+  for (m=0; m<=mmax;m++)   {
+    const complex<r_8>* almp = alm.columnData(m); 
+    complex<r_8>* bmp = &(bm(m));
+    r_8* arecp = a_recurrence_.columnData(m); 
+    *bmp = (lam_mm / bignorm2)*almp[0];  almp++;
+
+    lam_0=0.;
+    lam_1=1. /bignorm2 ;
+    
+    //    for (l=m+1; l<=lmax; l++) {
+    for (k=0; k<lmax-m; k++) {
+      lam_2 = (cth*lam_1-lam_0)*arecp[k];
+      lam_0 = lam_1/arecp[k];
+      lam_1 = lam_2;
+
+      *bmp += (lam_2*lam_mm)*almp[k];  
+    }
+    lam_mm = -lam_mm*sth* sqrt( (2.*m+3.)/ (2.*m+2.) );
+  }
+}
+
+/*!
+  \brief : Specialized/optimized static function for fast spherical harmonic transform.
+*/
+void LambdaLMBuilder::ComputeBmFrAlm(r_8 theta,int_4 lmax, int_4 mmax,  
+				     const Alm<r_4>& alm, Bm< complex<r_4> >& bm)
+{
+  Alm<r_8> alm8(alm.Lmax());
+  for(sa_size_t k=0; k<alm8.Size(); k++) 
+    alm8(k) = complex<r_8>((r_8)alm(k).real() , (r_8)alm(k).imag());
+  Bm< complex<r_8> > bm8(bm.Mmax());
+  ComputeBmFrAlm(theta, lmax, mmax, alm8, bm8);
+  for(sa_size_t kk=-bm.Mmax(); kk<=bm.Mmax(); kk++) 
+    bm(kk)= complex<r_4>((r_4)bm8(kk).real() , (r_4)bm8(kk).imag());
+  return;
+}
+
+
+/*!
+  \brief : Specialized/optimized static function for fast spherical harmonic transform.
+  Computes alm(l,m) = Sum_l>=m [ lambda(l,m) * phase(l,m) ] 
+  See SphericalTransformServer<T>::carteVersAlm(SphericalMap<T>& map, nlmax, ctcut, alm) 
+*/
+void LambdaLMBuilder::ComputeAlmFrPhase(r_8 theta,int_4 lmax, int_4 mmax, 
+					TVector< complex<r_8> >& phase, Alm<r_8> & alm)
+{
+  updateArrayRecurrence(lmax);
+  r_8 cth = cos(theta);
+  r_8 sth = sin(theta);
+  
+  r_8 bignorm2 = 1.e268; // = 1e-20*1.d288
+  
+  r_8 lam_mm = 1. / sqrt(4.*Pi) *bignorm2;
+  register r_8 lam_0, lam_1, lam_2;
+  
+  int_4 l, m, k;
+
+  for (m=0; m<=mmax;m++)  {
+    complex<r_8>* almp = alm.columnData(m); 
+    complex<r_8>  phi = phase(m);
+    
+    *almp += (lam_mm / bignorm2)*phi;    almp++;
+
+    lam_0=0.;
+    lam_1=1. /bignorm2 ;
+    
+    r_8* arecp = a_recurrence_.columnData(m); 
+    //    for (l=m+1; l<=lmax; l++)   {
+    for (k=0; k<lmax-m; k++) {
+      lam_2 = (cth*lam_1-lam_0)*arecp[k];
+      lam_0 = lam_1/arecp[k];
+      lam_1 = lam_2;
+
+      almp[k] += (lam_2*lam_mm) * phi; 
+    }
+    lam_mm = -lam_mm*sth* sqrt( (2.*m+3.)/ (2.*m+2.) );
+  }
+}
+
+/*!
+  \brief : Specialized/optimized static function for fast spherical harmonic transform.
+  Computes alm(l,m) = Sum_l>=m [ lambda(l,m) * phase(l,m) ] 
+  See SphericalTransformServer<T>::carteVersAlm(SphericalMap<T>& map, nlmax, ctcut, alm) 
+*/
+void LambdaLMBuilder::ComputeAlmFrPhase(r_8 theta,int_4 lmax, int_4 mmax, 
+					TVector< complex<r_4> >& phase, Alm<r_4> & alm) 
+{
+  updateArrayRecurrence(lmax);
+  r_8 cth = cos(theta);
+  r_8 sth = sin(theta);
+  
+  r_8 bignorm2 = 1.e268; // = 1e-20*1.d288
+  
+  r_8 lam_mm = 1. / sqrt(4.*Pi) *bignorm2;
+  register r_8 lam_0, lam_1, lam_2;
+  
+  int_4 l, m, k;
+
+  for (m=0; m<=mmax;m++)  {
+    complex<r_4>* almp = alm.columnData(m); 
+    complex<r_4>  phi = phase(m);
+    
+    *almp += ((r_4)(lam_mm / bignorm2))*phi;    almp++;
+
+    lam_0=0.;
+    lam_1=1. /bignorm2 ;
+    
+    r_8* arecp = a_recurrence_.columnData(m); 
+    //    for (l=m+1; l<=lmax; l++)   {
+    for (k=0; k<lmax-m; k++) {
+      lam_2 = (cth*lam_1-lam_0)*arecp[k];
+      lam_0 = lam_1/arecp[k];
+      lam_1 = lam_2;
+
+      almp[k] += ((r_4)(lam_2*lam_mm)) * phi; 
+    }
+    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)
+   {
+     if ( (a_recurrence_.Size() > 0) && (lmax < a_recurrence_.rowNumber()) ) 
+       return;  // Pas besoin de recalculer le tableau de recurrence
+     if (a_recurrence_.Size() > 0)  {
+       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()-1 << endl;
+	 }
+
+     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_Nov2007/SophyaLib/Samba/lambdaBuilder.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/lambdaBuilder.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/lambdaBuilder.h	(revision 3445)
@@ -0,0 +1,165 @@
+#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() {};
+
+
+//--- Optimisation Reza mai 2006 Serie de fonctions statiques 
+// specialisees/optimisees pour SphericalTransform
+static void ComputeBmFrAlm(r_8 theta,int_4 lmax, int_4 mmax, 
+			   const Alm<r_8>& alm, Bm< complex<r_8> >& bm);
+static void ComputeBmFrAlm(r_8 theta,int_4 lmax, int_4 mmax, 
+			   const Alm<r_4>& alm, Bm< complex<r_4> >& bm);
+static void ComputeAlmFrPhase(r_8 theta,int_4 lmax, int_4 mmax, 
+			      TVector< complex<r_8> >& phase, Alm<r_8> & alm);
+static void ComputeAlmFrPhase(r_8 theta,int_4 lmax, int_4 mmax, 
+			      TVector< complex<r_4> >& phase, Alm<r_4> & alm);
+//---- Fin foctions specialisees
+
+ /*! 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:
+ static 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_Nov2007/SophyaLib/Samba/misstime.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/misstime.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/misstime.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/mlobe.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/mlobe.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/mlobe.cc	(revision 3445)
@@ -0,0 +1,240 @@
+#include "sopnamsp.h"
+#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 "srandgen.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-- */
+//++
+void MainLobe::Print(ostream& os) const
+//
+//--
+{
+os << "MainLobe_Info() : Sigma= " << mSigma << " Dels= " << mDels << " NC= " 
+  << mNC << " NTotPix= " << mNpix << " Integ= " << mTotVal << endl;
+
+int i,j,k;
+os << " Direction Teta,Phi = " << mDirTet << " , " << mDirPhi << endl;      
+os << " Pixel 0 , Teta= " << mT0[0] << " Phi= " << mP0[0] 
+     << " Val= " << mVal[0] << endl;
+k = 1;
+for(i=1; i<mNC; i++) {
+  os << " Couche # " << i << " NPix= " << i*6 << endl;
+  for(j=0;j<6*i;j++) {
+    os << "K= " << k << "Teta,Phi= "  << mTC[k] << ", " << mPC[k] 
+         << " (" << mT0[k] << ", " << mP0[k] << ") "
+         << " Val= " << mVal[k] << endl; 
+    k++;
+    }
+  }
+
+}
+
Index: /tags/V_Nov2007/SophyaLib/Samba/mlobe.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/mlobe.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/mlobe.h	(revision 3445)
@@ -0,0 +1,58 @@
+// 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>
+
+#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);
+	       void     Print(ostream& os) const; 
+
+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;
+};
+
+inline ostream& operator << (ostream& s, MainLobe const & ml)
+  {  ml.Print(s);  return(s);  }
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/Samba/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/objlist.list	(revision 3445)
@@ -0,0 +1,10 @@
+alm.o
+bruit.o
+circle.o
+datacirclefake.o
+harmspher.o
+lambdaBuilder.o
+mlobe.o
+sambainit.o
+scan.o
+sphericaltransformserver.o
Index: /tags/V_Nov2007/SophyaLib/Samba/prefcount.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/prefcount.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/prefcount.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/samba.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/samba.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/samba.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/sambainit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/sambainit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/sambainit.cc	(revision 3445)
@@ -0,0 +1,43 @@
+// Classe d'initialisation du module Samba 
+
+#include "sopnamsp.h"
+#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;
+
+// Module version number - 
+#define MOD_VERS   1.3
+
+SambaInitiator::SambaInitiator()
+  : SkyMapInitiator()
+{
+  SambaInitiator::FgInit++;
+  if (SambaInitiator::FgInit > 1)  return;
+  ntinit = new NToolsInitiator;
+
+  SophyaInitiator::RegisterModule("Samba", MOD_VERS);  // Module name and version number registration
+}
+
+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_Nov2007/SophyaLib/Samba/sambainit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/sambainit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/sambainit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/Samba/scan.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/scan.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/scan.cc	(revision 3445)
@@ -0,0 +1,443 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "scan.h"
+#include <complex>
+#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_Nov2007/SophyaLib/Samba/scan.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/scan.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/scan.h	(revision 3445)
@@ -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>
+#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_Nov2007/SophyaLib/Samba/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/Samba/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/smakefile	(revision 3445)
@@ -0,0 +1,208 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSamba.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)alm.o $(SOPHYAOBJP)bruit.o $(SOPHYAOBJP)circle.o $(SOPHYAOBJP)datacirclefake.o $(SOPHYAOBJP)harmspher.o $(SOPHYAOBJP)lambdaBuilder.o $(SOPHYAOBJP)mlobe.o $(SOPHYAOBJP)sambainit.o $(SOPHYAOBJP)scan.o $(SOPHYAOBJP)sphericaltransformserver.o
+	rm -f $(SOPHYALIBP)libSamba.a
+ 
+$(SOPHYALIBP)libSamba.a : $(SOPHYAOBJP)alm.o $(SOPHYAOBJP)bruit.o $(SOPHYAOBJP)circle.o $(SOPHYAOBJP)datacirclefake.o $(SOPHYAOBJP)harmspher.o $(SOPHYAOBJP)lambdaBuilder.o $(SOPHYAOBJP)mlobe.o $(SOPHYAOBJP)sambainit.o $(SOPHYAOBJP)scan.o $(SOPHYAOBJP)sphericaltransformserver.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)alm.o: alm.cc $(SOPHYAINCP)sopnamsp.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  alm.cc
+ 
+$(SOPHYAOBJP)bruit.o: bruit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)fmath.h bruit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  bruit.cc
+ 
+$(SOPHYAOBJP)circle.o: circle.cc $(SOPHYAINCP)sopnamsp.h \
+  circle.h $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)utilgeom.h geometry.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  circle.cc
+ 
+$(SOPHYAOBJP)datacirclefake.o: datacirclefake.cc \
+  $(SOPHYAINCP)sopnamsp.h datacirclefake.h \
+  datacirclebase.h circle.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)utilgeom.h geometry.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  datacirclefake.cc
+ 
+$(SOPHYAOBJP)harmspher.o: harmspher.cc $(SOPHYAINCP)machdefs.h \
+  harmspher.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  harmspher.cc
+ 
+$(SOPHYAOBJP)lambdaBuilder.o: lambdaBuilder.cc \
+  $(SOPHYAINCP)sopnamsp.h lambdaBuilder.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)nbconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lambdaBuilder.cc
+ 
+$(SOPHYAOBJP)mlobe.o: mlobe.cc $(SOPHYAINCP)sopnamsp.h mlobe.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mlobe.cc
+ 
+$(SOPHYAOBJP)sambainit.o: sambainit.cc $(SOPHYAINCP)sopnamsp.h \
+  sambainit.h $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sambainit.cc
+ 
+$(SOPHYAOBJP)scan.o: scan.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h scan.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scan.cc
+ 
+$(SOPHYAOBJP)sphericaltransformserver.o: sphericaltransformserver.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  sphericaltransformserver.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)tvector.h lambdaBuilder.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphericaltransformserver.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.cc	(revision 3445)
@@ -0,0 +1,1348 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <math.h>
+#include <complex>
+#include "sphericaltransformserver.h"
+#include "tvector.h"
+#include "srandgen.h"
+#include "nbmath.h"
+#include "timing.h"
+//#include "spherehealpix.h"
+
+
+/*! 
+  \ingroup Samba
+  \class SOPHYA::SphericalTransformServer
+  
+  \brief Analysis/synthesis in spherical harmonics server.
+
+ Class for performing analysis and synthesis of sky maps using spin-0 or spin-2 spherical harmonics.
+
+Maps must be SOPHYA SphericalMaps (SphereHEALPix or SphereThetaPhi or SphereECP).
+
+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;
+
+  Bm<complex<T> > b_m_theta(nmmax);
+
+  // 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();
+    if (nph < 2) continue;  // On laisse tomber les tranches avec un point
+    //       -----------------------------------------------------
+    //	      for each theta, and each m, computes
+    //	      b(m,theta) = sum_over_l>m (lambda_l_m(theta) * a_l_m) 
+    //	      ------------------------------------------------------
+    // ===> Optimisation Reza, Mai 2006 
+    /*---  Le bout de code suivant est remplace par l'appel a la nouvelle fonction
+      qui calcule la somme au vol 
+      LambdaLMBuilder lb(theta,nlmax,nmmax);
+      //  somme sur m de 0 a l'infini
+      for (int_4 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);
+      }
+      ------- Fin version PRE-Mai2006 */
+    LambdaLMBuilder::ComputeBmFrAlm(theta,nlmax,nmmax, alm, b_m_theta);
+    //Fin Optimisation Reza, Mai 2006 <==== 
+
+    //        obtains the negative m of b(m,theta) (= complex conjugate)
+    for (int_4 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)
+    // ---------------------------------------------------------------*/
+
+    /* ----- Reza, Juin 2006 : 
+       En verifiant la difference entre deux cartes 
+       cl -> map -> alm -> map2 et mapdiff = map-map2 
+       je me suis apercu qu'il y avait des differences importantes - dans les
+       deux zones 'polar cap' de HEALPix - qui utilisait RfourierSynthesisFromB
+       TF complex -> reel . Le probleme venant de l'ambiguite de taille, lie 
+       a la partie imaginaire de la composante a f_nyquist , j'ai corrige et 
+       tout mis en TF complexe -> reel 
+    */
+    TVector<T> Temp = RfourierSynthesisFromB(b_m_theta,nph,phi0);
+    // Si on peut acceder directement les pixels d'un tranche, on le fait
+    T* pix = map.GetThetaSliceDataPtr(ith);
+    if (pix != NULL) 
+      for (int_4 i=0;i< nph;i++) pix[i] = Temp(i);
+    else 
+      for (int_4 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_m' (exp(i*m'*phi(j)) somme_k 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_m' (exp(i*m'*phi(j)) somme_k 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_k 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> > 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++)  
+    data(mprime)=bw(mprime)*complex<T>((T)cos(mprime*phi0),(T)sin(mprime*phi0));    
+  TVector<T> sortie(nph);
+// On met la partie imaginaire du dernier element du data a zero pour nph pair
+  if (nph%2 == 0) data(nph/2) = complex<T>(data(nph/2).real(), (T)0.);
+// et on impose l'utilisation de la taille en sortie pour FFTBack (..., ..., true)
+  fftIntfPtr_-> FFTBackward(data, sortie, true); 
+  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
+//	-----------------------------------------------------------------------
+
+      // ===> Optimisation Reza, Mai 2006 
+      /*---  Le bout de code suivant est remplace par l'appel a la nouvelle fonction
+        qui calcule la somme au vol 
+      //        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 ; 
+	    }
+	}
+      ------- Fin version PRE-Mai2006 */
+      r_8 domega=map.PixSolAngle(map.PixIndexSph(theta,phi0));
+      phase *= complex<T>((T)domega, 0.);
+      LambdaLMBuilder::ComputeAlmFrPhase(theta,nlmax,nmmax, phase, alm);
+      //Fin Optimisation Reza, Mai 2006 <==== 
+      
+
+      
+      //
+      //
+      //       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);
+  // Il faut avoir instancie le serveur de FFT avec l'option preserveinput=true
+  fftIntfPtr_-> FFTForward(const_cast<TVector< complex<T> > &>(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;
+  // Il faut avoir instancie le serveur de FFT avec l'option preserveinput=true
+  fftIntfPtr_-> FFTForward(const_cast< TVector<T> &>(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");
+      
+    }
+  bool healpix = true;
+  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.
+    healpix = false;
+    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, healpix);
+    // 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, bool healpix) 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, bool healpix) const
+{
+  int i;
+
+  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));
+	}
+      if (healpix) 
+	{
+	  TVector<T> Tempq = RfourierSynthesisFromB(b_m_theta_q,nph,phi0);  
+	  TVector<T> Tempu = RfourierSynthesisFromB(b_m_theta_u,nph,phi0); 
+	  for (i=0;i< nph;i++)
+	    {
+	      mapq(pixNumber(i))=Tempq(i);
+	      mapu(pixNumber(i))=Tempu(i);
+	    }
+	}
+      else
+	// pour des pixelisations quelconques (autres que HEALPix
+	//  nph n'est pas toujours pair
+	// ca fait des problemes pour les transformees de Fourier
+	// car le server de TF ajuste la longueur du vecteur reel 
+	// en sortie de TF, bref, la securite veut qu'on prenne une 
+	// TF complexe
+	{
+          TVector<complex<T> > Tempq = fourierSynthesisFromB(b_m_theta_q,nph,phi0);  
+	  TVector<complex<T> > Tempu = fourierSynthesisFromB(b_m_theta_u,nph,phi0); 
+	  for (i=0;i< nph;i++)
+	    {
+	      mapq(pixNumber(i))=Tempq(i).real();
+	      mapu(pixNumber(i))=Tempu(i).real();
+	    }
+	}
+    } 
+}
+/*! \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 SOPHYA::SphericalTransformServer<r_8>;
+template class SOPHYA::SphericalTransformServer<r_4>;
+#endif
Index: /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/sphericaltransformserver.h	(revision 3445)
@@ -0,0 +1,125 @@
+#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(true); // preserveinput = true
+      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.
+ \warning The FFTServerInterface object should NOT overwrite the input arrays
+*/
+  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, bool healpix) 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_Nov2007/SophyaLib/Samba/tod.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/Samba/tod.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/Samba/tod.h	(revision 3445)
@@ -0,0 +1,58 @@
+// 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)); }
+
+protected:
+  SphereCoordSys* cs_ ;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.cc	(revision 3445)
@@ -0,0 +1,715 @@
+// utilitaires de pixelisation HEALPix
+#include "sopnamsp.h"
+#include "HEALPixUtils.h"
+#include <iostream>
+#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);
+}
+
+ 
+/*! 
+  \brief return the size index value corresponding to resolution \b res  
+  Computes the size index m providing a resolution better or equal the 
+  specified value \b res (in radian)
+
+  - m : size-index 
+  - number of pixels for 4Pi : 12*m*m
+
+  \sa SOPHYA::Angle
+*/
+int_4 HEALPix::ResolToSizeIndex(double res)
+{
+  int_4 m = 1;
+  double cres = sqrt(M_PI/3.); // 4PI/12
+  while (cres > 1.001*res) {
+    m *= 2;
+    cres = sqrt(4.*M_PI/(12*m*m));
+  }
+  return m;
+}  
+
+//! return the pixel resolution for a given size index (nside)
+double HEALPix::SizeIndexToResol(int_4 m)
+{
+  double res = 4.*M_PI/(double)(12*m*m);
+  return sqrt(res);
+}  
Index: /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/HEALPixUtils.h	(revision 3445)
@@ -0,0 +1,36 @@
+#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) ;
+  
+  static int_4  ResolToSizeIndex(double res);  
+  static inline int_4  ResolToNSide(double res) 
+  { return   ResolToSizeIndex(res); }
+  static double SizeIndexToResol(int_4 m);  
+  static inline double  NSideToResol(int_4 m) 
+  { return  SizeIndexToResol(m); }
+};
+
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/Makefile	(revision 3445)
@@ -0,0 +1,396 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSkyMap.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)HEALPixUtils.o $(SOPHYAOBJP)fiolocalmap.o $(SOPHYAOBJP)fiosphereecp.o $(SOPHYAOBJP)fiospherehealpix.o $(SOPHYAOBJP)fiospherethetaphi.o $(SOPHYAOBJP)localmap.o $(SOPHYAOBJP)longlat.o $(SOPHYAOBJP)mapoperation.o $(SOPHYAOBJP)skymapinit.o $(SOPHYAOBJP)sphereecp.o $(SOPHYAOBJP)spherehealpix.o $(SOPHYAOBJP)spherepos.o $(SOPHYAOBJP)spherethetaphi.o $(SOPHYAOBJP)unitvector.o $(SOPHYAOBJP)utilgeom.o $(SOPHYAOBJP)vector3d.o
+	rm -f $(SOPHYALIBP)libSkyMap.a
+ 
+$(SOPHYALIBP)libSkyMap.a : $(SOPHYAOBJP)fiolocalmap.o $(SOPHYAOBJP)fiosphereecp.o $(SOPHYAOBJP)fiospherehealpix.o $(SOPHYAOBJP)fiospherethetaphi.o $(SOPHYAOBJP)HEALPixUtils.o $(SOPHYAOBJP)localmap.o $(SOPHYAOBJP)longlat.o $(SOPHYAOBJP)mapoperation.o $(SOPHYAOBJP)skymapinit.o $(SOPHYAOBJP)sphereecp.o $(SOPHYAOBJP)spherehealpix.o $(SOPHYAOBJP)spherepos.o $(SOPHYAOBJP)spherethetaphi.o $(SOPHYAOBJP)unitvector.o $(SOPHYAOBJP)utilgeom.o $(SOPHYAOBJP)vector3d.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)HEALPixUtils.o: HEALPixUtils.cc \
+  $(SOPHYAINCP)sopnamsp.h HEALPixUtils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  HEALPixUtils.cc
+ 
+$(SOPHYAOBJP)fiolocalmap.o: fiolocalmap.cc \
+  $(SOPHYAINCP)sopnamsp.h fiolocalmap.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h localmap.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiolocalmap.cc
+ 
+$(SOPHYAOBJP)fiosphereecp.o: fiosphereecp.cc \
+  $(SOPHYAINCP)sopnamsp.h fiosphereecp.h \
+  sphereecp.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiosphereecp.cc
+ 
+$(SOPHYAOBJP)fiospherehealpix.o: fiospherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h fiospherehealpix.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h spherehealpix.h \
+  HEALPixUtils.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiospherehealpix.cc
+ 
+$(SOPHYAOBJP)fiospherethetaphi.o: fiospherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h fiospherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h spherethetaphi.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiospherethetaphi.cc
+ 
+$(SOPHYAOBJP)localmap.o: localmap.cc $(SOPHYAINCP)sopnamsp.h \
+  localmap.h pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  localmap.cc
+ 
+$(SOPHYAOBJP)longlat.o: longlat.cc $(SOPHYAINCP)sopnamsp.h \
+  longlat.h $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  longlat.cc
+ 
+$(SOPHYAOBJP)mapoperation.o: mapoperation.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h mapoperation.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mapoperation.cc
+ 
+$(SOPHYAOBJP)skymapinit.o: skymapinit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h spherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h fiospherehealpix.h \
+  spherehealpix.h HEALPixUtils.h fiospherethetaphi.h fiolocalmap.h \
+  localmap.h fiosphereecp.h sphereecp.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapinit.cc
+ 
+$(SOPHYAOBJP)sphereecp.o: sphereecp.cc $(SOPHYAINCP)sopnamsp.h \
+  sphereecp.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphereecp.cc
+ 
+$(SOPHYAOBJP)spherehealpix.o: spherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h spherehealpix.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h HEALPixUtils.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherehealpix.cc
+ 
+$(SOPHYAOBJP)spherepos.o: spherepos.cc $(SOPHYAINCP)sopnamsp.h \
+  spherepos.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherepos.cc
+ 
+$(SOPHYAOBJP)spherethetaphi.o: spherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h spherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherethetaphi.cc
+ 
+$(SOPHYAOBJP)unitvector.o: unitvector.cc \
+  $(SOPHYAINCP)sopnamsp.h unitvector.h vector3d.h \
+  longlat.h $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  unitvector.cc
+ 
+$(SOPHYAOBJP)utilgeom.o: utilgeom.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utilgeom.cc
+ 
+$(SOPHYAOBJP)vector3d.o: vector3d.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h vector3d.h longlat.h \
+  utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  vector3d.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/SkyMap/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyMap/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/Makefile.mgr	(revision 3445)
@@ -0,0 +1,261 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSkyMap.a
+clean:
+	rm -f $(OBJ)HEALPixUtils.o $(OBJ)fiolocalmap.o $(OBJ)fiosphereecp.o $(OBJ)fiospherehealpix.o $(OBJ)fiospherethetaphi.o $(OBJ)localmap.o $(OBJ)longlat.o $(OBJ)mapoperation.o $(OBJ)skymapinit.o $(OBJ)sphereecp.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)fiosphereecp.o $(OBJ)fiospherehealpix.o $(OBJ)fiospherethetaphi.o $(OBJ)localmap.o $(OBJ)longlat.o $(OBJ)mapoperation.o $(OBJ)skymapinit.o $(OBJ)sphereecp.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)fioarr.h \
+ $(INC)fiondblock.h \
+ $(INC)datatype.h
+$(OBJ)fiosphereecp.o: fiosphereecp.cc fiosphereecp.h sphereecp.h \
+ sphericalmap.h $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)fioarr.h \
+ $(INC)datatype.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 \
+ $(INC)datatype.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 \
+ $(INC)datatype.h
+$(OBJ)localmap.o: localmap.cc localmap.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)fiondblock.h \
+ $(INC)timing.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 fiosphereecp.h sphereecp.h
+$(OBJ)sphereecp.o: sphereecp.cc sphereecp.h sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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
+$(OBJ)spherehealpix.o: spherehealpix.cc \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)fiondblock.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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 \
+ $(INC)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.h unitvector.h vector3d.h \
+ longlat.h utilgeom.h $(INC)anydataobj.h \
+ $(INC)datatype.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)ppfbinstream.h \
+ $(INC)rawstream.h \
+ $(INC)ppfnametag.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)fiondblock.h
+$(OBJ)unitvector.o: unitvector.cc unitvector.h vector3d.h longlat.h \
+ $(INC)machdefs.h utilgeom.h
+$(OBJ)utilgeom.o: utilgeom.cc $(INC)machdefs.h \
+ utilgeom.h
+$(OBJ)vector3d.o: vector3d.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h vector3d.h longlat.h \
+ utilgeom.h
Index: /tags/V_Nov2007/SophyaLib/SkyMap/fiolocalmap.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiolocalmap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiolocalmap.cc	(revision 3445)
@@ -0,0 +1,236 @@
+// G. Le Meur 04/2000
+
+#include "sopnamsp.h"
+#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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/SkyMap/fiolocalmap.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiolocalmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiolocalmap.h	(revision 3445)
@@ -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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.cc	(revision 3445)
@@ -0,0 +1,151 @@
+// G. Le Meur 04/2000
+
+#include "sopnamsp.h"
+#include "fiosphereecp.h"
+#include "fioarr.h"
+#include "pexceptions.h"
+#include "datatype.h"
+#include <typeinfo>
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les classes delegues pour la gestion de persistance 
+// --------------------------------------------------------
+//////////////////////////////////////////////////////////
+namespace SOPHYA {
+
+template <class T>
+FIO_SphereECP<T>::FIO_SphereECP()
+{
+  dobj= new SphereECP<T>;
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereECP<T>::FIO_SphereECP(string const& filename)
+{
+  dobj= new SphereECP<T>;
+  ownobj= true;
+  Read(filename);
+}
+
+template <class T>
+FIO_SphereECP<T>::FIO_SphereECP(const SphereECP<T>& obj)
+{
+  dobj= new SphereECP<T>(obj, true);
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereECP<T>::FIO_SphereECP(SphereECP<T>* obj)
+{
+  dobj= obj;
+  ownobj= false;
+}
+
+template <class T>
+FIO_SphereECP<T>::~FIO_SphereECP()
+{
+  if (ownobj && dobj) delete dobj;
+}
+
+template <class T>
+AnyDataObj* FIO_SphereECP<T>::DataObj()
+{
+  return(dobj);
+}
+
+
+template <class T>
+void FIO_SphereECP<T>::SetDataObj(AnyDataObj & o)
+{
+  SphereECP<T> * po = dynamic_cast< SphereECP<T> * >(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_SphereECP<%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_SphereECP<T>::ReadSelf(PInPersist& is)
+{
+  if(dobj == NULL)  {
+    dobj= new SphereECP<T>;
+    ownobj= true;      
+  }
+  
+  // On lit les 3 premiers uint_8
+  int_4 itab[4];
+  is.Get(itab, 4);
+  dobj->_partial = (itab[1] & 1) ? true : false;
+
+  is >> dobj->_theta1 >> dobj->_theta2 ; 
+  is >> dobj->_phi1 >> dobj->_phi2; 
+  is >> dobj->_dtheta >> dobj->_dphi;
+  is >> dobj->_outofmapidx >> dobj->_outofmappix >> dobj->_outofmapval;
+  // Let's Read the SphereCoordSys object  -- ATTENTIOn - $CHECK$
+  FIO_SphereCoordSys fio_scs( dobj->GetCoordSys());
+  fio_scs.Read(is);
+  // S'il y avait un objet Info() a lire 
+  if (itab[1] & 2)  is >> dobj->Info();  
+  // On lit le tableau des pixels
+  is >> dobj->_pixels;
+}
+
+template <class T>
+void FIO_SphereECP<T>::WriteSelf(POutPersist& os) const
+{
+  if(dobj == NULL) {
+      cout << " FIO_SphereECP<T>::WriteSelf:: dobj= null " << endl;
+      return;
+    }
+//  On ecrit 4 int_4 
+//  itab[0] : Numero de version,  
+//itab[1] = 0 full map, , =1 partial map  (bit 0) , bit 1 set -> has info
+//  itab[2], itab[3]  reserve a un usage futur
+  int_4 itab[4];
+  itab[0] = 1;
+  itab[1] = (dobj->IsPartial()) ? 1 : 0;
+  if (dobj->ptrInfo() != NULL)  itab[1] |= 
+  itab[2] = itab[3] = 0;
+  os.Put(itab, 4);
+
+  os << dobj->_theta1 << dobj->_theta2 ; 
+  os << dobj->_phi1 << dobj->_phi2; 
+  os << dobj->_dtheta << dobj->_dphi;
+  os << dobj->_outofmapidx << dobj->_outofmappix << dobj->_outofmapval;
+
+  // Let's write the SphereCoordSys object
+  FIO_SphereCoordSys fio_scs( dobj->GetCoordSys());
+  fio_scs.Write(os);
+  // On ecrit l'objet info si necessaire
+  if (dobj->ptrInfo() != NULL) os << dobj->Info();
+
+  // On ecrit le tableau des pixels
+  os << dobj->_pixels;
+}
+
+}// Fin du namespace
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FIO_SphereECP<int_4>
+#pragma define_template FIO_SphereECP<r_8>
+#pragma define_template FIO_SphereECP<r_4>
+#pragma define_template FIO_SphereECP< complex<r_4> >
+#pragma define_template FIO_SphereECP< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+namespace SOPHYA {
+template class FIO_SphereECP<int_4>;
+template class FIO_SphereECP<r_8>;
+template class FIO_SphereECP<r_4>;
+template class FIO_SphereECP< complex<r_4> >;
+template class FIO_SphereECP< complex<r_8> >;
+}
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiosphereecp.h	(revision 3445)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de persistance PPF pour les sphereECP 
+// R. Ansari, Septembre 2004 
+
+#ifndef FIOSPHEREECP_SEEN
+#define FIOSPHEREECP_SEEN
+
+#include "sphereecp.h"
+#include "ppersist.h"
+
+
+namespace SOPHYA {
+
+template <class T>
+class FIO_SphereECP : public PPersist  
+{
+public:
+
+FIO_SphereECP();
+FIO_SphereECP(string const & filename); 
+FIO_SphereECP(const SphereECP<T>& obj);
+FIO_SphereECP(SphereECP<T>* obj);
+virtual ~FIO_SphereECP();
+virtual AnyDataObj* DataObj();
+void SetDataObj(AnyDataObj & o);
+inline operator SphereECP<T>() { return(*dobj); }
+
+protected :
+
+virtual void ReadSelf(PInPersist&);           
+virtual void WriteSelf(POutPersist&) const;  
+SphereECP<T>* dobj;
+bool ownobj;
+};
+
+/*! \ingroup SkyMap \fn operator<<(POutPersist&,SphereECP<T>&)
+  \brief Write SphereECP \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, SphereECP<T> & obj)
+{ FIO_SphereECP<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup SkyMap \fn operator>>(PInPersist&,SphereECP<T>&)
+  \brief Read SphereECP \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, SphereECP<T> & obj)
+{ FIO_SphereECP<T> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/fiospherehealpix.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiospherehealpix.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiospherehealpix.cc	(revision 3445)
@@ -0,0 +1,191 @@
+// G. Le Meur 04/2000
+
+#include "sopnamsp.h"
+#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);
+ 
+//  Juin 2006 : NumVer 1->2 avec mise en place de HEALPix NESTED
+//  Si itab[2]==1 --> NESTED 
+bool fgring = true;
+if (itab[2] == 1) fgring = false;
+
+// 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, fgring);
+
+// 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
+//  Juin 2006 : NumVer 1->2 avec mise en place de HEALPix NESTED
+//  totalement back-compatible , on utilise itab[2] qu'on met a 1
+//  pour NESTED
+uint_8 itab[3];
+itab[0] = 2;
+itab[1] = dobj_->SizeIndex();
+itab[2] = (dobj_->IfRING()) ? 0 : 1;
+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<uint_2>
+#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)
+namespace SOPHYA {
+template class FIO_SphereHEALPix<uint_2>;
+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_Nov2007/SophyaLib/SkyMap/fiospherehealpix.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiospherehealpix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiospherehealpix.h	(revision 3445)
@@ -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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.cc	(revision 3445)
@@ -0,0 +1,198 @@
+// G. Le Meur 04/2000
+
+#include "sopnamsp.h"
+#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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/fiospherethetaphi.h	(revision 3445)
@@ -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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/healpix.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/healpix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/healpix.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyMap/localmap.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/localmap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/localmap.cc	(revision 3445)
@@ -0,0 +1,970 @@
+#include "sopnamsp.h"
+#include "localmap.h"
+#include "smathconst.h"
+#include <complex>
+#include "fiondblock.h"
+
+#include <string.h>
+#include <iostream>
+#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_) this->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_) this->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 (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+      if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
+}
+template<class T>
+void LocalMap<T>::Share(const LocalMap<T>& a)
+{
+      recopierVariablesSimples(a);     
+      pixels_.Share(a.pixels_);
+      if (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+      if (a.mInfo_) this->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 (this->mInfo_) delete this->mInfo_;
+      this->mInfo_ = NULL;
+      if (a.mInfo_) this->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_;
+
+  // Aout07 : Correction -dy change en +dy suite message S.Plaszczynski du 12/07/07 pour XP et YP (Reza)
+  XP = XC_ - dx*snphC_ + dy*csthC_*csphC_;  // Aout07: -dy change en +dy (Rz/SP)
+  YP = YC_ + dx*csphC_ + dy*csthC_*snphC_;  // Aout07: -dy change en +dy (Rz/SP)
+  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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/SkyMap/localmap.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/localmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/localmap.h	(revision 3445)
@@ -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(this->PixVal(k));}
+inline T const& operator()(int_4 k) const {return(this->PixVal(k));}
+inline T& operator()(int_4 ix, int_4 iy) {return this->PixVal(iy*nSzX_+ix);};
+inline T const& operator()(int_4 ix, int_4 iy) const {return this->PixVal(iy*nSzX_+ix);};
+
+// Acces a un pixel 
+inline T& operator()(double theta,double phi) {return(this->PixValSph(theta,phi));};
+inline T  const& operator()(double theta,double phi) const {return(this->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);
+
+//! assign a new object Id (or DataRef Id) - useful for PPF write operations
+  inline void RenewObjId() { pixels_.RenewObjId(); }
+
+// ---------- 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); 
+    result.CloneOrShare(a); result.DivElt(b); 
+    return result; }
+
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/longlat.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/longlat.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/longlat.cc	(revision 3445)
@@ -0,0 +1,79 @@
+//   Angles/geometrie 3D
+//        B. Revenu 2000
+//        R. Ansari 2006
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#include "sopnamsp.h"
+#include "longlat.h"
+
+
+/*!
+   \class SOPHYA::LongLat
+   \ingroup SkyMap
+   \brief Coordinate transform from  (longitude,latitude) to (theta,phi)
+   All angles are specified in radians
+   
+   - longitude=phi
+   - latitude=Pi/2-theta  (latitude=0 -> equator)
+*/
+
+//! Default constructor: longitude=latitude=0 
+LongLat::LongLat()
+{
+  _lon=0.;
+  _lat=0.;
+}
+//! Constructor
+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]
+}
+
+//! Constructor form cartesian coordiantes
+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_Nov2007/SophyaLib/SkyMap/longlat.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/longlat.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/longlat.h	(revision 3445)
@@ -0,0 +1,65 @@
+//   Angles/geometrie 3D
+//        B. Revenu 2000
+//        R. Ansari 2006
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef LONGLAT_H_SEEN
+#define LONGLAT_H_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include <iostream>
+#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&);
+
+  //! Set the longitude/latitude coordinates (in radians)  
+  void Set(double longitude, double latitude);
+  //! Return the longitude value (in radians) 
+  double Longitude() const {return _lon;}
+  //! Return the phi value (in radians) 
+  double Phi() const {return _lon;}
+  //! Return the latitude value (in radians) 
+  double Latitude() const {return _lat;}
+  //! Return the theta value (in radians) 
+  double Theta() const {return pi_over_2-_lat;}
+
+  //! print the object (ascii representation) on stream os 
+  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_Nov2007/SophyaLib/SkyMap/mapoperation.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/mapoperation.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/mapoperation.cc	(revision 3445)
@@ -0,0 +1,85 @@
+// 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 "sopnamsp.h"
+#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 SOPHYA::MapOperations<r_4>;
+template class SOPHYA::MapOperations<r_8>;
+#endif
+   
Index: /tags/V_Nov2007/SophyaLib/SkyMap/mapoperation.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/mapoperation.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/mapoperation.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyMap/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/objlist.list	(revision 3445)
@@ -0,0 +1,16 @@
+fiolocalmap.o
+fiosphereecp.o
+fiospherehealpix.o
+fiospherethetaphi.o
+HEALPixUtils.o
+localmap.o
+longlat.o
+mapoperation.o
+skymapinit.o
+sphereecp.o
+spherehealpix.o
+spherepos.o
+spherethetaphi.o
+unitvector.o
+utilgeom.o
+vector3d.o
Index: /tags/V_Nov2007/SophyaLib/SkyMap/pixelmap.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/pixelmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/pixelmap.h	(revision 3445)
@@ -0,0 +1,177 @@
+// 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 "datatype.h"
+#include <iostream>
+#include <typeinfo>
+
+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)); }
+
+//! Ascii print of synthetic information about the pixelmap on stream os
+virtual void  Show(ostream& os) const;
+//! Show information on \b cout
+inline  void  Show() const { Show(cout); }
+
+                     
+//! Return a reference to the associated DVList object
+DVList& Info()
+  {
+    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>
+inline ostream& operator << (ostream& s,  const PixelMap<T> & a)
+{ a.Show(s);   return(s); }
+
+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);
+}
+
+template <class T>
+void PixelMap<T>::Show(ostream& os) const
+{
+os << "PixelMap<T>::Show() class: " << typeid(*this).name() 
+   << " T= " << DataTypeInfo<T>::getTypeName() 
+   << " TypeOfMap= " << TypeOfMap() << endl;
+double solang = 0.;
+if (NbPixels() > 0) solang = PixSolAngle(NbPixels()/2);
+ double frac = NbPixels()*solang*100/(4.*M_PI);
+if (frac > 100.) frac = 100.;
+os << " NbPixels()= " << NbPixels() << " ResolArcMin ~=" 
+   << Angle(sqrt(solang)).ToArcMin() << " SphereFrac ~= " 
+   << frac << " % of 4Pi" << endl;
+}
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/SkyMap/skymap.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/skymap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/skymap.h	(revision 3445)
@@ -0,0 +1,17 @@
+// 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 "sphereecp.h"
+#include "fiospherethetaphi.h"
+#include "fiospherehealpix.h"
+#include "fiolocalmap.h"
+#include "fiosphereecp.h"
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/skymapinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/skymapinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/skymapinit.cc	(revision 3445)
@@ -0,0 +1,126 @@
+// Classe d'initialisation du module Outils++ 
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "skymapinit.h" 
+
+#include <unistd.h>
+#include "spherethetaphi.h"
+#include "fiospherehealpix.h"
+#include "fiospherethetaphi.h"
+#include "fiolocalmap.h"
+#include "fiosphereecp.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;
+
+// Module version number - 1.6, Jul 06
+//   V=1.61 , Fev 2007: Ajout RenewObjId() pour SphereHealPix,ThetaPhi,ECP,LocalMap
+//   V=1.62 , Aou 2007: Correction ds LocalMap::PixToSphereC() 
+#define MOD_VERS   1.62
+
+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<uint_2>);  
+  DObjRegister(FIO_SphereHEALPix<uint_2>, SphereHEALPix<uint_2>);
+
+  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> >);
+
+  // ---------- Les SphereECP ---------
+
+  PPRegister(FIO_SphereECP<int_4>);
+  DObjRegister(FIO_SphereECP<int_4>, SphereECP<int_4>);
+
+  PPRegister(FIO_SphereECP<r_4>);
+  DObjRegister(FIO_SphereECP<r_4>, SphereECP<r_4>);
+
+  PPRegister(FIO_SphereECP<r_8>);
+  DObjRegister(FIO_SphereECP<r_8>, SphereECP<r_8>);
+
+  PPRegister(FIO_SphereECP< complex<r_4> >);
+  DObjRegister(FIO_SphereECP< complex<r_4> >, SphereECP< complex<r_4> >);
+
+  PPRegister(FIO_SphereECP< complex<r_8> >);
+  DObjRegister(FIO_SphereECP< complex<r_8> >, SphereECP< complex<r_8> >);
+
+  SophyaInitiator::RegisterModule("SkyMap", MOD_VERS);  // Module name and version number registration
+}
+
+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_Nov2007/SophyaLib/SkyMap/skymapinit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/skymapinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/skymapinit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyMap/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/smakefile	(revision 3445)
@@ -0,0 +1,396 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSkyMap.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)HEALPixUtils.o $(SOPHYAOBJP)fiolocalmap.o $(SOPHYAOBJP)fiosphereecp.o $(SOPHYAOBJP)fiospherehealpix.o $(SOPHYAOBJP)fiospherethetaphi.o $(SOPHYAOBJP)localmap.o $(SOPHYAOBJP)longlat.o $(SOPHYAOBJP)mapoperation.o $(SOPHYAOBJP)skymapinit.o $(SOPHYAOBJP)sphereecp.o $(SOPHYAOBJP)spherehealpix.o $(SOPHYAOBJP)spherepos.o $(SOPHYAOBJP)spherethetaphi.o $(SOPHYAOBJP)unitvector.o $(SOPHYAOBJP)utilgeom.o $(SOPHYAOBJP)vector3d.o
+	rm -f $(SOPHYALIBP)libSkyMap.a
+ 
+$(SOPHYALIBP)libSkyMap.a : $(SOPHYAOBJP)fiolocalmap.o $(SOPHYAOBJP)fiosphereecp.o $(SOPHYAOBJP)fiospherehealpix.o $(SOPHYAOBJP)fiospherethetaphi.o $(SOPHYAOBJP)HEALPixUtils.o $(SOPHYAOBJP)localmap.o $(SOPHYAOBJP)longlat.o $(SOPHYAOBJP)mapoperation.o $(SOPHYAOBJP)skymapinit.o $(SOPHYAOBJP)sphereecp.o $(SOPHYAOBJP)spherehealpix.o $(SOPHYAOBJP)spherepos.o $(SOPHYAOBJP)spherethetaphi.o $(SOPHYAOBJP)unitvector.o $(SOPHYAOBJP)utilgeom.o $(SOPHYAOBJP)vector3d.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)HEALPixUtils.o: HEALPixUtils.cc \
+  $(SOPHYAINCP)sopnamsp.h HEALPixUtils.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  HEALPixUtils.cc
+ 
+$(SOPHYAOBJP)fiolocalmap.o: fiolocalmap.cc \
+  $(SOPHYAINCP)sopnamsp.h fiolocalmap.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h localmap.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiolocalmap.cc
+ 
+$(SOPHYAOBJP)fiosphereecp.o: fiosphereecp.cc \
+  $(SOPHYAINCP)sopnamsp.h fiosphereecp.h \
+  sphereecp.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiosphereecp.cc
+ 
+$(SOPHYAOBJP)fiospherehealpix.o: fiospherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h fiospherehealpix.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h spherehealpix.h \
+  HEALPixUtils.h $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiospherehealpix.cc
+ 
+$(SOPHYAOBJP)fiospherethetaphi.o: fiospherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h fiospherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h spherethetaphi.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fiospherethetaphi.cc
+ 
+$(SOPHYAOBJP)localmap.o: localmap.cc $(SOPHYAINCP)sopnamsp.h \
+  localmap.h pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  localmap.cc
+ 
+$(SOPHYAOBJP)longlat.o: longlat.cc $(SOPHYAINCP)sopnamsp.h \
+  longlat.h $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  longlat.cc
+ 
+$(SOPHYAOBJP)mapoperation.o: mapoperation.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h mapoperation.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  mapoperation.cc
+ 
+$(SOPHYAOBJP)skymapinit.o: skymapinit.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h spherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h fiospherehealpix.h \
+  spherehealpix.h HEALPixUtils.h fiospherethetaphi.h fiolocalmap.h \
+  localmap.h fiosphereecp.h sphereecp.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapinit.cc
+ 
+$(SOPHYAOBJP)sphereecp.o: sphereecp.cc $(SOPHYAINCP)sopnamsp.h \
+  sphereecp.h sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphereecp.cc
+ 
+$(SOPHYAOBJP)spherehealpix.o: spherehealpix.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h spherehealpix.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  pixelmap.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  unitvector.h vector3d.h longlat.h utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h HEALPixUtils.h \
+  $(SOPHYAINCP)strutil.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherehealpix.cc
+ 
+$(SOPHYAOBJP)spherepos.o: spherepos.cc $(SOPHYAINCP)sopnamsp.h \
+  spherepos.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherepos.cc
+ 
+$(SOPHYAOBJP)spherethetaphi.o: spherethetaphi.cc \
+  $(SOPHYAINCP)sopnamsp.h spherethetaphi.h \
+  sphericalmap.h $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)machdefs.h pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h spherepos.h \
+  $(SOPHYAINCP)machdefs.h unitvector.h vector3d.h \
+  longlat.h utilgeom.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spherethetaphi.cc
+ 
+$(SOPHYAOBJP)unitvector.o: unitvector.cc \
+  $(SOPHYAINCP)sopnamsp.h unitvector.h vector3d.h \
+  longlat.h $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  unitvector.cc
+ 
+$(SOPHYAOBJP)utilgeom.o: utilgeom.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utilgeom.cc
+ 
+$(SOPHYAOBJP)vector3d.o: vector3d.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h vector3d.h longlat.h \
+  utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  vector3d.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.cc	(revision 3445)
@@ -0,0 +1,466 @@
+#include "sopnamsp.h"
+#include "sphereecp.h"
+#include <math.h>
+
+/*!
+  \class SOPHYA::SphereECP
+  \ingroup SkyMap
+  \brief Spherical maps in Equatorial Cylindrical Projection
+
+  Class implementing spherical maps, with a pixelisation
+  corresponding to the an Equatorial Cylindrical Projection.
+  Pixel size varie from equator to poles. The sphere is divided 
+  into a number of slices along the parallels. Each slice is subdivided
+  into the same number of pixels.
+  This class provides the possibility to have partial coverage.
+  Can be used for the following types: <br>
+  <tt> int_4 , r_4 , r_8 , complex<r_4> , complex<r_8> </tt>
+*/
+
+namespace SOPHYA {
+
+//! Default constructor
+template <class T>
+SphereECP<T>::SphereECP()
+  : _pixels()
+{
+  _partial = false;
+  _theta1 = 0.;
+  _theta2 = M_PI;
+  _phi1 = 0.;
+  _phi2 = 2*M_PI;
+  _outofmapidx = -99;
+  _outofmapnphi = 0;
+  _outofmapntet = 0;
+  _outofmappix = 0;
+  _outofmapval = 0;
+  _dtheta = 0.;
+  _dphi = 0.;
+}
+
+/*!
+  \brief  Constructor with the pixelisation parameter m
+  
+  Complete coverage.
+  The sphere is divided into \b m slices in theta (0..pi). each slice is divided
+  into \b 2m pixels (along phi) 
+*/
+template <class T>
+SphereECP<T>::SphereECP(int m)
+  : _pixels(2*m,m,0,0,0,true)
+{
+  _partial = false;
+  _theta1 = 0.;
+  _theta2 = M_PI;
+  _phi1 = 0.;
+  _phi2 = 2*M_PI;
+  _outofmapidx = -99;
+  _outofmapnphi = 0;
+  _outofmapntet = 0;
+  _outofmappix = 0;
+  _outofmapval = 0;
+  _dtheta = _dphi = M_PI/m;
+}
+
+/*! 
+  Complete coverage.
+  \b ntet slices in theta (0..pi) and \b nphi pixels (along phi) for 
+  each slice in theta
+*/
+template <class T>
+SphereECP<T>::SphereECP(int ntet, int nphi)
+  : _pixels(nphi,ntet,0,0,0,true)
+{
+  _partial = false;
+  _theta1 = 0.;
+  _theta2 = M_PI;
+  _phi1 = 0.;
+  _phi2 = 2*M_PI; 
+  _outofmapidx = -99;
+  _outofmapnphi = 0;
+  _outofmapntet = 0;
+  _outofmappix = 0;
+  _outofmapval = 0;
+  _dtheta = M_PI/ntet;
+  _dphi = 2*M_PI/nphi;
+}
+
+/*! 
+  Partial coverage : 
+  \b ntet slices in theta , in the range (tet1 .. tet2) and \b nphi pixels (along phi) for 
+  each slice in theta in the range (phi1 .. phi2) 
+*/
+template <class T>
+SphereECP<T>::SphereECP(r_8 tet1, r_8 tet2, int ntet, r_8 phi1, r_8 phi2, int nphi)
+  : _pixels(nphi,ntet,0,0,0,true)
+{
+  if( (tet1 > M_PI) || (tet1 < 0.) || (tet2 > M_PI) || (tet2 < 0.) || 
+      (phi1 < 0.) || (phi1 > 2*M_PI) || (phi1 < 0.) || (phi1 > 2*M_PI) ||
+      (tet2 <= tet1) || (phi2 <= phi1) )
+    throw  ParmError("SphereECP::SphereECP() Bad range for theta/phi limits");
+
+   _partial = true;
+  _theta1 = tet1;
+  _theta2 = tet2;
+  _phi1 = phi1;
+  _phi2 = phi2; 
+  _outofmapidx = _pixels.Size()+659;
+  // Reza, 23 sep 2004 
+  // pour des cartes partielles, et des pixels sur la sphere, mais 
+  // en dehors de la couverture, on code le numero de tranche en theta, 
+  // compte a partir de theta=0,phi=0 +  _outofmapidx
+  // theta -> idx =  _outofmapidx + theta/_dtheta*_outofmapnphi +  _outofmapntet
+  _outofmapntet = 0;
+  _outofmappix = 0;
+  _outofmapval = 0;
+  _dtheta = (_theta2-_theta1)/ntet;
+  _dphi = (_phi2-_phi1)/nphi;
+
+  _outofmapntet = M_PI/_dtheta;
+  _outofmapnphi = 2*M_PI/_dphi;
+}
+
+//! Copy constructor - shares the pixel data if \b share=true
+template <class T>
+SphereECP<T>::SphereECP(const SphereECP<T>& a, bool share)
+  : _pixels(a._pixels, share)
+{
+  _partial = a._partial;
+  _theta1 = a._theta1;
+  _theta2 = a._theta2;
+  _phi1 = a._phi1;
+  _phi2 = a._phi2;   
+  _outofmapidx = a._outofmapidx;
+  _outofmapnphi = a._outofmapnphi;
+  _outofmapntet = a._outofmapntet;
+  _outofmappix = a._outofmappix;
+  _outofmapval = a._outofmapval;
+  _dtheta = a._dtheta;
+  _dphi = a._dphi;
+}
+
+//! Copy constructor - shares the pixel data 
+template <class T>
+SphereECP<T>::SphereECP(const SphereECP<T>& a)
+  : _pixels(a._pixels)
+{
+  _partial = a._partial;
+  _theta1 = a._theta1;
+  _theta2 = a._theta2;
+  _phi1 = a._phi1;
+  _phi2 = a._phi2;   
+  _outofmapidx = a._outofmapidx;
+  _outofmapnphi = a._outofmapnphi;
+  _outofmapntet = a._outofmapntet;
+  _outofmappix = a._outofmappix;
+  _outofmapval = a._outofmapval;
+  _dtheta = a._dtheta;
+  _dphi = a._dphi;
+}
+
+template <class T>
+SphereECP<T>::~SphereECP()
+{
+}
+
+template <class T>
+string SphereECP<T>::TypeOfMap() const
+{
+  return string("ECP");
+}
+
+template <class T>
+void SphereECP<T>::SetTemp(bool temp) const
+{
+  _pixels.SetTemp(temp);
+}
+
+template <class T>
+int_4 SphereECP<T>::NbPixels() const
+{
+  return _pixels.Size();
+}
+
+template <class T>
+T& SphereECP<T>::PixVal(int_4 k)
+{
+  // On pourrait etre plus strict en demandant aussi k<_outofmapidx+_outofmapnphi*_outofmapntet (Reza 23/09/04)
+  if ((_partial) && (k>=_outofmapidx))   return _outofmappix;
+  if((k < 0) || (k >= _pixels.Size()) )  
+     throw RangeCheckError("SphereECP::PIxVal() Pixel index out of range");
+  return _pixels.DataBlock()(k);
+}
+
+template <class T>
+T const& SphereECP<T>::PixVal(int_4 k)  const
+{
+  // On pourrait etre plus strict en demandant aussi k<_outofmapidx+_outofmapnphi*_outofmapntet (Reza 23/09/04)
+  if ((_partial) && (k>=_outofmapidx))   return _outofmapval;
+  if((k < 0) || (k >= _pixels.Size()) )  
+     throw RangeCheckError("SphereECP::PIxVal() Pixel index out of range");
+  //  return _pixels.DataBlock()(k);
+  return _pixels.Data()[k];
+}
+
+template <class T>
+bool  SphereECP<T>::ContainsSph(double theta, double phi) const
+{
+  if (_partial) {
+    if ( (theta >= _theta1) && (theta <= _theta2) &&
+	 (phi >= _phi1) && (phi <= _phi2) )  return true;
+    else return false;
+  }
+  else return false;
+}
+
+template <class T>
+int_4  SphereECP<T>::PixIndexSph(double theta, double phi) const
+{
+  if((theta > M_PI) || (theta < 0.)) return(-1);
+  if((phi < 0.) || (phi > 2*M_PI)) return(-1);
+  if (_partial) {
+    if ( (theta < _theta1) || (theta > _theta2) ||
+	 (phi < _phi1) || (phi > _phi2) )  return _outofmapidx+theta/_dtheta*_outofmapnphi+phi/_dphi;
+  }
+  int_4 it = (theta-_theta1)/_dtheta;
+  int_4 jp = (phi-_phi1)/_dphi;
+  return (it*_pixels.SizeX()+jp);
+}
+
+template <class T>
+void  SphereECP<T>::PixThetaPhi(int_4 k, double& theta, double& phi) const
+{
+  if ((_partial) && (k>=_outofmapidx)) {
+    theta = (((k-_outofmapidx) / _outofmapnphi)+0.5)*_dtheta;
+    phi = (((k-_outofmapidx) % _outofmapnphi)+0.5)*_dphi;;
+    return;
+  }
+  if((k < 0) || (k >= _pixels.Size()) )  
+     throw RangeCheckError("SphereECP::PixThetaPhi() Pixel index out of range");
+
+  int_4 it = k / _pixels.SizeX();
+  int_4 jp = k % _pixels.SizeX();
+  theta = _theta1+(it+0.5)*_dtheta;
+  phi = _phi1*(jp+0.5)*_dphi;
+  return;
+}
+
+template <class T>
+T  SphereECP<T>::SetPixels(T v)
+{
+  _pixels = v;
+  return v;
+}
+
+template <class T>
+double  SphereECP<T>::PixSolAngle(int_4 k) const
+{
+  if ((_partial) && (k>=_outofmapidx)) {
+    double theta = (((k-_outofmapidx) / _outofmapnphi)+0.5)*_dtheta;
+    return (_dtheta*_dphi*sin(theta));
+  }
+  if((k < 0) || (k >= _pixels.Size()) )  
+     throw RangeCheckError("SphereECP::PixSolAngle(int_4 k) Pixel index out of range");
+
+  int_4 it = k / _pixels.SizeX();
+  double theta = _theta1+it*_dtheta;
+  return (_dtheta*_dphi*sin(theta));
+}
+
+template <class T>
+int_4  SphereECP<T>::SizeIndex() const
+{
+  return _pixels.SizeY();
+}
+
+template <class T>
+void  SphereECP<T>::Resize(int_4 m)
+{
+  if ( (m <= 0) || ( m == _pixels.SizeY()) ) { 
+    cout << " SphereECP<T>::Resize(int_4 " << m << ") m<0 ou m=NTheta - Ne fait rien " << endl;
+    return;
+  }
+  int mphi = m;
+  if (_pixels.Size() > 0)  mphi = m*_pixels.SizeX()/_pixels.SizeY();
+  cout << " SphereECP<T>::Resize(" << m 
+       << ") -> _pixels.Resize(" << mphi << "," << m << ")" << endl; 
+  sa_size_t sz[5] = {0,0,0,0,0};
+  sz[0] = mphi;  sz[1] = m;
+  _pixels.ReSize(2,sz);
+  _outofmapidx = _pixels.Size()+659;
+  _dtheta = (_theta2-_theta1)/m;
+  _dphi = (_phi2-_phi1)/mphi;
+
+  _outofmapntet = M_PI/_dtheta;
+  _outofmapnphi = 2*M_PI/_dphi;
+  return;
+}
+
+template <class T>
+uint_4  SphereECP<T>::NbThetaSlices() const
+{
+  return _pixels.SizeY();
+}
+
+template <class T>
+r_8  SphereECP<T>::ThetaOfSlice(int_4 index) const
+{
+  if( (index < 0) || (index >= _pixels.SizeY()) )  
+     throw RangeCheckError("SphereECP::ThetaOfSlice() theta index out of range");
+  return (_theta1 + (index+0.5)*_dtheta);
+ 
+}
+
+template <class T>
+void  SphereECP<T>::GetThetaSlice(int_4 index,r_8& theta, 
+				  TVector<r_8>& phi, TVector<T>& value) const 
+{
+  if( (index < 0) || (index >= _pixels.SizeY()) )  
+     throw RangeCheckError("SphereECP::GetThetaSlice() index out of range");
+
+  theta = _theta1 + (index+0.5)*_dtheta;
+  int_4 nphit = 2.*M_PI/_dphi;
+  phi.ReSize(nphit); 
+  value.ReSize(nphit); 
+  int_4 ioff = _phi1/_dphi;
+  int_4 i;
+  for(i=0; i<ioff; i++) {
+    phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
+    value(i) = _outofmapval;
+  }
+  for(i=ioff; i<ioff+_pixels.SizeX(); i++) {
+    phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
+    value(i) = _pixels(i-ioff,index,0);
+  }
+  for(i=ioff+_pixels.SizeX(); i<nphit; i++) {
+    phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
+    value(i) = _outofmapval;
+  }
+  return;
+}
+
+template <class T>
+void  SphereECP<T>::GetThetaSlice(int_4 index, r_8& theta, r_8& phi0, 
+				  TVector<int_4>& pixidx, TVector<T>& value) const
+{
+  if( (index < 0) || (index >= _pixels.SizeY()) )  
+    throw RangeCheckError("SphereECP::GetThetaSlice() index out of range");
+  
+  theta = _theta1 + (index+0.5)*_dtheta;
+  int_4 ioff = _phi1/_dphi;
+  phi0 = _phi1 - (ioff-0.5)*_dphi;
+
+  int_4 nphit = 2.*M_PI/_dphi;
+  pixidx.ReSize(nphit); 
+  value.ReSize(nphit);
+ 
+  int_4 i;
+  for(i=0; i<ioff; i++) {
+    pixidx(i) = _outofmapidx+theta/_dtheta*_outofmapnphi+phi0/_dphi+i;
+    value(i) = _outofmapval;
+  }
+  for(i=ioff; i<ioff+_pixels.SizeX(); i++) {
+    pixidx(i) = index*_pixels.SizeX()+(i-ioff);
+    value(i) = _pixels(i-ioff,index,0);
+  }
+  for(i=ioff+_pixels.SizeX(); i<nphit; i++) {
+    pixidx(i) = _outofmapidx+theta/_dtheta*_outofmapnphi+phi0/_dphi+i;
+    value(i) = _outofmapval;
+  }
+  return;
+
+}
+
+template <class T>
+T*  SphereECP<T>::GetThetaSliceDataPtr(int_4 index)
+{
+  if( (index < 0) || (index >= _pixels.SizeY()) )  
+    throw RangeCheckError("SphereECP::GetThetaSliceDataPtr() index out of range");
+  int_4 ioff = _phi1/_dphi;
+  if (ioff != 0) return NULL;
+  return _pixels.Data() + index*_pixels.SizeX();
+}
+
+template <class T>
+void  SphereECP<T>::Show(ostream& os) const
+{
+  PixelMap<T>::Show(os);
+  if (_partial)
+    os << "SphereECP<T>::Print() - Partial ECP Map NPhi=" << _pixels.SizeX() 
+       << " x NTheta= " <<  _pixels.SizeY() << " SolidAngle=" << PixSolAngle() << "\n"
+       << "ThetaLimits= " << _theta1 << " .. " << _theta2 
+       << "  PhiLimits= " << _phi1 << " .. " << _phi2 << endl;
+  else 
+    os << "SphereECP<T>::Print() - Full ECP Map NPhi=" << _pixels.SizeX() 
+       << " x NTheta= " <<  _pixels.SizeY() << " SolidAngle=" << PixSolAngle() << endl;
+}
+
+template <class T>
+void  SphereECP<T>::Print(ostream& os) const
+{
+  Show(os);
+  os << _pixels;
+}
+
+template <class T>
+SphereECP<T>&  SphereECP<T>::Set(const SphereECP<T>& a)
+{
+  _pixels.Set(a._pixels);
+  _partial = a._partial;
+  _theta1 = a._theta1;
+  _theta2 = a._theta2;
+  _phi1 = a._phi1;
+  _phi2 = a._phi2;   
+  _outofmapidx = a._outofmapidx;
+  _outofmapnphi = a._outofmapnphi;
+  _outofmapntet = a._outofmapntet;
+  _outofmappix = a._outofmappix;
+  _outofmapval = a._outofmapval;
+  _dtheta = a._dtheta;
+  _dphi = a._dphi; 
+  return *this ;
+}
+
+template <class T>
+SphereECP<T>&  SphereECP<T>::SetCst(T x)
+{
+  _pixels.SetCst(x);
+  return *this ;
+}
+
+template <class T>
+SphereECP<T>&  SphereECP<T>::AddCst(T x)
+{
+  _pixels += x;
+  return *this ;
+}
+
+template <class T>
+SphereECP<T>&  SphereECP<T>::MulCst(T x)
+{
+  _pixels *= x;
+  return *this ;
+}
+
+
+
+}// Fin du namespace
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template SphereECP<int_4>
+#pragma define_template SphereECP<r_4>
+#pragma define_template SphereECP<r_8>
+#pragma define_template SphereECP< complex<r_4> >
+#pragma define_template SphereECP< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+namespace SOPHYA {
+template class SphereECP<int_4>;
+template class SphereECP<r_4>;
+template class SphereECP<r_8>;
+template class SphereECP< complex<r_4> >;
+template class SphereECP< complex<r_8> >;
+}
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/sphereecp.h	(revision 3445)
@@ -0,0 +1,163 @@
+#ifndef SPHEREECP_SEEN
+#define SPHEREECP_SEEN
+
+#include "sphericalmap.h"
+#include "ndatablock.h"
+#include "tvector.h"
+
+
+/* Classe de carte spherique avec decoupage theta-phi 
+  (projection cylindique: Equatorial Cylindrical Projection) 
+  avec couverture posiibilite de couverture partielle,
+  limites en theta,phi
+  R. Ansari  - Septembre 2004 
+ */
+
+namespace SOPHYA {
+template <class T>
+class FIO_SphereECP;  
+
+template <class T> 
+class SphereECP : public SphericalMap<T>
+{
+public :
+
+//! return the size index value corresponding to resolution res (in radian)
+static inline int_4 ResolToSizeIndex(double res)
+  { return (int_4)((M_PI/res)+0.5); }
+//! return the pixel resolution (in radian) for the size index \b m 
+static inline double  SizeIndexToResol(int_4 m) 
+  { return  (M_PI/(double)m); }
+
+  // Constructeur par defaut
+			SphereECP();
+  // Constructeur , couverture complete, m tranches en theta (delta theta = M_PI), 2m en phi (delta phi = 2Pi)
+			SphereECP(int m);
+  // Constructeur , couverture complete, ntet tranches en theta (delta theta = M_PI), nphi en phi (delta phi = 2Pi)
+			SphereECP(int ntet, int nphi);
+  // Constructeur , couverture partielle, ntet tranches en theta , nphi en phi 
+			SphereECP(r_8 tet1, r_8 tet2, int ntet, r_8 phi1, r_8 phi2, int nphi);
+  // Constructeur de copie, share=true -> partage des pixels
+			SphereECP(const SphereECP<T>& a, bool share);
+  // Constructeur de copie, partage des pixels
+			SphereECP(const SphereECP<T>& a);
+  virtual		~SphereECP();
+
+// Renvoie TETAPHI comme les SphereThetaPhi pour le moment  
+  virtual string	TypeOfMap() const;  
+  virtual void		SetTemp(bool temp=false) const;  // A supprimer 
+
+// Informations sur carte partielle/complete + zone de couverture
+  inline  bool		IsPartial() const { return _partial; }
+  inline  double        MinTheta() const { return _theta1; }
+  inline  double        MaxTheta() const { return _theta2; }
+  inline  double        DeltaTheta() const { return _dtheta; }
+  inline  double        MinPhi() const { return _phi1; }
+  inline  double        MaxPhi() const { return _phi2; }
+  inline  double        DeltaPhi() const { return _dphi; }
+
+// Interface de Pixelmap
+/*!    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 l'angle Solide couvert par la carte   (steradians) */ 
+  virtual double TotSolAngle(void) const
+    {return fabs((_phi2-_phi1)*(cos(_theta2)-cos(_theta1)));}
+
+/* retourne/fixe la valeur du parametre de decoupage m */ 
+  virtual int_4		SizeIndex() const ;
+
+// Interface de SphericalMap 
+// index characterizing the size pixelization : m for SphereThetaPhi
+// nside for Gorski sphere...
+  virtual void		Resize(int_4 m);
+  virtual uint_4	NbThetaSlices() const;
+
+  // Nb de tranches en Phi
+  inline  uint_4	NbPhiSlices() const { return _pixels.SizeX(); }
+
+  virtual r_8           ThetaOfSlice(int_4 index) 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 T*            GetThetaSliceDataPtr(int_4 index);
+
+  // Valeur de pixel hors carte
+  inline void		SetOutOfMapValue(T v) { _outofmappix = _outofmapval = v; }
+  inline T		GetOutOfMapValue(T v) { return _outofmapval; }
+
+  // Impression 
+  virtual void          Show(ostream& os) const;
+  inline void		Show() const { Show(cout); }
+  virtual void          Print(ostream& os) const;
+  inline void		print(ostream& os) const { Print(os); }
+  inline void		Print() const { Print(cout); }
+
+  // ---- les operations =, +, - , *
+  // operation = (remplissage avec une valeur ou carte)
+  virtual SphereECP<T>& Set(const SphereECP<T>& a);
+  inline  SphereECP<T>&	operator = (const SphereECP<T>& a) { return Set(a); }
+  virtual SphereECP<T>& SetCst(T x);
+  inline  SphereECP<T>&	operator = (T x)   { return SetCst(x); }
+  // Operation + , * avec des Constantes 
+  virtual SphereECP<T>&	AddCst(T x) ;
+  virtual SphereECP<T>&	MulCst(T x) ;
+
+  inline  SphereECP<T>&  operator += (T x)            { return AddCst(x); }
+  inline  SphereECP<T>&  operator -= (T x)            { return AddCst(-x); }
+  inline  SphereECP<T>&  operator *= (T x)            { return MulCst(x); }
+
+  // Acces au tableau des pixels
+  inline TArray<T>&	GetPixelArray() { return _pixels; }
+  inline TArray<T>	GetPixelArray() const { return _pixels; }
+
+  //! assign a new object Id (or DataRef Id) - useful for PPF write operations
+  inline void RenewObjId() { _pixels.RenewObjId(); }
+
+  friend class  FIO_SphereECP<T>;   // Gestion de persistance PPF
+
+protected:
+  bool _partial;
+  r_8 _theta1,_theta2;
+  r_8 _phi1, _phi2;
+  r_8 _dtheta, _dphi;
+  TArray<T> _pixels;
+  int_4 _outofmapidx;
+  int_4 _outofmapnphi;
+  int_4 _outofmapntet;
+  T _outofmappix;
+  T _outofmapval;
+};
+
+
+}// Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/spherehealpix.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherehealpix.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherehealpix.cc	(revision 3445)
@@ -0,0 +1,686 @@
+#include "sopnamsp.h"
+#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
+  \brief Spherical maps in HEALPix pixelisation scheme.
+
+  Class implementing spherical maps, in the HEALPix pixelisation scheme, 
+  with template data types (double, float, complex, ...)
+
+
+\verbatim
+    Adapted from :
+    -----------------------------------------------------------------------
+     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-- */
+
+//! Default constructor - optional pixelisation scheme parameter
+template<class T>
+SphereHEALPix<T>::SphereHEALPix(bool fgring) : fgring_(fgring), pixels_(), 
+				    sliceBeginIndex_(), sliceLenght_()
+
+{
+  InitNul();
+}
+
+/*! \brief Constructor with specification of nside and optional pixelisation scheme
+  
+  \param <m> : "nside" of the Healpix algorithm
+  \param <fgring> : if true -> RING pixelisation (default), if not NESTED
+
+  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, bool fgring)
+
+{
+  fgring_ = fgring;
+  InitNul();
+  Pixelize(m);
+  SetThetaSlices();
+}
+//!    Copy constructor
+template<class T>
+SphereHEALPix<T>::SphereHEALPix(const SphereHEALPix<T>& s, bool share)
+  : pixels_(s.pixels_, share), sliceBeginIndex_(s.sliceBeginIndex_, share), 
+				sliceLenght_(s.sliceLenght_, share)
+//--
+{
+  nSide_= s.nSide_;
+  nPix_ = s.nPix_;
+  omeg_ = s.omeg_;
+  fgring_ = s.fgring_;
+  if(s.mInfo_) this->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_;
+  fgring_ = s.fgring_;
+  if(s.mInfo_) this->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_;
+  fgring_ = a.fgring_;
+  pixels_.CloneOrShare(a.pixels_);
+  sliceBeginIndex_.CloneOrShare(a.sliceBeginIndex_);
+  sliceLenght_.CloneOrShare(a.sliceLenght_);
+  if (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+  if (a.mInfo_) this->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_;
+  fgring_ = a.fgring_;
+  pixels_.Share(a.pixels_);
+  sliceBeginIndex_.Share(a.sliceBeginIndex_);
+  sliceLenght_.Share(a.sliceLenght_);
+  if (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+  if (a.mInfo_) this->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 (this->mInfo_) delete this->mInfo_;
+      this->mInfo_ = NULL;
+      if (a.mInfo_) this->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(a)  - Not Allocated SphereHEALPix ! ");
+  if (NbPixels() != a.NbPixels()) 
+    throw(SzMismatchError("SphereHEALPix<T>::CopyElt(a) SizeMismatch")) ;
+  nSide_= a.nSide_;
+  nPix_ = a.nPix_;
+  omeg_ = a.omeg_;
+  int k;
+  if (fgring_ == a.fgring_) 
+    for (k=0; k< nPix_; k++) pixels_(k) = a.pixels_(k);
+  else {
+    if (fgring_)  for (k=0; k< nPix_; k++) 
+      pixels_(k) = a.pixels_(ring2nest(nSide_, k));
+    else  for (k=0; k< nPix_; k++) 
+      pixels_(k) = a.pixels_(nest2ring(nSide_, 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);
+}
+
+template<class T>
+SphereHEALPix<T>::~SphereHEALPix()
+{
+}
+
+/*!  \fn   void SOPHYA::SphereHEALPix::Resize(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>
+void SphereHEALPix<T>::Resize(int_4 m)
+{
+  if ((m <= 0 && nSide_ > 0))  {
+    cout << "SphereHEALPix<T>::Resize(m) with m<=0, NOT resized" << endl;
+    return;
+  }
+  InitNul();
+  Pixelize(m);
+  SetThetaSlices();
+}
+
+
+//! return type of the map pixelisation : RING or NESTED
+template<class T>
+string SphereHEALPix<T>::TypeOfMap() const 
+{
+  if (fgring_)  return string("RING");
+  else return string("NESTED");
+}
+
+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)
+{
+  if (m<=0 || m> 8192) {
+    cout << "SphereHEALPix<T>::Pixelize() m=" << m <<" out of range [0,8192]" << endl;
+    throw ParmError("SphereHEALPix<T>::Pixelize() m out of range");
+  }
+  // verifier que m est une puissance de deux 
+  int x= m;
+  while (x%2==0) x/=2;
+  if(x != 1) {  
+    cout << "SphereHEALPix<T>::Pixelize() m=" << m << " != 2^n " << endl;
+    throw ParmError("SphereHEALPix<T>::Pixelize() m!=2^n");
+  }
+
+  // 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;
+}
+
+//! Return the theta angle for slice defined by \b index
+template<class T>
+r_8 SphereHEALPix<T>::ThetaOfSlice(int_4 index) const
+{
+  uint_4 nbslices = uint_4(4*nSide_-1);
+  if (index<0 || index >= nbslices) 
+    throw RangeCheckError(" SphereHEALPix::ThetaOfSlice()  index out of range");
+  r_8 theta, phi0;
+  PixThetaPhi(sliceBeginIndex_(index), theta, phi0);
+  return theta;
+}
+
+//! Return true : All theta slices have a symmetric slice at Pi-Theta in SphereHEALPix
+template <class T>
+bool SphereHEALPix<T>::HasSymThetaSlice() const 
+{
+  return true;
+}
+//! Return the slice index for the symmetric slice at theta=Pi-ThetaOfSlice(idx) 
+template <class T>
+int_4 SphereHEALPix<T>::GetSymThetaSliceIndex(int_4 idx) const
+{
+  if(idx < 0 || idx >= NbThetaSlices()) 
+    throw RangeCheckError("SphereHEALPix::GetSymThetaSliceIndex index out of range"); 
+  return (NbThetaSlices()-1-idx);
+}
+
+/*!  \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()) 
+    throw RangeCheckError(" SphereHEALPix::GetThetaSlice()  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.;
+  if (fgring_) {  // RING pixelisation scheme
+    for(int_4 kk = 0; kk < lring;kk++)  {
+      PixThetaPhi(kk+iring,TH,FI);
+      phi(kk)= FI;
+      value(kk)= pixels_(kk+iring);
+    }
+    PixThetaPhi(iring, theta, FI);
+  }
+  else {  // NESTED pixelisation scheme
+    for(int_4 kk = 0; kk < lring;kk++)  {
+      int kkn = ring2nest(nSide_, kk+iring);
+      PixThetaPhi(kkn,TH,FI);
+      phi(kk)= FI;
+      value(kk)= pixels_(kkn);
+    }
+    PixThetaPhi(ring2nest(nSide_,iring), theta, FI);    
+  }
+  //  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()) 
+    throw RangeCheckError(" SphereHEALPix::GetThetaSlice() index out of range");
+  int_4 iring= sliceBeginIndex_(sliceIndex);
+  int_4 lring  =  sliceLenght_(sliceIndex);
+  pixelIndices.ReSize(lring);
+  value.ReSize(lring);
+
+  if (fgring_) {  // RING pixelisation scheme
+    for(int_4 kk = 0; kk < lring;kk++)  {
+      pixelIndices(kk)= kk+iring;
+      value(kk)= pixels_(kk+iring);
+    }
+    PixThetaPhi(iring, theta, phi0);
+  }
+  else {  // NESTED pixelisation scheme
+    for(int_4 kk = 0; kk < lring;kk++)  {
+      int_4 kkn = ring2nest(nSide_, kk+iring);
+      pixelIndices(kk)= kkn;
+      value(kk)= pixels_(kkn);
+    }
+    PixThetaPhi(ring2nest(nSide_,iring), theta, phi0);    
+  }
+}
+
+//! return a pointer to the specified slice pixel data in RING ordering, NULL in NESTED
+template<class T>
+T* SphereHEALPix<T>::GetThetaSliceDataPtr(int_4 sliceIndex) 
+
+{
+  if (sliceIndex<0 || sliceIndex >= NbThetaSlices()) 
+    throw RangeCheckError(" SphereHEALPix::GetThetaSliceDataPtr(): index out of range");
+  if (fgring_) 
+    return pixels_.Begin()+sliceBeginIndex_(sliceIndex);
+  else return NULL;
+}
+
+template<class T>
+void SphereHEALPix<T>::SetThetaSlices()  
+{
+  sliceBeginIndex_.ReSize(4*nSide_-1);
+  sliceLenght_.ReSize(4*nSide_-1);
+  int_4 sliceIndex;
+  int_4 offp = 0;
+  for (sliceIndex=0; sliceIndex<  nSide_-1; sliceIndex++)  {
+    //      sliceBeginIndex_(sliceIndex)  = 2*sliceIndex*(sliceIndex+1);      
+    sliceBeginIndex_(sliceIndex)  = offp;
+    sliceLenght_(sliceIndex) = 4*(sliceIndex+1);
+    offp += sliceLenght_(sliceIndex);
+  }
+  for (sliceIndex= nSide_-1; sliceIndex<  3*nSide_; sliceIndex++)  {
+    //      sliceBeginIndex_(sliceIndex)  = 2*nSide_*(2*sliceIndex-nSide_+1);
+    sliceBeginIndex_(sliceIndex)  = offp;
+    sliceLenght_(sliceIndex) = 4*nSide_;
+    offp += sliceLenght_(sliceIndex);
+  }
+  for (sliceIndex= 3*nSide_; sliceIndex< 4*nSide_-1; sliceIndex++) {
+    int_4 nc= 4*nSide_-1-sliceIndex;
+      //      sliceBeginIndex_(sliceIndex)  = nPix_-2*nc*(nc+1); 
+    sliceBeginIndex_(sliceIndex)  = offp; 
+    sliceLenght_(sliceIndex) = 4*nc;
+    offp += sliceLenght_(sliceIndex);    
+  }
+}
+
+
+
+//!   \return value of the \b k th pixel 
+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);
+}
+
+//!   \return value of the \b k th pixel 
+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 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
+
+{
+  if (fgring_) return ang2pix_ring(nSide_,theta,phi);
+  else return ang2pix_nest(nSide_,theta,phi);
+}
+
+
+//!  \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
+{
+  if (fgring_) pix2ang_ring(nSide_,k,theta,phi);
+  else pix2ang_nest(nSide_,k,theta,phi);
+}
+
+//! Set all pixels to value v 
+template <class T>
+T SphereHEALPix<T>::SetPixels(T v)
+{
+pixels_.Reset(v);
+return(v);
+}
+
+
+
+//!  Conversion from NESTED index  into RING index 
+template<class T>
+int_4 SphereHEALPix<T>::NestToRing(int_4 k) const
+{
+  return  nest2ring(nSide_,k);
+}
+
+//!  Conversion 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(a) SizeMismatch")) ;
+  if (fgring_ != a.fgring_) 
+    throw(ParmError("SphereHEALPix<T>::AddElt(a) different pixelisation RING<>NESTED")) ;
+
+  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(a) SizeMismatch")) ;
+  if (fgring_ != a.fgring_) 
+    throw(ParmError("SphereHEALPix<T>::SubElt(a) different pixelisation RING<>NESTED")) ;
+
+  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(a) SizeMismatch")) ;
+  if (fgring_ != a.fgring_) 
+    throw(ParmError("SphereHEALPix<T>::MulElt(a) different pixelisation RING<>NESTED")) ;
+
+  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(a) SizeMismatch")) ;
+  if (fgring_ != a.fgring_) 
+    throw(ParmError("SphereHEALPix<T>::DivElt(a) different pixelisation RING<>NESTED")) ;
+  pixels_ /= a.pixels_;
+  return (*this);
+}
+
+
+
+
+template <class T>
+void SphereHEALPix<T>::print(ostream& os) const
+{
+  this->Show(os);
+  os << "SphereHEALPix<T>(" << TypeOfMap() << ") NSide= " 
+     << nSide_ << " nPix_   = " << nPix_  << " omeg_ = " << omeg_   << endl;
+
+  if(this->mInfo_) os << "  DVList Info= " << *(this->mInfo_) << endl;
+  os << "... Pixel values : ";
+  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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/SkyMap/spherehealpix.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherehealpix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherehealpix.h	(revision 3445)
@@ -0,0 +1,310 @@
+#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); }
+
+  //! return the size index (=nside) corresponding to resolution res (in radian)
+  static inline int_4 ResolToSizeIndex(double res)
+         { return  HEALPix::ResolToSizeIndex(res); }
+
+  //! return the size index (=nside) corresponding to resolution res (in radian)
+  static inline int_4 ResolToNSide(double res)
+         { return  HEALPix::ResolToSizeIndex(res); }
+  //! return the pixel resolution (in radian) for the size index (=nside) m 
+  static inline double  SizeIndexToResol(int_4 m) 
+  { return  HEALPix::SizeIndexToResol(m); }
+  //! return the pixel resolution (in radian) for the size index (=nside) m 
+  static inline double  NSideToResol(int_4 m) 
+  { return  HEALPix::SizeIndexToResol(m); }
+
+SphereHEALPix(bool fgring=true);
+SphereHEALPix(int_4 m, bool fgring=true);
+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;
+
+virtual uint_4 NbThetaSlices() const;
+virtual r_8  ThetaOfSlice(int_4 index) const;
+virtual bool  HasSymThetaSlice() const;
+virtual int_4 GetSymThetaSliceIndex(int_4 idx) 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 T*   GetThetaSliceDataPtr(int_4 sliceIndex);
+
+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);
+
+/*! \brief 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);
+virtual string TypeOfMap() const;
+
+inline bool IfRING() const { return fgring_; } 
+inline bool IfNESTED() const { return ( (fgring_) ? false : true ); } 
+
+
+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;
+inline void Print(ostream& os) const { print(os); }
+
+//--------------------- 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);
+
+//! assign a new object Id (or DataRef Id) - useful for PPF write operations
+// Reza 02/2007 : Est-il suffisant de faire l'operation sur pixels_ ?
+  inline void RenewObjId() { pixels_.RenewObjId(); }
+
+ // 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, 
+			  bool fgring) 
+{
+  nSide_= nside;
+  nPix_= nbpixels;
+  omeg_= solangle;
+  fgring_ = fgring;
+}
+
+// ------------- variables internes -----------------------
+
+int_4 nSide_;
+int_4 nPix_;
+double omeg_;
+bool fgring_;  // true -> RING pixelisation , false -> NESTED
+
+NDataBlock<T> pixels_;
+NDataBlock<int_4> sliceBeginIndex_;    // Indices in RING scheme
+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); 
+    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); 
+    result.CloneOrShare(a); result.DivElt(b); 
+    return result; }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/spherepos.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherepos.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherepos.cc	(revision 3445)
@@ -0,0 +1,169 @@
+// Classes SphereCoordSys , SpherePosition
+//      G. Le Meur  2000
+//      R. Ansari 2006 (documentation/commentaire) 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+// 04/01/00 : implantation de la persistance par classe deleguee - Guy Le Meur
+
+#include "sopnamsp.h"
+#include "spherepos.h"
+#include "datatype.h"
+#include <typeinfo>
+
+static char *head_spherepos_cc_ = "$Header: /Users/garnier/temp/CVSSophya/SophyaLib/SkyMap/spherepos.cc,v 1.4 2006-06-20 16:01:48 ansari Exp $";
+
+
+//................. SphereCoordSys class .................
+
+/*!
+   \class SOPHYA::SphereCoordSys
+   \ingroup SkyMap
+   \brief  Class which describes the coordinate system used in spherical maps
+   Current implementation (~ 2006 ) does NOT perform any coordinate transformation
+   \sa SOPHYA::PixelMap
+*/
+
+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 .................
+/*!
+   \class SOPHYA::SpherePosition
+   \ingroup SkyMap
+   \brief  Class to define a (angular) position on a sphere, combined a coordinate system
+   Current implementation (~ 2006 ) does NOT perform any coordinate transformation
+   \sa SOPHYA::PixelMap
+*/
+
+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_Nov2007/SophyaLib/SkyMap/spherepos.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherepos.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherepos.h	(revision 3445)
@@ -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.2 2006-06-20 16:01:48 ansari Exp $";
+
+namespace SOPHYA {
+
+ 
+class SphereCoordSys : public  AnyDataObj {
+public:
+  
+  enum SphereCoordSysIds { NEUTRAL =0, 
+                           ROTATION =1,
+                           OTHER = 0xFFFF
+  };
+
+  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_Nov2007/SophyaLib/SkyMap/spherethetaphi.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherethetaphi.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherethetaphi.cc	(revision 3445)
@@ -0,0 +1,856 @@
+#include "sopnamsp.h"
+#include "spherethetaphi.h"
+#include "smathconst.h"
+#include <complex>
+#include "fiondblock.h"
+#include <iostream>
+
+
+/*!
+  \class SOPHYA::SphereThetaPhi
+  \ingroup SkyMap
+
+  \brief Spherical map with equal latitude (iso-theta) rings 
+
+
+  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-- */
+
+/*!  
+  \brief Constructor with specification of number of slices (in a hemisphere)
+  \param m is the number of slices in theta on an hemisphere (the polar cap
+  forms the first slice).
+*/
+template <class T>
+SphereThetaPhi<T>::SphereThetaPhi(int_4 m)
+{
+  InitNul();
+  Pixelize(m);
+}
+
+//! Copy constructor (shares the pixel data if share==true) 
+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_) this->mInfo_= new DVList(*s.mInfo_);
+}
+
+//! Copy constructor (shares the pixel data)
+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_) this->mInfo_= new DVList(*s.mInfo_);
+}
+
+//++
+// Titre	Destructor
+//--
+//++
+template <class T>
+SphereThetaPhi<T>::~SphereThetaPhi()
+
+//--
+{}
+
+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$
+}
+
+
+//!   re-pixelize the sphere if (m > 0) 
+template <class T>
+void SphereThetaPhi<T>::Resize(int_4 m)
+{
+  if ((m <= 0) && (NTheta_ > 0) ) {
+    cout << "SphereThetaPhi<T>::Resize(m) with m<=0 - NOT resized" << endl;
+    return;
+  }
+  InitNul();
+  Pixelize(m);
+}
+
+//! Clone or share the SphereThetaPhi object \b a
+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 (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+  if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
+}
+//! Share the pixel data with object \b a
+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 (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
+  if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
+}
+
+////////////////////////// methodes de copie/share
+//! Perform data copy or shares the data 
+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 (this->mInfo_) delete this->mInfo_;
+      this->mInfo_ = NULL;
+      if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
+    }
+  return(*this);
+}
+
+//! Perform data copy or shares the data 
+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_4 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-- */
+//!    Return total number of pixels 
+template <class T>
+int_4 SphereThetaPhi<T>::NbPixels() const
+{
+  return(NPix_);
+}
+
+/* --Methode-- */
+//!    Return value of pixel with index k
+template <class T>
+T& SphereThetaPhi<T>::PixVal(int_4 k)
+{
+  if((k < 0) || (k >= NPix_)) 
+    {
+      throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
+    }
+  return pixels_(k);
+}
+
+//!    Return value of pixel with index k
+template <class T>
+T const& SphereThetaPhi<T>::PixVal(int_4 k) const
+{
+  if((k < 0) || (k >= NPix_)) 
+    {
+       throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
+    } 
+  return *(pixels_.Data()+k);
+}
+
+/* --Methode-- */
+//! Return true if teta,phi in map  
+template <class T>
+bool SphereThetaPhi<T>::ContainsSph(double /*theta*/, double /*phi*/) const
+{
+  return(true);
+}
+
+/* --Methode-- */
+//!    Return index of the pixel corresponding to direction (theta, phi).
+template <class T>
+int_4 SphereThetaPhi<T>::PixIndexSph(double theta, double phi) const
+{
+  double dphi;
+  int_4 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-- */
+//!   Return (theta,phi) coordinates of middle of  pixel with  index k
+template <class T>
+void SphereThetaPhi<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
+{
+  int_4 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;
+}
+
+//! Setting pixel values to a constant 
+template <class T>
+T SphereThetaPhi<T>::SetPixels(T v)
+{
+pixels_.Reset(v);
+return(v);
+}
+
+/*!
+  \brief 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.
+*/
+template <class T>
+double SphereThetaPhi<T>::PixSolAngle(int_4 /*dummy*/) const
+
+{
+  return Omega_;
+}
+
+/* --Methode-- */
+//!   Return values of theta,phi which limit the pixel with  index k
+template <class T>
+void SphereThetaPhi<T>::Limits(int_4 k,double& tetMin,double& tetMax,double& phiMin,double& phiMax) 
+  {
+  int_4 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_4 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-- */
+//!    Return number of theta-slices on the sphere
+template <class T>
+uint_4 SphereThetaPhi<T>::NbThetaSlices() const
+{
+  if (NTheta_<=0) 
+    {
+      throw PException(" sphere not pixelized, NbSlice=0 ");
+    }
+  return( 2*NTheta_);
+}
+
+/* --Methode-- */
+//!    Return number of pixels along the phi-direction of the kt-th slice
+template <class T>
+int_4 SphereThetaPhi<T>::NPhi(int_4 kt) const
+{
+  int_4 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-- */
+//!    Return  theta values which limit the slice kt
+template <class T>
+void SphereThetaPhi<T>::Theta(int_4 kt,double& tetMin,double& tetMax) const 
+{
+  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-- */
+//!   Return values of phi which limit the jp-th pixel of the kt-th slice
+template <class T>
+void SphereThetaPhi<T>::Phi(int_4 kt,int_4 jp,double& phiMin,double& phiMax) const 
+{
+  // 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-- */
+//!    Return pixel index  with sequence index jp in the slice kt 
+template <class T>
+int_4 SphereThetaPhi<T>::Index(int_4 kt,int_4 jp) const
+{
+  int_4 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-- */
+//!    Return indices kt (theta) and jp (phi) of  pixel with index k
+template <class T>
+void SphereThetaPhi<T>::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp) 
+{
+  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_4 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);  
+}
+/*!
+  \brief 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).
+*/
+template <class T>
+void  SphereThetaPhi<T>::Pixelize(int_4 m) 
+
+//--
+{
+  int_4 ntotpix,j;
+  
+  // Decodage et controle des arguments d'appel :
+  // au moins 2 et au plus 524288 bandes d'un hemisphere en theta
+  if (m < 2) m = 2;
+  if (m > 524288) m = 524288;
+  
+  // 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);
+    }
+}
+
+//! Return the theta angle for slice defined by \b index
+template <class T>
+r_8 SphereThetaPhi<T>::ThetaOfSlice(int_4 index) const
+{
+  if(index < 0 || index >= 2*NTheta_) 
+    throw RangeCheckError("SphereThetaPhi::ThetaOfSlice() index out of range"); 
+  double tet1, tet2;
+  Theta(index, tet1, tet2); 
+  return 0.5*(tet1+tet2);  
+}
+
+//! Return true : All theta slices have a symmetric slice at Pi-Theta in SphereThetaPhi
+template <class T>
+bool SphereThetaPhi<T>::HasSymThetaSlice() const 
+{
+  return true;
+}
+//! Return the slice index for the symmetric slice at theta=Pi-ThetaOfSlice(idx) 
+template <class T>
+int_4 SphereThetaPhi<T>::GetSymThetaSliceIndex(int_4 idx) const
+{
+  if(idx < 0 || idx >= NbThetaSlices()) 
+    throw RangeCheckError("SphereThetaPhi::GetSymThetaSliceIndex index out of range"); 
+  return (NbThetaSlices()-1-idx);
+}
+
+/*!    
+  \brief return a Theta slice information
+  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 SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, TVector<r_8>& phi, TVector<T>& value) const 
+
+{
+
+  if(index < 0 || index >= NbThetaSlices()) 
+    throw RangeCheckError("SphereThetaPhi::GetThetaSlice(idx...) index out of range"); 
+    
+
+  int_4 iring= Index(index,0);
+  int_4 lring  = NPhi(index);
+
+  phi.ReSize(lring);
+  value.ReSize(lring);
+  double Te= 0.;
+  double Fi= 0.;
+  PixThetaPhi(iring,Te,Fi);
+  double DFi = DeuxPi/(double)NPhi(index);
+  for(int_4 kk = 0; kk < lring; kk++)   {
+    value(kk)= pixels_(kk+iring);
+    phi(kk)= Fi;
+    Fi += DFi;
+  }
+  theta= Te;
+}
+
+/*
+  \brief return information on a theta slice 
+  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 
+*/
+template <class T>
+void SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, r_8& phi0,TVector<int_4>& pixelIndices, TVector<T>& value) const 
+
+{
+
+  if(index < 0 || index >= NbThetaSlices()) 
+    throw RangeCheckError("SphereThetaPhi::GetThetaSlice(idx...)  idx out of range"); 
+
+  int_4 iring= Index(index,0);
+  int_4 lring  = NPhi(index);
+
+  pixelIndices.ReSize(lring);
+  value.ReSize(lring);
+  double Te= 0.;
+  double Fi= 0.;
+  for(int_4 kk = 0; kk < lring; kk++)  {
+    pixelIndices(kk)=kk+iring ;
+    value(kk)= pixels_(kk+iring);
+  }
+  PixThetaPhi(iring,theta,phi0);
+}
+
+//! return a pointer to the specified slice pixel data
+template <class T>
+T* SphereThetaPhi<T>::GetThetaSliceDataPtr(int_4 index)
+{
+  if(index < 0 || index >= NbThetaSlices()) 
+    throw RangeCheckError("SphereThetaPhi::GetThetaSliceDataPtr(idx)  idx out of range"); 
+  return pixels_.Begin()+Index(index,0);
+}
+
+
+template <class T>
+void SphereThetaPhi<T>::print(ostream& os) const
+{
+  this->Show(os);
+  os << "SphereThetaPhi<T> NTheta_= " << NTheta_ << " NPix_    = " << NPix_ 
+     << " Omega_  =  " << Omega_   << endl;
+  if(this->mInfo_) os << "  DVList Info= " << *(this->mInfo_) << endl;
+
+  os << "... NPhi_ Values : ";
+  int_4 i;
+  for(i=0; i < NTheta_; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << NPhi_(i) <<", ";
+    }
+  os << endl;
+
+  os << "... Theta_ Values : ";
+  for(i=0; i < NTheta_+1; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << Theta_(i) <<", ";
+    }
+  os << endl;
+
+  os << "... TNphi_ Values : ";
+  for(i=0; i < NTheta_+1; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << TNphi_(i) <<", ";
+    }
+  os << endl;
+
+  os << "... Pixel Values : ";
+  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)
+namespace SOPHYA {
+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_Nov2007/SophyaLib/SkyMap/spherethetaphi.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/spherethetaphi.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/spherethetaphi.h	(revision 3445)
@@ -0,0 +1,319 @@
+#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 *****************************
+template <class T>
+class SphereThetaPhi : public SphericalMap<T>
+{
+
+public :
+
+//! return the size index value corresponding to resolution \b res (in radian)
+static inline int_4 ResolToSizeIndex(double res)
+  { return (int_4)((M_PI/2./res)+0.5); }
+//! return the pixel resolution (in radian) for the size index \b m 
+static inline double  SizeIndexToResol(int_4 m) 
+  { return (M_PI/(2.*(double)m)); }
+
+SphereThetaPhi();
+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 */ 
+virtual int_4 NbPixels() const;
+
+/* retourne la valeur du pixel d'indice 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 */ 
+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) */ 
+virtual double PixSolAngle(int_4 dummy=0) const;
+ 
+/* retourne/fixe la valeur du parametre de decoupage m */ 
+//! Return the pixelisation parameter (number of slices in a hemisphere)
+inline virtual int_4 SizeIndex() const { return( NTheta_); }
+
+/*  Acces to the DataBlock  */
+//! Acces to the pixel data NDataBlock<T> object
+inline       NDataBlock<T>& DataBlock()       {return pixels_;}
+//! Acces to the pixel data NDataBlock<T> object (const version)
+inline const NDataBlock<T>& DataBlock() const {return pixels_;}
+
+// ------------- Specific methods  ----------------------
+
+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  */ 
+void Theta(int_4 kt, double& t1, double& t2) const;
+
+/* Renvoie dans p1,p2 les valeurs phimin et phimax du pixel d'indice jp  */
+/* dans la tranche d'indice kt  */ 
+void Phi(int_4 kt, int_4 jp, double& p1, double& p2) const;
+
+/* 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  */ 
+void ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp);
+
+void Pixelize(int_4); 
+
+virtual r_8  ThetaOfSlice(int_4 index) const;
+virtual int_4 GetSymThetaSliceIndex(int_4 idx) const;
+virtual bool  HasSymThetaSlice() const;
+
+virtual void GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const; 
+virtual void GetThetaSlice(int_4 index, r_8& theta, r_8& phi0,TVector<int_4>& pixelIndices, TVector<T>& value) const ;
+virtual T*   GetThetaSliceDataPtr(int_4 sliceIndex);
+
+
+//! ASCII dump (print) of the pixel map on stream \b os
+void print(ostream& os) const;
+//! ASCII dump (print) of the pixel map 
+inline void Print(ostream& os) const { print(os); }
+//! ASCII dump (print) of the pixel map on cout
+inline void Print() const { print(cout); }
+
+
+
+// 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);
+
+//! assign a new object Id (or DataRef Id) - useful for PPF write operations
+// Reza 02/2007 : Est-il suffisant de faire l'operation sur pixels_ ?
+  inline void RenewObjId() { pixels_.RenewObjId(); }
+
+
+ // 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); 
+    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); 
+    result.CloneOrShare(a); result.DivElt(b); 
+    return result; }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyMap/sphericalmap.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/sphericalmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/sphericalmap.h	(revision 3445)
@@ -0,0 +1,80 @@
+#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(this->PixVal(k));}
+inline T  const& operator()(int k) const {return(this->PixVal(k));}
+inline T& operator()(double theta,double phi) {return(this->PixValSph(theta,phi));};
+inline T  const& operator()(double theta,double phi) const {return(this->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 r_8  ThetaOfSlice(int_4 index) const=0;
+/*!
+  Return true if some theta slices have a symmetric counter-part at (Pi-Theta)
+  (the default implementation return true) 
+*/
+virtual bool  HasSymThetaSlice() const { return false; }
+/*! 
+  Return the slice index for the symmetric slice theta=Pi-ThetaOfSlice(idx) 
+  an invalid index is returned if the symmetric slice does not exist
+*/
+virtual int_4 GetSymThetaSliceIndex(int_4 idx) const { return -1; }
+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 ;
+/*!
+  If possible return a pointer to the slice pixel data. return NULL otherwise 
+*/
+virtual T*   GetThetaSliceDataPtr(int_4 sliceIndex) { return NULL; }
+};
+
+
+} // Fin du namespace
+
+
+
+
+#endif
+
+
+
+
+
+
Index: /tags/V_Nov2007/SophyaLib/SkyMap/unitvector.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/unitvector.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/unitvector.cc	(revision 3445)
@@ -0,0 +1,88 @@
+//   3-D Geometry 
+//        B. Revenu, G. Le Meur   2000
+//        R. Ansari (documentation 2006)
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#include <math.h>
+#include "sopnamsp.h"
+#include "unitvector.h"
+
+/*!
+   \class SOPHYA::UnitVector
+   \ingroup SkyMap
+   \brief Specialisation of Vector3d class for representing unit (length=1) 3-vectors. 
+*/
+
+//! Default constructor : unit vector in the x direction
+UnitVector::UnitVector() : Vector3d(1.,0.,0.) 
+{
+}
+
+//! Constructor: Unit vector along the x,y,z cartesian coordinates
+UnitVector::UnitVector(double x, double y, double z) : Vector3d(x,y,z) 
+{
+  this->Normalize();
+}
+
+//! Constructor: Unit vector along the theta,phi direction (spherical coordinates)
+UnitVector::UnitVector(double theta, double phi) : Vector3d(theta,phi) 
+{
+  this->Normalize();
+}
+//! copy constructor
+UnitVector::UnitVector(const Vector3d& v) : Vector3d(v) 
+{
+  this->Normalize();
+}
+//! print the vector on stream os
+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_Nov2007/SophyaLib/SkyMap/unitvector.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/unitvector.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/unitvector.h	(revision 3445)
@@ -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>
+#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_Nov2007/SophyaLib/SkyMap/utilgeom.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/utilgeom.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/utilgeom.cc	(revision 3445)
@@ -0,0 +1,127 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <math.h>
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyMap/utilgeom.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/utilgeom.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/utilgeom.h	(revision 3445)
@@ -0,0 +1,19 @@
+#ifndef UTILGEOM_H_SEEN
+#define UTILGEOM_H_SEEN
+#include <math.h>
+#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_Nov2007/SophyaLib/SkyMap/vector3d.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/vector3d.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/vector3d.cc	(revision 3445)
@@ -0,0 +1,450 @@
+// Classes Angle Vector3d
+//      B. Revenu , G. Le Meur  2000
+//      R. Ansari 2006
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <math.h>
+#include "pexceptions.h"
+#include "vector3d.h"
+#include "utilgeom.h"
+
+// Class de conversion d'angles R. Ansari , Juin 2006 
+double Angle::_deg2rad = M_PI/180.;
+double Angle::_rad2deg = 180./M_PI;
+double Angle::_rad2min = 180./M_PI*60.;
+double Angle::_rad2sec = 180./M_PI*3600.;
+
+/*!
+   \class SOPHYA::Angle
+   \ingroup SkyMap
+   \brief  Class to ease angle conversions (radian <> degree <> arcmin <> arcsec).
+   The angle value is kept in radians internally.
+   \code
+   // Example to convert 0.035 radians to arcsec
+   double vr = 0.035;
+   cout << "Angle rad= " << vr << " ->arcsec= " << Angle(vr).ToArcSec() << endl;
+   // Example to convert 2.3 arcmin to radian - we use the conversion operator
+   double vam = 2.3;
+   cout << "Angle arcmin= " << vam << " ->rad= " 
+        << (double)Angle(vam, Angle::ArcMin) << endl;
+   \endcode
+
+*/
+
+Angle::Angle(double val, Angle::AngleUnit un)
+{
+  switch (un) {
+  case Angle::Radian :
+    _angrad = val;
+    break;
+  case Angle::Degree :
+    _angrad = val*_deg2rad;
+    break;
+  case Angle::ArcMin :
+    _angrad = val/_rad2min;
+    break;
+  case Angle::ArcSec :
+    _angrad = val/_rad2sec;
+    break;
+  default:
+    _angrad = val;
+    break;
+  }
+}
+
+//   3-D Geometry 
+//        B. Revenu, G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+/*!
+   \class SOPHYA::Vector3d
+   \ingroup SkyMap
+   \brief 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
+*/
+
+//! default constructor - unit vector along x direction
+Vector3d::Vector3d()
+{
+  Setxyz(1.,0.,0.);
+}
+
+//! Constructor with specification of cartesian coordinates
+Vector3d::Vector3d(double x, double y, double z) 
+{
+  _x=x;
+  _y=y;
+  _z=z;
+  xyz2ThetaPhi();
+}
+//! Constructor: unit vector with direction (spherical coordinates) specification 
+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();
+}
+
+//! Constructor: unit vector with longitude-latitude specification 
+Vector3d::Vector3d(const LongLat& ll)
+{
+  _theta=ll.Theta(); // dans [0;pi]
+  _phi=ll.Phi(); // dans [0;2pi]
+  ThetaPhi2xyz();
+}
+
+//! Copy constructor
+Vector3d::Vector3d(const Vector3d& v) 
+{
+  _x=v._x;
+  _y=v._y;
+  _z=v._z;
+  _theta=v._theta;
+  _phi=v._phi;
+}
+
+//! Set/changes the vector direction (result is a unit vector)
+void Vector3d::SetThetaPhi(double theta, double phi) 
+{
+  _theta=mod(theta,M_PI);
+  _phi=mod(phi,pi2);
+  ThetaPhi2xyz();
+}
+
+//! Set/changes the vector specifying cartesian coordinates
+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.;
+    }
+}
+//! Normalize the vector (-> unit length) for non zero vectors
+Vector3d& Vector3d::Normalize() 
+{
+  double norm=this->Norm();
+  if( norm != 0. )  (*this)/=norm;
+  //DEL  else cerr << "Division par zero" << endl;
+  return *this;
+} 
+
+//! Return the vector norm (length)
+double Vector3d::Norm() const 
+{
+  return sqrt(_x*_x+_y*_y+_z*_z);
+}
+
+//! Return the scalar (dot) product of the two vectors
+double Vector3d::Psc(const Vector3d& v) const 
+{
+  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_Nov2007/SophyaLib/SkyMap/vector3d.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyMap/vector3d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyMap/vector3d.h	(revision 3445)
@@ -0,0 +1,179 @@
+//   3-D Geometry 
+//        B. Revenu, G. Le Meur   2000
+//        R. Ansari 2006
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef VECTOR3D_H_SEEN
+#define VECTOR3D_H_SEEN
+
+#include <math.h>
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "longlat.h"
+
+
+namespace SOPHYA { 
+
+//! Class to ease angle conversions (radian <> degree <> arcmin <> arcsec)
+class Angle {
+public:
+  enum AngleUnit { Radian, Degree, ArcMin, ArcSec };
+  //! Constructor with specification of angle value in radian 
+  Angle(double val=0.) { _angrad = val; }
+  //! Constructor with specification of angle value and unit
+  Angle(double val, Angle::AngleUnit un);
+  //! Copy constructor
+  Angle(Angle const& a) { _angrad = a._angrad; }
+
+  //! Conversion to radian
+  inline double ToRadian() const { return _angrad; }
+  //! Conversion to degree
+  inline double ToDegree() const { return _angrad*_rad2deg; }
+  //! Conversion to arcmin
+  inline double ToArcMin() const { return _angrad*_rad2min; }
+  //! Conversion to arcsec
+  inline double ToArcSec() const { return _angrad*_rad2sec; }
+
+  //! return the angle value in radian
+  inline operator double () const { return _angrad; }
+
+protected:  
+  double _angrad;  // angle in radians 
+
+  static double _deg2rad;  // deg -> radian conversion factor
+  static double _rad2deg;  // rad -> degree conversion factor
+  static double _rad2min;  // rad -> arcmin conversion factor
+  static double _rad2sec;  // rad -> arcmin conversion factor
+  
+};
+
+/*
+  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 
+  B. Revenu / G. Le Meur
+  "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
+*/
+ 
+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
+  //! return the vector product (*this)^v2
+  virtual Vector3d Vect(const Vector3d& v2) const;
+
+  // vecteur perpendiculaire de meme phi
+  //! return the perpendicular vector, with equal phi 
+  virtual Vector3d VperpPhi() const;
+
+  // vecteur perpendiculaire de meme theta
+  //! return the perpendicular vector, with equal theta 
+  virtual Vector3d VperpTheta() const;
+
+  virtual Vector3d ETheta() const;
+  virtual Vector3d EPhi() const;
+
+  // rotations d'Euler
+  //! Perform   Euler's rotations 
+  virtual Vector3d Euler(double, double, double) const;
+
+  // rotation inverse
+  //! perform   inverse Euler rotation 
+  Vector3d InvEuler(double, double, double) const;
+
+  // rotation d'angle phi autour d'un axe omega (regle du tire-bouchon)
+  //! perform 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_Nov2007/SophyaLib/SkyT/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/Makefile	(revision 3445)
@@ -0,0 +1,217 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSkyT.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)blackbody.o $(SOPHYAOBJP)convtools.o $(SOPHYAOBJP)derivblackbody.o $(SOPHYAOBJP)gaussfilt.o $(SOPHYAOBJP)nupower.o $(SOPHYAOBJP)radspec.o $(SOPHYAOBJP)radspecvector.o $(SOPHYAOBJP)skyinit.o $(SOPHYAOBJP)specresp.o $(SOPHYAOBJP)specrespvector.o $(SOPHYAOBJP)squarefilt.o $(SOPHYAOBJP)trianglefilt.o
+	rm -f $(SOPHYALIBP)libSkyT.a
+ 
+$(SOPHYALIBP)libSkyT.a : $(SOPHYAOBJP)blackbody.o $(SOPHYAOBJP)convtools.o $(SOPHYAOBJP)derivblackbody.o $(SOPHYAOBJP)gaussfilt.o $(SOPHYAOBJP)nupower.o $(SOPHYAOBJP)radspec.o $(SOPHYAOBJP)radspecvector.o $(SOPHYAOBJP)skyinit.o $(SOPHYAOBJP)specresp.o $(SOPHYAOBJP)specrespvector.o $(SOPHYAOBJP)squarefilt.o $(SOPHYAOBJP)trianglefilt.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)blackbody.o: blackbody.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h blackbody.h radspec.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  blackbody.cc
+ 
+$(SOPHYAOBJP)convtools.o: convtools.cc $(SOPHYAINCP)sopnamsp.h \
+  convtools.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  convtools.cc
+ 
+$(SOPHYAOBJP)derivblackbody.o: derivblackbody.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h derivblackbody.h \
+  radspec.h specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  derivblackbody.cc
+ 
+$(SOPHYAOBJP)gaussfilt.o: gaussfilt.cc $(SOPHYAINCP)machdefs.h \
+  gaussfilt.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  gaussfilt.cc
+ 
+$(SOPHYAOBJP)nupower.o: nupower.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nupower.h radspec.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nupower.cc
+ 
+$(SOPHYAOBJP)radspec.o: radspec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h radspec.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)integ.h \
+  $(SOPHYAINCP)classfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  radspec.cc
+ 
+$(SOPHYAOBJP)radspecvector.o: radspecvector.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h radspecvector.h \
+  radspec.h specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  radspecvector.cc
+ 
+$(SOPHYAOBJP)skyinit.o: skyinit.cc $(SOPHYAINCP)sopnamsp.h \
+  skyinit.h $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h specrespvector.h \
+  $(SOPHYAINCP)machdefs.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h gaussfilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skyinit.cc
+ 
+$(SOPHYAOBJP)specresp.o: specresp.cc $(SOPHYAINCP)sopnamsp.h \
+  specresp.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)integ.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)classfunc.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  specresp.cc
+ 
+$(SOPHYAOBJP)specrespvector.o: specrespvector.cc \
+  $(SOPHYAINCP)machdefs.h specrespvector.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  specrespvector.cc
+ 
+$(SOPHYAOBJP)squarefilt.o: squarefilt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h squarefilt.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  squarefilt.cc
+ 
+$(SOPHYAOBJP)trianglefilt.o: trianglefilt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h trianglefilt.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  trianglefilt.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/SkyT/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/Makefile.mgr	(revision 3445)
@@ -0,0 +1,120 @@
+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 \
+ $(INC)classfunc.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)classfunc.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_Nov2007/SophyaLib/SkyT/blackbody.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/blackbody.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/blackbody.cc	(revision 3445)
@@ -0,0 +1,100 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: blackbody.cc,v 1.9 2004-09-10 09:54:39 cmv 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyT/blackbody.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/blackbody.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/blackbody.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/convtools.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/convtools.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/convtools.cc	(revision 3445)
@@ -0,0 +1,29 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: convtools.cc,v 1.4 2004-09-10 09:54:39 cmv Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/SkyT/convtools.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/convtools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/convtools.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/derivblackbody.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/derivblackbody.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/derivblackbody.cc	(revision 3445)
@@ -0,0 +1,107 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: derivblackbody.cc,v 1.7 2004-09-10 09:54:40 cmv 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyT/derivblackbody.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/derivblackbody.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/derivblackbody.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/gaussfilt.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/gaussfilt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/gaussfilt.cc	(revision 3445)
@@ -0,0 +1,167 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: gaussfilt.cc,v 1.11 2007-04-27 16:13:35 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream>
+#include <math.h>
+
+#include "gaussfilt.h"
+
+namespace SOPHYA {
+
+/*! 
+ * \class 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;
+
+
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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());
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/SkyT/gaussfilt.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/gaussfilt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/gaussfilt.h	(revision 3445)
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: gaussfilt.h,v 1.6 2003-12-06 23:59:21 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& is, GaussianFilter & obj)
+    { ObjFileIO<GaussianFilter> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is);}
+
+}  // End of namespace 
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyT/nupower.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/nupower.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/nupower.cc	(revision 3445)
@@ -0,0 +1,103 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: nupower.cc,v 1.9 2004-09-10 09:54:40 cmv 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyT/nupower.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/nupower.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/nupower.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/objlist.list	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/radspec.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/radspec.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/radspec.cc	(revision 3445)
@@ -0,0 +1,309 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspec.cc,v 1.8 2004-09-10 09:54:40 cmv 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyT/radspec.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/radspec.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/radspec.h	(revision 3445)
@@ -0,0 +1,89 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspec.h,v 1.6 2003-02-11 15:31:07 cmv Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef RADSPEC_H_SEEN
+#define RADSPEC_H_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+
+#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_Nov2007/SophyaLib/SkyT/radspecvector.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/radspecvector.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/radspecvector.cc	(revision 3445)
@@ -0,0 +1,147 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspecvector.cc,v 1.9 2004-09-10 09:54:40 cmv 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaLib/SkyT/radspecvector.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/radspecvector.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/radspecvector.h	(revision 3445)
@@ -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>
+
+#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_Nov2007/SophyaLib/SkyT/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/SkyT/skyinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/skyinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/skyinit.cc	(revision 3445)
@@ -0,0 +1,44 @@
+// Classe d'initialisation du module Outils++ 
+#include <unistd.h>
+
+#include "sopnamsp.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;
+
+// Module version number 
+#define MOD_VERS  0.7 
+
+SkyTInitiator::SkyTInitiator()
+  : NToolsInitiator()
+{
+  SkyTInitiator::FgInit++;
+  if (SkyTInitiator::FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du modules SkyT
+  
+  PPRegister(ObjFileIO<SpecRespVec>);
+  DObjRegister(ObjFileIO<SpecRespVec>, SpecRespVec);
+  PPRegister(ObjFileIO<GaussianFilter>);
+  DObjRegister(ObjFileIO<GaussianFilter>, GaussianFilter);
+
+  SophyaInitiator::RegisterModule("SkyT", MOD_VERS);  // Module name and version number registration
+}
+
+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_Nov2007/SophyaLib/SkyT/skyinit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/skyinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/skyinit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/skyt.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/skyt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/skyt.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/smakefile	(revision 3445)
@@ -0,0 +1,217 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSkyT.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)blackbody.o $(SOPHYAOBJP)convtools.o $(SOPHYAOBJP)derivblackbody.o $(SOPHYAOBJP)gaussfilt.o $(SOPHYAOBJP)nupower.o $(SOPHYAOBJP)radspec.o $(SOPHYAOBJP)radspecvector.o $(SOPHYAOBJP)skyinit.o $(SOPHYAOBJP)specresp.o $(SOPHYAOBJP)specrespvector.o $(SOPHYAOBJP)squarefilt.o $(SOPHYAOBJP)trianglefilt.o
+	rm -f $(SOPHYALIBP)libSkyT.a
+ 
+$(SOPHYALIBP)libSkyT.a : $(SOPHYAOBJP)blackbody.o $(SOPHYAOBJP)convtools.o $(SOPHYAOBJP)derivblackbody.o $(SOPHYAOBJP)gaussfilt.o $(SOPHYAOBJP)nupower.o $(SOPHYAOBJP)radspec.o $(SOPHYAOBJP)radspecvector.o $(SOPHYAOBJP)skyinit.o $(SOPHYAOBJP)specresp.o $(SOPHYAOBJP)specrespvector.o $(SOPHYAOBJP)squarefilt.o $(SOPHYAOBJP)trianglefilt.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)blackbody.o: blackbody.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h blackbody.h radspec.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  blackbody.cc
+ 
+$(SOPHYAOBJP)convtools.o: convtools.cc $(SOPHYAINCP)sopnamsp.h \
+  convtools.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  convtools.cc
+ 
+$(SOPHYAOBJP)derivblackbody.o: derivblackbody.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h derivblackbody.h \
+  radspec.h specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  derivblackbody.cc
+ 
+$(SOPHYAOBJP)gaussfilt.o: gaussfilt.cc $(SOPHYAINCP)machdefs.h \
+  gaussfilt.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  gaussfilt.cc
+ 
+$(SOPHYAOBJP)nupower.o: nupower.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nupower.h radspec.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h convtools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nupower.cc
+ 
+$(SOPHYAOBJP)radspec.o: radspec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h radspec.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)integ.h \
+  $(SOPHYAINCP)classfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  radspec.cc
+ 
+$(SOPHYAOBJP)radspecvector.o: radspecvector.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h radspecvector.h \
+  radspec.h specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pexceptions.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  radspecvector.cc
+ 
+$(SOPHYAOBJP)skyinit.o: skyinit.cc $(SOPHYAINCP)sopnamsp.h \
+  skyinit.h $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h specrespvector.h \
+  $(SOPHYAINCP)machdefs.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h gaussfilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skyinit.cc
+ 
+$(SOPHYAOBJP)specresp.o: specresp.cc $(SOPHYAINCP)sopnamsp.h \
+  specresp.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)integ.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)classfunc.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  specresp.cc
+ 
+$(SOPHYAOBJP)specrespvector.o: specrespvector.cc \
+  $(SOPHYAINCP)machdefs.h specrespvector.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  specrespvector.cc
+ 
+$(SOPHYAOBJP)squarefilt.o: squarefilt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h squarefilt.h specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  squarefilt.cc
+ 
+$(SOPHYAOBJP)trianglefilt.o: trianglefilt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h trianglefilt.h \
+  specresp.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  trianglefilt.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/SkyT/specresp.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/specresp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/specresp.cc	(revision 3445)
@@ -0,0 +1,205 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specresp.cc,v 1.7 2004-09-10 09:54:40 cmv 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 "sopnamsp.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_Nov2007/SophyaLib/SkyT/specresp.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/specresp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/specresp.h	(revision 3445)
@@ -0,0 +1,82 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specresp.h,v 1.5 2003-02-11 15:31:07 cmv 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>
+//------------------------------------
+// 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_Nov2007/SophyaLib/SkyT/specrespvector.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/specrespvector.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/specrespvector.cc	(revision 3445)
@@ -0,0 +1,191 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specrespvector.cc,v 1.13 2007-04-27 16:17:01 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>
+#include <math.h>
+// #include <typeinfo>
+
+#include "specrespvector.h"
+#include "pexceptions.h"
+#include "fioarr.h"
+
+namespace SOPHYA {
+
+//----------------
+// Constructor --
+//----------------
+/*! 
+ * \class 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();
+}
+
+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();
+}
+
+
+//--------------
+// 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;
+
+}
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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);
+  }
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/SkyT/specrespvector.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/specrespvector.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/specrespvector.h	(revision 3445)
@@ -0,0 +1,76 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specrespvector.h,v 1.7 2003-12-06 23:59:21 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+#ifndef SPECRESPVEC_H_SEEN
+#define SPECRESPVEC_H_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+
+#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& is, SpecRespVec & obj)
+    { ObjFileIO<SpecRespVec> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is);}
+
+}  // End of namespace 
+#endif
Index: /tags/V_Nov2007/SophyaLib/SkyT/squarefilt.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/squarefilt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/squarefilt.cc	(revision 3445)
@@ -0,0 +1,95 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: squarefilt.cc,v 1.8 2004-09-10 09:54:40 cmv Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+
+#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_Nov2007/SophyaLib/SkyT/squarefilt.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/squarefilt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/squarefilt.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SkyT/trianglefilt.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/trianglefilt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/trianglefilt.cc	(revision 3445)
@@ -0,0 +1,104 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: trianglefilt.cc,v 1.8 2004-09-10 09:54:40 cmv Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+
+#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_Nov2007/SophyaLib/SkyT/trianglefilt.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SkyT/trianglefilt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SkyT/trianglefilt.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SysTools/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/Makefile	(revision 3445)
@@ -0,0 +1,83 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSysTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
+	rm -f $(SOPHYALIBP)libSysTools.a
+ 
+$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h \
+  cexpre.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cexpre.cc
+ 
+$(SOPHYAOBJP)commander.o: commander.cc $(SOPHYAINCP)sopnamsp.h \
+  commander.h $(SOPHYAINCP)machdefs.h pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h ctimer.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h cexpre.h \
+  $(SOPHYAINCP)pexceptions.h rpneval.h \
+  $(SOPHYAINCP)srandgen.h zthread.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  commander.cc
+ 
+$(SOPHYAOBJP)ctimer.o: ctimer.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ctimer.cc
+ 
+$(SOPHYAOBJP)cxxcmplnk.o: cxxcmplnk.cc $(SOPHYAINCP)sopnamsp.h \
+  cxxcmplnk.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sspvflags.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxcmplnk.cc
+ 
+$(SOPHYAOBJP)pdlmgr.o: pdlmgr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sopnamsp.h pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pdlmgr.cc
+ 
+$(SOPHYAOBJP)periodic.o: periodic.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h periodic.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  periodic.cc
+ 
+$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h \
+  psighand.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psighand.cc
+ 
+$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h \
+  resusage.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  resusage.cc
+ 
+$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h \
+  rpneval.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rpneval.cc
+ 
+$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h \
+  zthread.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  zthread.cc
+ 
+$(SOPHYAOBJP)timing.o: timing.c timing.h
+	$(CCOMPILE) -o $@  timing.c
+ 
Index: /tags/V_Nov2007/SophyaLib/SysTools/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/Makefile.mgr	(revision 3445)
@@ -0,0 +1,58 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSysTools.a
+clean:
+	rm -f $(OBJ)cexpre.o $(OBJ)commander.o $(OBJ)ctimer.o $(OBJ)cxxcmplnk.o $(OBJ)pdlmgr.o $(OBJ)periodic.o $(OBJ)psighand.o $(OBJ)resusage.o $(OBJ)rpneval.o $(OBJ)zthread.o $(OBJ)timing.o
+	rm -f $(LIB)libSysTools.a
+$(LIB)libSysTools.a : $(OBJ)cexpre.o $(OBJ)commander.o $(OBJ)ctimer.o $(OBJ)cxxcmplnk.o $(OBJ)pdlmgr.o $(OBJ)periodic.o $(OBJ)psighand.o $(OBJ)resusage.o $(OBJ)rpneval.o $(OBJ)timing.o $(OBJ)zthread.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)cexpre.o: cexpre.cc cexpre.h $(INC)machdefs.h \
+  $(INC)osx_values.h \
+  $(INC)pexceptions.h
+$(OBJ)commander.o: commander.cc commander.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h ctimer.h \
+  $(INC)strutil.h \
+  $(INC)strutilxx.h \
+  $(INC)srandgen.h
+$(OBJ)ctimer.o: ctimer.cc $(INC)machdefs.h \
+  $(INC)osx_values.h ctimer.h
+$(OBJ)cxxcmplnk.o: cxxcmplnk.cc cxxcmplnk.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h
+$(OBJ)pdlmgr.o: pdlmgr.cc $(INC)machdefs.h \
+  $(INC)osx_values.h pdlmgr.h
+$(OBJ)periodic.o: periodic.cc $(INC)machdefs.h \
+  $(INC)osx_values.h periodic.h
+$(OBJ)psighand.o: psighand.cc psighand.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h \
+  $(INC)pexceptions.h
+$(OBJ)resusage.o: resusage.cc resusage.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h
+$(OBJ)rpneval.o: rpneval.cc rpneval.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h \
+  $(INC)pexceptions.h \
+  $(INC)strutilxx.h \
+  $(INC)srandgen.h
+$(OBJ)zthread.o: zthread.cc zthread.h \
+  $(INC)machdefs.h \
+  $(INC)osx_values.h \
+  $(INC)pexceptions.h
+$(OBJ)timing.o: timing.c timing.h
Index: /tags/V_Nov2007/SophyaLib/SysTools/cexpre.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/cexpre.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/cexpre.cc	(revision 3445)
@@ -0,0 +1,622 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "sopnamsp.h"
+#include "cexpre.h"
+#include <stack>
+#include <math.h>
+#include "srandgen.h"
+
+namespace SOPHYA {
+
+long CExprBase::totnexp_create = 0;
+long CExprBase::totnexp_delete = 0;
+CExprBase::CExprBase()
+{
+  totnexp_create++;
+  // cout << "CExprBase::CExprBase()-Creation " << hex << this << dec << endl;
+}
+
+CExprBase::~CExprBase()
+{
+  totnexp_delete++;
+  // cout << "CExprBase::~CExprBase() " << hex << this << dec << endl;
+}
+
+void CExprBase::CheckThrow(const char * msg) const
+{
+  string errmsg;
+  bool ok = CheckE(errmsg);
+  if (ok) return;
+  else {
+    errmsg += msg;
+    throw CExprException(errmsg);
+  }
+}
+
+//---------------------------------------------------------
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Class representing numbers for expression evaluation 
+  \sa CExpressionEvaluator
+*/
+class CE_NumberExp : public CExprBase {
+public:
+  CE_NumberExp(double v) { _val = v; }
+  CE_NumberExp(string const & s);
+  virtual ~CE_NumberExp() {}
+  virtual double Evaluate() const { return _val; }  
+  virtual void  Print(ostream& os) const { os << _val; }
+protected:
+  double _val;
+};
+
+CE_NumberExp::CE_NumberExp(string const & s)
+{
+  size_t l = s.length();
+  if (l < 1) { 
+    string errmsg = "CE_NumberExp::CE_NumberExp() Empty expression";
+    throw CExprException(errmsg);
+  }
+  if (s == "Pi") _val = M_PI;
+  else if (s == "E") _val = M_E;
+  else {
+    string errmsg = "CE_NumberExp::CE_NumberExp() Bad numerical constant: ";
+    errmsg += s;
+    
+    char* lcc;
+    _val = strtod(s.c_str(), &lcc);
+    if (*lcc != '\0')  throw CExprException(errmsg);
+  }
+}
+
+//---------------------------------------------------------
+//-----------  Expression changement de signe -------------
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Class for handling change sign expression (-x)
+  \sa CExpressionEvaluator
+*/
+class CE_ChsExp : public CExprBase {
+public:
+  explicit CE_ChsExp(CExprBase * e) { _e = e; } 
+  virtual  ~CE_ChsExp() { if (_e) delete _e; } 
+  virtual double Evaluate() const { return -_e->Evaluate(); }  
+  virtual bool   CheckE(string& errmsg) const { if (_e) return true; else return false; }
+  virtual void  Print(ostream& os) const { os << "-( "; _e->Print(os); os << " )"; }
+ protected:
+  CExprBase * _e;
+};
+
+//---------------------------------------------------------
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Base class for binary operations on expressions
+  \sa CExpressionEvaluator
+*/
+class CE_BinExp : public CExprBase {
+public:
+  explicit CE_BinExp(char op, int prior); 
+  virtual ~CE_BinExp() { if (_e1) delete _e1; if (_e2) delete _e2; }
+  inline void SetE1(CExprBase * e) { _e1 = e; } 
+  inline void SetE2(CExprBase * e) { _e2 = e; }
+  virtual bool CheckE(string& errmsg) const; 
+  virtual void Print(ostream& os) const;
+  inline char BOpC() const { return _bop; } 
+  inline int  Priority() const { return _priority; } 
+ protected:
+  CExprBase * _e1;
+  CExprBase * _e2;
+  char _bop;     // Caractere identificateur d'operation (+,-,*,/ ...)
+  int _priority; // Niveau de priorite: 1= +,-  2: *,/  3: ^...
+};
+
+CE_BinExp::CE_BinExp(char op, int prior)
+{
+  _e1 = NULL; _e2 = NULL; 
+  _bop = op;
+  _priority = prior;
+}
+
+bool CE_BinExp::CheckE(string& errmsg) const 
+{	
+  if ((_e1 == NULL) || (_e2 == NULL)) {
+    errmsg += "CE_BinExp::CheckE: Binary expression-missing argument ";
+    return false;
+  }
+  return true;
+}
+
+void CE_BinExp::Print(ostream& os) const
+{ 
+  os << "(" << (*_e1) << _bop << (*_e2) << ")" ; 
+}
+
+//---------------------------------------------------------
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Addition of two CExprBase (binary operation : x+y)
+  \sa CExpressionEvaluator
+*/
+class CE_AddExp : public CE_BinExp {
+public:
+  CE_AddExp() : CE_BinExp('+',1) {}
+  virtual double Evaluate() const { CheckThrow("CE_AddExp::Evaluate"); return _e1->Evaluate()+_e2->Evaluate();
+ }
+};
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Multiplication of two CExprBase (binary operation : x*y)
+  \sa CExpressionEvaluator
+*/
+class CE_MulExp : public CE_BinExp {
+public:
+  CE_MulExp() : CE_BinExp('*',2) {}
+  virtual double Evaluate() const { CheckThrow("CE_MulExp::Evaluate"); return _e1->Evaluate()*_e2->Evaluate(); }
+};
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Subtraction of two CExprBase (binary operation : x-y)
+  \sa CExpressionEvaluator
+*/
+class CE_SubExp : public CE_BinExp {
+public:
+  CE_SubExp() : CE_BinExp('-',1) {}
+  virtual double Evaluate() const { CheckThrow("CE_SubExp::Evaluate"); return _e1->Evaluate()-_e2->Evaluate(); }
+};
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Division of two CExprBase (binary operation : x/y)
+  \sa CExpressionEvaluator
+*/
+class CE_DivExp : public CE_BinExp {
+public:
+  CE_DivExp() : CE_BinExp('/',2) {}
+  virtual double Evaluate() const { CheckThrow("CE_DivExp::Evaluate"); return _e1->Evaluate()/_e2->Evaluate(); }
+};
+
+//---------------------------------------------------------
+typedef double (* f0exp) ();
+typedef double (* f1exp) (double x);
+typedef double (* f2exp) (double x, double y);
+typedef double (* f3exp) (double x, double y, double z);
+
+//---------------------------------------------------------
+#define FMXARG 3
+/*! 
+  \internal 
+  \ingroup SysTools
+  \brief Function evaluation on other expression in the form f(), f(x), f(x,y), f(x,y,z)
+  \sa CExpressionEvaluator
+*/
+class CE_FuncExp : public CExprBase {
+public:
+  CE_FuncExp(string const & func);
+  virtual ~CE_FuncExp(); 
+  virtual double Evaluate() const ;
+  inline void AddArg(CExprBase * e);
+  inline int  GetMaxNArg() const { return _maxne; }
+  virtual bool CheckE(string& errmsg) const; 
+  virtual void Print(ostream& os) const;
+protected:
+  f0exp _f0; 
+  f1exp _f1; 
+  f2exp _f2; 
+  f3exp _f3; 
+  int _ne, _maxne;
+  CExprBase * _e[FMXARG];
+  string _fname;
+};
+
+// Les fonctions de generation de nombre aleatoire
+static double _CE_rand01() { return drand01(); }
+static double _CE_randpm1() { return drandpm1(); }
+static double _CE_gaurand() { return GauRnd(0., 1.); }
+//---------------------------------------------------------
+CE_FuncExp::CE_FuncExp(string const & func)
+{
+  _ne = 0; _maxne = -1;
+  for(int k=0; k<FMXARG; k++)  _e[k] = NULL;
+  _f0 = NULL;
+  _f1 = NULL;
+  _f2 = NULL;
+  _f3 = NULL;
+  if (func == "sin") _f1 = sin;
+  else if (func == "cos") _f1 = cos;
+  else if (func == "tan") _f1 = tan;
+  else if (func == "asin") _f1 = asin;
+  else if (func == "acos") _f1 = acos;
+  else if (func == "atan") _f1 = atan;
+  else if (func == "atan2") _f2 = atan2;
+  else if (func == "sqrt") _f1 = sqrt;
+  else if (func == "fabs") _f1 = fabs;
+  else if (func == "floor") _f1 = floor;
+  else if (func == "exp") _f1 = exp;
+  else if (func == "log") _f1 = log;
+  else if (func == "log10") _f1 = log10;
+  else if (func == "pow") _f2 = pow;
+  else if (func == "hypot") _f2 = hypot;
+  else if (func == "sinh") _f1 = sinh;
+  else if (func == "cosh") _f1 = cosh;
+  else if (func == "tanh") _f1 = tanh;
+// Les fonctions aleatoires declaree plus haut 
+  else if (func == "rand01") _f0 = _CE_rand01;	
+  else if (func == "randpm1") _f0 = _CE_randpm1;	
+  else if (func == "gaurand") _f0 = _CE_gaurand;	
+  else { 
+    string errmsg = "CE_FuncExp::CE_FuncExp() - Uknown function " ;
+    errmsg += func;
+    throw CExprException(errmsg);
+  } 
+  if (_f0)  _maxne = 0;
+  else if (_f1)  _maxne = 1;
+  else if (_f2) _maxne = 2;
+  else if (_f3) _maxne = 3;
+  _fname = func;
+}
+
+
+CE_FuncExp::~CE_FuncExp()
+{  
+for(int k=0; k<FMXARG; k++)  if (_e[k]) delete _e[k];
+}
+
+void CE_FuncExp::AddArg(CExprBase * e)
+{
+  if ((e != NULL) && (_ne < _maxne)) { _e[_ne] = e; _ne++; }
+  else  throw CExprException("CE_FuncExp::AddArg() e=NULL or too many arguments ");
+}
+
+double CE_FuncExp::Evaluate() const 
+{
+  if ((_ne != _maxne) || (_maxne < 0) ) {
+    throw CExprException("CE_FuncExp::Evaluate() - Wrong argument number ");
+  }
+  if (_ne == 0) return _f0();
+  else if (_ne == 1) return _f1(_e[0]->Evaluate());
+  else if (_ne == 2) return _f2(_e[0]->Evaluate(), _e[1]->Evaluate());
+  else if (_ne == 3) return _f3(_e[0]->Evaluate(), _e[1]->Evaluate(), 
+				_e[2]->Evaluate());
+  else return 0.;
+}
+
+bool CE_FuncExp::CheckE(string& errmsg) const
+{	
+  if ((_ne != _maxne) || (_maxne < 0) ) {
+    char buff[128];
+    sprintf(buff, "CE_FuncExp::CheckE() %s - Wrong argument number - ne=%d maxne=%d ", 
+	    _fname.c_str(), _ne, _maxne);
+    errmsg += buff;
+    return false;
+  }
+  return true;
+}
+
+void CE_FuncExp::Print(ostream& os) const
+{ 
+  if ((_ne != _maxne) || (_maxne < 1) ) 
+    os << _fname << "(ArgError)" ;
+  else {
+    if (_ne == 1) os << _fname << "(" << *(_e[0]) << ")";
+    else if (_ne == 2) os << _fname << "(" << *(_e[0]) << "," << *(_e[1]) << ")";
+    else if (_ne == 3) os << _fname << "(" << *(_e[0]) 
+			  << "," << *(_e[1]) << "," << *(_e[2]) << ")";
+  }
+}
+
+//---------------------------------------------------------
+/*!
+  \class CExpressionEvaluator
+  \ingroup SysTools
+  \brief Class for evaluation of arithmetic expressions with C-like syntax.
+
+  This classes can handle the parsing of c-like arithmetic
+  expressions containing numerical constants, the four 
+  basic operations (addition +, subtraction -, multiplication *,
+  division /) and functions.
+  The numerical constants are also defined <tt> (Pi = M_PI E = M_E) </tt>.
+  The following functions from the standard math library and 
+  random generators are available:
+  
+  - sqrt fabs floor hypot
+  - exp log log10 pow 
+  - sin cos tan asin acos atan atan2
+  - sinh cosh tanh
+  - rand01() : Flat random number generator in the range [0 1]
+  - randpm1() : Flat random number generator in the range [-1 1]
+  - gaurand() : Gaussian random number generator (m=0, sigma=1)
+
+  Usage example : 
+  \code
+  #include "cexpre.h"
+  ...
+  string es = "4.+3*(cos(Pi/8.)+1.5)";
+  CExpressionEvaluator e(es);
+  cout << " Expression: " << e << " = " << e.Evaluate() << endl;
+  \endcode
+
+  Output : \n
+  <tt>  Expression: (4+(3*(cos((3.14159/8))+1.5))) = 11.2716 </tt>
+*/
+
+/*! 
+  Parse the string \c sex and builds an expression.
+  Can throw CExprException exception.
+*/
+CExpressionEvaluator::CExpressionEvaluator(string const & sex)
+{
+  _exp = NULL;
+  size_t off=0,stop=0;
+  string fname = "";
+  string errmsg;
+  _exp=  ParseString(0,fname,sex,off,stop,errmsg);
+  if (_exp == NULL)  throw CExprException(errmsg);
+}
+
+CExpressionEvaluator::~CExpressionEvaluator()
+{
+  if (_exp) delete _exp;
+}
+
+double CExpressionEvaluator::Evaluate() const
+{
+  if (_exp) return _exp->Evaluate();
+  else return 0.;
+}
+
+void CExpressionEvaluator::Print(ostream& os) const
+{
+  if (_exp) _exp->Print(os);
+  else os << "CExpressionEvaluator ???";
+}
+
+// cette fonction rearrange le stack des operations binaires en attente
+static CExprBase* Arrange_CE_BinExpStack(stack<CE_BinExp* >& sbx, CExprBase* cex, CE_BinExp* nbx)
+{
+  while ( !sbx.empty() && (nbx->Priority() <= sbx.top()->Priority()) ) {
+    sbx.top()->SetE2(cex);
+    cex = sbx.top();  sbx.pop();
+  }
+  nbx->SetE1(cex);
+  sbx.push(nbx);
+  return NULL;
+}
+
+// cette fonction rearrange le stack des operations binaires en attente
+static CExprBase* Arrange_CE_BinExpStack(stack<CE_BinExp* >& sbx, CExprBase* cex)
+{
+  if (sbx.empty())  return cex;
+  while ( !sbx.empty() ) {
+    sbx.top()->SetE2(cex);
+    cex = sbx.top();  sbx.pop();
+  }
+  return cex;
+}
+
+
+CExprBase* CExpressionEvaluator::ParseString(int extype, string fname, string const & sex, 
+					size_t off, size_t& stop, string& errmsg)
+{
+  size_t len = sex.length();
+  if (len < 1) { 
+    string errmsg = "CExpressionEvaluator::ParseString() Empty expression";
+    throw CExprException(errmsg);
+  }
+  errmsg = "";
+  CExprBase* rx = NULL;   // Expression resultat
+  stack< CE_BinExp* > sbx;  // Stack des expressions binaires
+  CE_FuncExp* fx = NULL;    // Expression fonction 
+  CExprBase* cx = NULL;       // Element d'expression (courante)
+
+  if (extype == 2)  fx = new CE_FuncExp(fname);
+
+  size_t p=0, q=0;
+  char lastopc=0, opc=0; // Last/current operation sign (+,-,*,/,...)
+  int osn = 0;
+  bool finok = false;
+  bool fgcont = true;
+  bool checkok = true;
+  bool apperrmsg = true;
+  //  cout << " DBG-ParseString off= " << off << " sex[off]= " << sex[off] 
+  //	<< " extype= " << extype << endl;
+  p = stop = off;  
+  while ((p < len) && (fgcont) && (checkok) ) { 
+    // cout << " DBG-2-ParseString p=" << p << " q=" << q << endl;
+
+    cx = NULL;
+    // ------------------------------- Bretelle ------
+    // Il faut sauter les signes +/- qui se trouverait dans les
+    // exposants des nombres xxxe-yy xxxe+y : 0.4e-2 ...
+    // Les qques lignes sont une bretelle qui saute ces signes +/- (Reza, Aout 2004) 
+    // On verifie d'abord s'il y a un nombre valide au debut de la positions courante
+    char* lcc;
+    size_t pfn=0,psn;
+    bool numberok = false;
+    strtod(sex.c_str()+p, &lcc);
+    if (lcc != sex.c_str()+p) {  // Expression valide de double au debut 
+      numberok = true;           // de la position courante
+      pfn = lcc-sex.c_str();
+    }
+    // On cherche le 1er signe d'operateur - apres le nombre de debut 
+    q = sex.find_first_of("+-*/(),",p);
+
+    while ( numberok && (q < len) && (q < pfn) && (q > p) && 
+            ((sex[q] == '+') || (sex[q] == '-')) ) {
+      psn = q+1; 
+      if (psn < len) q = sex.find_first_of("+-*/(),",psn);
+      else q = len+1;
+    }
+    //---- Fin de la Bretelle ---- pour sauter les signes +/- de l'exposant des nombres
+
+    if (q < len) {  // operateur trouve
+      opc = sex[q];  // signe operateur courant
+      switch (opc) {
+        case '(' : 
+	  if (q == p) { 
+	    string fname = "";
+	    cx = ParseString(1, fname, sex, q+1, stop, errmsg);
+	  }
+	  else cx = ParseString(2, sex.substr(p,q-p), sex, q+1, stop, errmsg);
+	  if (!cx)  { checkok = false; p = stop+1; apperrmsg = false; }
+	  else { 
+	    if (osn == 1) {
+              if (sex[p-osn] == '-')  cx = new CE_ChsExp(cx);
+            }
+	    if (osn > 1) {
+	      checkok = false; p = stop+1; fgcont = false; 
+	      delete cx;
+	      errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - multiple chs (+/-) (AA)"; 
+            }
+	    else if (rx) { 
+	      checkok = false; p = stop+1; fgcont = false; 
+	      delete cx;
+	      errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - rx&&cx (A)"; 
+	    }
+	    else {
+	      if (stop == len-1)  { 
+		rx = Arrange_CE_BinExpStack(sbx, cx);
+		finok = true;
+	      }
+	      else rx = cx;
+	      p = stop+1; osn = 0; lastopc = opc; 
+	    }
+	  }
+	  break;
+
+        case ')' : 
+        case ',' :
+	  if (extype == 0) {
+	    checkok = false; p = q;  fgcont = false; 
+	    errmsg = "CExpressionEvaluator::ParseString() Unexpected ) or ,";
+	  }
+          if ( (extype == 1) && (opc == ',')) {
+	    checkok = false; p = q;  fgcont = false; 
+	    errmsg = "CExpressionEvaluator::ParseString() Unexpected ,";
+	  }
+	  if ((q > p) && (rx)) {
+	    checkok = false; p = q;  fgcont = false; 
+	    errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - rx&&cx (B)"; 
+	  }
+	  if (q > p) cx = new CE_NumberExp(sex.substr(p-osn,q-p+osn));
+	  else cx = rx;
+	  
+	  if (!cx && ( !fx || ( opc != ')' ) || 
+                       ( (fx && (fx->GetMaxNArg() > 0) && (opc == ')' ) ) ) ) ) {
+	    checkok = false; p = q;  fgcont = false; 
+	    errmsg = "CExpressionEvaluator::ParseString()/ Syntax Error - farg=NULL (BB)"; 
+	  }
+	  else {
+	    if (cx) { rx = Arrange_CE_BinExpStack(sbx, cx);
+	      if (extype == 2) {
+	        //	    cout << " DBG-ParseString-AddArg " << *(cx) << endl;
+	        fx->AddArg(rx);  rx = NULL;
+	      }
+            }
+	    if (opc == ')') { // Signe de fin de traitement d'une portion d'expression
+	      if (extype == 2) { rx = fx; fx = NULL; }
+	      stop = q;  osn = 0; lastopc = opc;
+	      fgcont = false;
+	      finok = true;
+	    }
+	    else {
+	      if (q == (len-1)) finok = true;
+	      p = q+1; osn = 0; lastopc = opc; 
+	    }
+	  }
+	  break;
+
+        case '+' :
+        case '-' :
+        case '*' :
+        case '/' :
+	  if (!( ((opc=='+')||(opc=='-')) && ( (q==off) || ( (q==p) && lastopc != '(') ) ) ) {
+	    CE_BinExp* nbx;
+	    if (opc == '+')  nbx = new CE_AddExp;  
+	    else if (opc == '-')  nbx = new CE_SubExp;   
+	    else if (opc == '*')  nbx = new CE_MulExp;   
+	    else  nbx =  new CE_DivExp;  
+	    if ((p == q) && (rx == NULL)) {
+	      checkok = false; p = q;  osn = 0; fgcont = false; 
+	      delete nbx;
+	      errmsg = "CExpressionEvaluator::ParseString() Syntax Error - rx==NULL (C)";
+	    }
+	    else {
+	      if (p == q)  cx = rx;
+	      else cx = new CE_NumberExp(sex.substr(p-osn,q-p+osn));
+	      rx = Arrange_CE_BinExpStack(sbx, cx, nbx);
+	      p = q+1;  osn = 0; lastopc = opc;
+	    }
+	  }
+	  else {
+	  // Traitement des signes +/- qui pourrait faire partie d'une constante numerique
+	    p = q+1;  osn++;
+	    continue;
+	  }
+	  break;
+        default:
+	  throw CExprException("CExpressionEvaluator::ParseString() BUG-BUG-BUG");
+	  break;
+      }  // Fin de switch 
+    }
+    else {  // dernier element
+      if ( (p<len) && (rx != NULL)) {
+	checkok = false; p = len-1; fgcont = false; 
+	errmsg = "CExpressionEvaluator::ParseString() Syntax Error - rx!=NULL at end (D)";
+      }
+      else { 
+	if (p<len)  cx = new CE_NumberExp(sex.substr(p-osn));
+	else cx = rx;
+	rx = Arrange_CE_BinExpStack(sbx, cx);
+	stop = p = len;  fgcont = false;      
+	finok = true;  
+      }
+    }
+  }
+  //  cout << " DBG-ParseString-out stop= " << stop << " sex[stop]= " << sex[stop] << endl; 
+  if (finok && checkok) { 
+    if( !sbx.empty() ) { 
+      checkok = false; 
+      errmsg = "CExpressionEvaluator::ParseString() !sbx.empty() at the end (E)";
+    }
+    else  { 
+      checkok = rx->CheckE(errmsg);
+    }
+  }
+  if (!finok || !checkok || !rx) {
+    char buff[128];
+    if (errmsg.length() < 1) {
+      errmsg = "CExpressionEvaluator::ParseString() Error - " ;
+      if (!finok) errmsg += " !finok " ;
+      if (!checkok) errmsg += " !checkok " ;
+      if (!rx)  errmsg += " !rx " ;
+      errmsg += " (F)";
+    }    
+
+    if (apperrmsg) {
+      if (p<len) 
+        sprintf(buff,"\n CExprError... %s <> %s ", sex.substr(0,p).c_str(), 
+	        sex.substr(p).c_str());
+      else  sprintf(buff,"\n CExprError... %s <<", sex.c_str());
+      errmsg += buff;
+    }
+    if (rx) delete rx;
+    rx = NULL;
+    while (!sbx.empty()) {
+      delete sbx.top();
+      sbx.pop();
+    }
+  }
+  if (fx) delete fx; 
+  return rx;
+}
+
+}   // End of namespace SOPHYA
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/cexpre.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/cexpre.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/cexpre.h	(revision 3445)
@@ -0,0 +1,80 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Evaluateur d'expression C   -   R. Ansari 03/2004
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef CEXPREVAL_SEEN
+#define CEXPREVAL_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+#include <string>
+#include "pexceptions.h"
+
+using namespace std;
+namespace SOPHYA {
+
+/*! 
+  \ingroup SysTools
+  \brief Exception class used by  CExpressionEvaluator
+*/
+class CExprException : public PException {
+  public:
+  explicit CExprException(const char * m) : PException(m) {}
+  explicit CExprException(const string& m) : PException(m) {}
+};
+
+//--------------------------------------------------------------------
+/*! 
+  \ingroup SysTools
+  \brief Base class for arithmetic expressions used by CExpressionEvaluator
+  \sa CExpressionEvaluator
+*/
+class CExprBase {
+public:
+  explicit CExprBase(); 
+  virtual ~CExprBase();
+  virtual double Evaluate() const = 0;
+  virtual bool   CheckE(string& errmsg) const { return true; }
+  virtual void   CheckThrow(const char * msg) const;
+  inline  void   CheckThrow(string const & msg) const { CheckThrow(msg.c_str()); }
+  virtual void   Print(ostream& os) const = 0;
+  static long    NbCreate() { return totnexp_create; }
+  static long    NbDelete() { return totnexp_delete; }
+protected:
+  static long totnexp_create;
+  static long totnexp_delete;
+};
+
+/*! 
+  \ingroup SysTools
+  \brief For formatted write (print) of expressions in a stream
+*/
+inline ostream& operator << (ostream& s, CExprBase const & ex)
+  {  ex.Print(s);  return(s);  }
+
+class CE_BinExp;
+class CE_FuncExp;
+//---------------------------------------------------------
+class CExpressionEvaluator : public CExprBase {
+public:
+  CExpressionEvaluator(string const & sex);
+  virtual ~CExpressionEvaluator();
+//! Evaluate the expression and returns the corresponding value.
+  virtual double Evaluate() const;
+//! Alias for Evaluate()
+  inline double Value() const { return Evaluate(); }
+//! Formatted output on a stream
+  virtual void  Print(ostream& os) const;
+
+protected:
+//! Does the parsing and builds an CExprBase object.
+  CExprBase* ParseString(int extype, string fname, string const & sex, 
+		    size_t off, size_t& stop, string& errmsg);
+
+  CExprBase * _exp;
+};
+
+}   // End of namespace SOPHYA
+
+/* end of ifdef CEXPREVAL_SEEN */
+#endif
Index: /tags/V_Nov2007/SophyaLib/SysTools/commander.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/commander.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/commander.cc	(revision 3445)
@@ -0,0 +1,2357 @@
+#include "sopnamsp.h"
+#include "commander.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <math.h>
+#include <signal.h>
+
+#include "strutil.h"
+#include "strutilxx.h"
+#include "cexpre.h"
+#include "rpneval.h"
+#include "srandgen.h"
+#include "zthread.h"
+
+
+namespace SOPHYA {
+
+// Differents code de retour specifiques 
+#define CMD_RETURN_RC  99900
+#define CMD_BREAK_RC   99990
+#define CMD_BREAKEXE_RC 99999
+
+// ------------------------------------------------------------
+//         Bloc de commandes (Foreach, ...)    
+//               Classe  CommanderBloc    
+// ------------------------------------------------------------
+/*!
+  \internal
+  \class SOPHYA::CommanderBloc
+  \ingroup SysTools 
+  Class for internal use by class Commander to handle loops
+*/
+class CommanderBloc {
+public:
+  enum BType { BT_None, BT_ForeachList, BT_ForeachInt, BT_ForeachFloat, 
+	       BT_ForeachLineInFile };
+
+  CommanderBloc(Commander* piac, CommanderBloc* par, string& kw, vector<string>& args); 
+  ~CommanderBloc();
+  inline CommanderBloc*   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(CommanderBloc* blk)  
+    { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
+
+  // Execution complete du bloc (boucle)
+  int	        Execute();
+  // Execution pour un element de bloc 
+  int	        ExecuteOnce(string& lvv);
+
+  inline int&   TestLevel()  { return testlevel; }
+  inline int&   LoopLevel()  { return looplevel; }
+  inline bool   CheckBloc() 
+    { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)); }
+  
+protected:
+  Commander* _commander;
+  CommanderBloc* parent;
+  bool blkok;        // true -> block OK
+  BType typ;         // foreach , integer loop, float loop, test 
+  string varname;
+  string filename;   // forinfile bloc
+  vector<string> strlist;
+  vector<string> lines;
+  vector<CommanderBloc *> 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-- */
+CommanderBloc::CommanderBloc(Commander* piac, CommanderBloc* par, string& kw, vector<string>& args)
+{
+_commander = 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") && (kw != "forinfile"))  return;
+if (!piac->CheckVarName(args[0])) return;
+varname = args[0];  
+
+//if (isalpha((int)args[1][0]) ) {  This is a foreach bloc with string list
+if (kw == "forinfile") {
+  filename = args[1];
+  typ = BT_ForeachLineInFile;
+  blkok = true;
+}
+else if (kw == "foreach" ) { // This is a foreach bloc with string list
+  if ( (args[1] == "(") && (args[args.size()-1] == ")") ) {
+    // foreach varname ( w1 w2 w3 ... ) 
+    for(int kk=2; kk<args.size()-1; kk++) strlist.push_back(args[kk]);
+  }
+  else {
+    // foreach varname WordVectorName 
+    if (!piac->GetVar(args[1], strlist))  return;
+  }
+  if (strlist.size() < 1)  return;
+  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-- */
+CommanderBloc::~CommanderBloc()
+{
+for(int k=0; k<blocs.size(); k++) delete blocs[k];
+}
+
+/* --Methode-- */
+void CommanderBloc::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-- */
+int CommanderBloc::Execute()
+{
+int k=0;
+char buff[32];
+int rcc = 0;
+
+int mxloop = _commander->GetMaxLoopLimit();
+
+if (typ == BT_ForeachLineInFile) {  // foreach line in file loop
+  ifstream is(filename.c_str());
+  char buff[256];
+  string line;
+  while (!is.eof()) {
+    /* Reza, Juin 2005 : Remplace par getline(istream, string) - plus sur
+       is.getline(buff, 256); line += buff;  */
+    rcc = 0;
+    line = "";
+    getline(is,line);
+    if (is.good() || is.eof()) {
+      rcc = ExecuteOnce(line);
+      if (rcc == CMD_BREAKEXE_RC)  return rcc;
+      else if (rcc == CMD_BREAK_RC)  break;
+    }
+  }
+}
+else if (typ == BT_ForeachList) {  // foreach string loop
+  for(k=0; k<strlist.size(); k++) {
+    rcc = ExecuteOnce(strlist[k]);
+    if (rcc == CMD_BREAKEXE_RC)  return rcc;
+    else if (rcc == CMD_BREAK_RC)  break; 
+  }  
+}
+else if (typ == BT_ForeachInt)  { // Integer loop
+  for(int i=i1; i<i2; i+=di) {
+    k++;
+    if ((mxloop>0) && (k > mxloop)) {
+      cout << ">>> Maximum CommanderBloc loop limit ("<< mxloop << ") -> break " << endl;
+      break;
+      }
+    sprintf(buff, "%d", i);
+    string lvv = buff;
+    rcc = ExecuteOnce(lvv);
+    if (rcc == CMD_BREAKEXE_RC)  return rcc;
+    else if (rcc == CMD_BREAK_RC)  break; 
+  }
+}
+else if (typ == BT_ForeachFloat)  { // float loop
+  for(double f=f1; f<f2; f+=df) {
+    k++;
+    if ((mxloop>0) && (k > mxloop)) {
+      cout << ">>> Maximum CommanderBloc loop limit ("<< mxloop << ") -> break " << endl;
+      break;
+      }
+    sprintf(buff, "%g", f);
+    string lvv = buff;
+    rcc = ExecuteOnce(lvv);
+    if (rcc == CMD_BREAKEXE_RC)  return rcc;
+    else if (rcc == CMD_BREAK_RC)  break; 
+  }
+}
+return(rcc); 
+}
+
+/* --Methode-- */
+int CommanderBloc::ExecuteOnce(string& lvv)
+{
+  int kj=0;
+  int kk=0;
+  int rcc = 0;
+  _commander->SetVar(varname, lvv);
+  for(kj=0; kj<bloclineid.size(); kj++) {
+    rcc = 0;
+    kk = bloclineid[kj]; 
+    if (kk > 0)   
+      rcc = _commander->Interpret(lines[kk-1]);
+    else 
+      rcc = blocs[-kk-1]->Execute();
+    if (rcc == CMD_BREAKEXE_RC)  return (rcc);
+    if (rcc == CMD_BREAK_RC)  break;    
+  }
+  return rcc;
+}
+
+// ---------------------------------------------------------------
+//                  Classe CommanderScript 
+//   Definition et execution d'un script de Commander
+//   script : Une liste de commande Commander - Lors de l'execution, 
+//   les variables-argument $# $0 $1 sont definies. 
+// ---------------------------------------------------------------
+
+/*!
+  \internal 
+  \class SOPHYA::CommanderScript
+  \ingroup SysTools 
+  Class for internal use by class Commander to handle functions
+  or scripts
+*/
+
+class CommanderScript {
+public:
+  CommanderScript(Commander* piac, string const& name, string const& comm);
+  virtual ~CommanderScript();
+
+  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:
+  Commander* _commander;
+  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-- */
+CommanderScript::CommanderScript(Commander* piac, string const& name, 
+			   string const& comm)
+{
+_commander = piac;
+testlevel = looplevel = 0;
+scrdef = false;
+mName = name;
+if (!isalpha(name[0]))  fgok = false;
+else fgok = true;
+mComm = comm;
+}
+
+/* --Methode-- */
+CommanderScript::~CommanderScript()
+{
+}
+
+/* --Methode-- */
+void CommanderScript::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 CommanderScript::Execute(vector<string>& args)
+{
+  int rcc;
+  if (!CheckScript()) return(-1);
+  cout << " CommanderScript::Execute() - Executing script " << Name() << endl;
+  for(int k=0; k<lines.size(); k++) {
+    rcc = _commander->Interpret(lines[k]);
+    if ( (rcc == CMD_BREAKEXE_RC) || (rcc == CMD_RETURN_RC) ) break; 
+  }
+  return(rcc);
+}
+
+
+// ------------------------------------------------------------
+//         Classe CommandExeThr
+// ------------------------------------------------------------
+/*!
+  \internal
+  \class SOPHYA::CommandExeThr
+  \ingroup SysTools 
+  Class for internal use by class Commander for command execution in separate threads.
+  The command execution is carried in method run() which has its own exception handling bloc.
+*/
+class CommandExeThr :  public ZThread  {
+public:
+                 CommandExeThr(uint_8 id, CmdExecutor * cmdex, string& keyw, 
+			       vector<string>& args, string& toks);
+  virtual void   run();
+  inline  uint_8 Id() { return _id; }
+  inline  bool   IfDone() { return _fgdone; }
+  inline  string& Tokens() { return  _toks; }
+  inline  string& Keyword() { return  _keyw; }
+protected:
+  uint_8 _id;
+  CmdExecutor * _cmdex;
+  string _keyw, _toks;
+  vector<string> _args;
+  bool _fgdone;
+};
+
+/* --Methode-- */
+CommandExeThr::CommandExeThr(uint_8 id, CmdExecutor * cmdex, string& keyw, 
+			       vector<string>& args, string& toks)
+{
+  _id = id;
+  _cmdex = cmdex;
+  _keyw = keyw;
+  _args = args;
+  _args.erase(_args.end()-1);
+  _toks = toks;
+  for(size_t k=_toks.size()-1; k>0; k--) 
+    if (_toks[k] == '&') { _toks[k] = ' '; break; }
+  _fgdone = false;
+}
+
+/* --Methode-- */
+void CommandExeThr::run()
+{
+  int rc = 0;
+  try {
+    rc = _cmdex->Execute(_keyw, _args, _toks);
+  }
+  catch (PThrowable& exc) {
+    cout << "CommandExeThr::run() Catched Exception Msg()= " 
+	 << exc.Msg() << endl;
+    rc = -77;
+  }
+  catch (std::exception& sex) {
+    cout << "CommandExeThr::run() Catched std::exception what()= " 
+	 << sex.what() << endl;
+    rc = -78;
+  }
+  catch (...) {
+    cout << "CommandExeThr::run() Catched unknown (...) exception " << endl; 
+    rc = -79;
+  }
+  _fgdone = true;
+  setRC(rc);
+}
+
+// ------------------------------------------------------------
+//         Classe Commander
+// ------------------------------------------------------------
+typedef void (* DlModuleInitEndFunction) ();
+
+/*!
+  \class Commander
+  \ingroup SysTools
+  \brief Simple command interpreter
+
+  This Simple command interpreter with c-shell like syntax 
+  can be used to add scripting capabilities
+  to applications. 
+
+  Although the interpreter has many limitations compared to 
+  c-shell, or Tcl , it provides some interesting possibilities:
+
+  - Extended arithmetic operations (c-like and RPN)
+  - Simple and vector variables
+  - Script definition 
+  - Command execution in separate threads
+  - Dynamic Load 
+
+  \sa CmdExecutor CExpressionEvaluator RPNExpressionEvaluator
+
+  Usage example:
+  \code
+  #include "commander.h"
+  ...
+  Commander cmd;
+  char* ss[3] = {"foreach f ( AA bbb CCCC ddddd )", "echo $f" , "end"};
+  for(int k=0; k<3; k++) {
+    string line = ss[k];
+    cmd.Interpret(line);
+  }
+  \endcode
+*/
+
+#define _MAGENTA_ 1
+
+static Commander* cur_commander = NULL;
+/* --Methode-- */
+/*! 
+  \brief Constructor. Initializes variable list and copies \c history.pic to \c hisold.pic
+  if \b fgsigstop == true , calls ZThread::ActivateExitOnSignal()
+*/
+Commander::Commander(bool fgsigzt)
+{
+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> ";
+SetCurrentPrompt(spromptmul);
+SetDefaultPrompt(spromptmul);
+curscript = NULL;
+
+_xstatus = 0;
+ _retstr = "";
+
+// Controle du flot d'execution 
+ fgexebrk = false;
+
+CmdBlks.push(NULL);
+list<char> xtx;
+TestsStack.push(xtx);
+curtestresult = true;
+
+// Pour la numerotation et l'identification des threads
+ThrId = 0;
+
+// Numero de help-groupe courant - Le premier groupe ajoute aura un gid = 1
+// gid = 0 n'existe pas : c'est le groupe de toutes les commandes
+cmdgrpid = 0;
+
+string grp = "Commander";
+string gdesc = "Basic (generic) interpreter (class SOPHYA::Commander) builtin commands";
+AddHelpGroup(grp, gdesc);
+
+string kw = "Commander";
+string usage;
+usage = ">>> (Commander) Interpreter's keywords : \n";
+usage += "  > set varname string     # To set a variable, $varname \n";
+usage += "  > unset varname          # clear variable definition \n";
+usage += "  > rpneval varname RPNExpression  # Reverse Polish Notation evaluation \n";
+usage += "  > varname = ArithmeticExpression # C-like Expression evaluation   \n"; 
+usage += "  > varname = 'String'     # Set variable vname  \n"; 
+usage += "  > var2words varname wordvarname [sep]    # to break varname into words  \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 += "  > 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 += "  > forinfile varname FileName  # Loop over lines in file \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 += "  > thrlist       # List of command execution threads (& as the last character) \n";
+usage += "  > clearthrlist  # Removes finished threads from the list  \n";
+usage += "  > killthr Id    # Try to stop a given thread (ThrId=id) by sending SIGUSR1 \n";
+usage += "  > cancelthr Id  # Try to cancel a given thread (ThrId=id)  \n";
+usage += "  > waitthr       # Waits until all active threads have finished (join()) \n";
+usage += "  > exec filename # Execute commands from file \n";
+usage += "  > help <command_name>  # <command_name> usage info \n";   
+usage += "  > sleep nsec  # sleep nsec seconds \n";   
+usage += "  > readstdin varname      # reads a line from stdin into $varname \n"; 
+usage += "  > timingon  timingoff traceon  traceoff \n";
+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";
+RegisterCommand(kw, usage, NULL, grp);
+
+kw = "CExpEvaluator";
+usage  = "> Evaluation of C-like expression (used in V = C-like-Expression) \n";
+usage += "   >>> Arithmetic operators, parenthesis ( + - * / ) \n";
+usage += "   >>> Functions : sqrt fabs floor hypot \n";
+usage += "   ...  exp log log10 pow  ; sinh cosh tanh \n";
+usage += "   ...  sin cos tan asin acos atan atan2  \n";
+usage += "   ...  rand01()  randpm1() gaurand() \n";
+usage += "   >>> Constants : Pi = M_PI E = M_E \n";
+usage += "   Example: x = 5.*(2.+sin(0.3*Pi))";
+RegisterCommand(kw, usage, NULL, 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";
+RegisterCommand(kw, usage, NULL, grp);
+
+
+AddInterpreter(this);
+curcmdi = this;
+if (fgsigzt) ZThread::ActivateExitOnSignal(SIGUSR1);
+}
+
+/* --Methode-- */
+Commander::~Commander()
+{
+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; 
+ 
+if (cur_commander == this)  cur_commander = NULL;
+}
+
+/* --Methode-- */
+Commander* Commander::GetInterpreter()
+{
+return(cur_commander);
+}
+
+/* --Methode-- */
+//! Returns the string \c Commander as the interpreter's name.
+string Commander::Name()
+{
+return("Commander");
+}
+
+/* --Methode-- */
+//! Add the \b grp help group with description \b desc. 
+void Commander::AddHelpGroup(string& grp, string& desc)
+{
+  int gid; 
+  CheckHelpGrp(grp, gid, desc);
+}
+
+/* --Methode-- */
+/*! 
+  \brief Register a command executor associated with a given keyword.
+  \param keyw : keyword identifying the command
+  \param usage : the command help and usage information
+  \param ce : CmdExecutor pointer for this a command. The same object can be registered
+  multiple time for different commands.
+  \param grp : The help group corresponding to this command.
+*/
+void Commander::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, string& grp)
+{
+if (!ce) { 
+  RegisterHelp(keyw, usage, grp);
+  return;
+  }
+int gid;
+CheckHelpGrp(grp,gid);
+cmdex cme;
+cme.group = gid;
+cme.us = usage;
+cme.cex = ce;
+cmdexmap[keyw] = cme;
+}
+
+/* --Methode-- */
+/*! 
+  \brief Register a help text.
+  \param keyw : help keyword
+  \param usage : help text
+  \param grp : help group
+*/
+void Commander::RegisterHelp(string& keyw, string& usage, string& grp)
+{
+int gid;
+CheckHelpGrp(grp,gid);
+cmdex cme;
+cme.group = gid;
+cme.us = usage;
+cme.cex = NULL;
+helpexmap[keyw] = cme;
+}
+
+/* --Methode-- */
+bool Commander::CheckHelpGrp(string& grp, int& gid, string& desc)
+{
+gid = 0;
+CmdHGroup::iterator it = cmdhgrp.find(grp);
+if (it == cmdhgrp.end()) {
+  cmdgrpid++;  gid = cmdgrpid;
+  hgrpst hgs;  hgs.gid = gid;  hgs.desc = desc;
+  cmdhgrp[grp] = hgs;
+  return true;
+  }
+else { 
+  if (desc.length() > 0)  (*it).second.desc = desc; 
+  gid = (*it).second.gid;
+  return false;
+}
+}
+
+
+/* --Methode-- */
+/*!
+  \brief  Dynamic loader for modules
+
+  A module is a shared library extending the application functionalities.
+  Typically, a module adds new commands to the interpreter. Once loaded,
+  the module is activated (initialized) by calling a function with the 
+  name \b modulename_init . This function should be declared extern C
+  to avoid C++ name mangling. A cleanup function \b modulename_end
+  is called by the Commander destructor.
+
+  \param fnameso : Shared library name containing the module functions
+  and classes.
+  \param name : Module name. This string is used to form module 
+  initializer and cleanup function name \c name_init \c name_end
+*/
+void Commander::LoadModule(string& fnameso, string& name)
+{
+PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
+if (dynlink == NULL) {
+  cerr << "Commander/LoadModule_Error: Pb opening SO " << fnameso << endl;
+  return;
+  }
+string fname = name + "_init";
+DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
+if (!finit) {
+  cerr << "Commander/LoadModule_Error: Pb linking " << fname << endl;
+  return;
+  }
+cout << "Commander/LoadModule_Info: Initialisation module" << name 
+     << "  " << fname << "() ..." << endl;
+finit();
+modmap[name] = dynlink;
+return;
+}
+
+/* --Methode-- */
+//! Declare a new interpreter
+void Commander::AddInterpreter(CmdInterpreter * cl)
+{
+if (!cl) return;
+interpmap[cl->Name()] = cl;}
+
+/* --Methode-- */
+//! Select an interpreter by its name as the current interpreter. 
+void Commander::SelInterpreter(string& name)
+{
+InterpMap::iterator it = interpmap.find(name);
+if (it == interpmap.end())   return;
+curcmdi = (*it).second;
+}
+
+
+
+/* Fonction */
+static string GetStringFrStdin(Commander* piac)
+{
+char buff[128];
+fgets(buff, 128, stdin);
+buff[127] = '\0';
+return((string)buff);
+}
+
+/* --Methode-- */
+/*!
+  \brief Method which has to be invoked to interpret a given command line or string.
+*/
+int Commander::Interpret(string& s)
+{
+int rc = 0;
+ScriptList::iterator sit;
+
+// Si le flag d'arret d'execution a ete positionne on returne avec le code
+//  de BREAKEXECUTION
+if (fgexebrk) { 
+  cout << " ===> Commander::Interpret() - STOP Execution (CMD_BREAKEXE_RC)" << endl; 
+  fgexebrk = false; return CMD_BREAKEXE_RC; 
+}
+
+// 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 (lnb >= l) return(0); // il n'y a que des blancs
+if (s[lnb] == '\\' ) { // Lignes suite ...
+  mulinecmd += s.substr(0,lnb);
+  if (!mulinefg) {
+    spromptmul = GetCurrentPrompt();
+    SetCurrentPrompt("...? ");
+    mulinefg = true;
+  }
+  return(0);
+}
+
+if (mulinefg) {  // Il y avait des lignes suite
+  s = mulinecmd + s;
+  l = s.length();
+  mulinecmd = "";
+  mulinefg = false;
+  SetCurrentPrompt(spromptmul);
+}
+
+// Removing leading blanks
+size_t p,q;
+
+// On enleve le dernier caractere, si celui-ci est \n 
+if (s[l-1] == '\n') s[l-1] = '\0';
+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 << "Commander::Interpret()/syntax error near end else endif endscript \n"
+	 << "line: " << s << endl;
+    _xstatus = 91;
+    return(91);
+  }
+}
+
+// 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 << "Commander::Interpret() replacing script " 
+	     << curscript->Name() << endl;
+	CommanderScript* scr = mScripts[curscript->Name()];
+	mScripts.erase(sit);
+	delete scr;
+      }
+      cout << "Commander::Interpret() Script " << curscript->Name() 
+	   << " defined successfully" << endl;
+      mScripts[curscript->Name()] = curscript;
+      SetCurrentPrompt("Cmd> ");
+      curscript = NULL;
+      _xstatus = 0;
+      return(0);
+    }
+    else {
+      cout << "Commander::Interpret() Error in Script " << curscript->Name() 
+	   << " definition " << endl;
+      SetCurrentPrompt("Cmd> ");
+      curscript = NULL;
+      _xstatus = 92;
+      return(92);
+    }
+  }
+  else curscript->AddLine(s, kw);
+  _xstatus = 0;
+  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") || (kw == "forinfile") ) felevel++;
+  else if (kw == "end") felevel--;
+
+  int rcbex = 0;
+  if (felevel == 0) { // Il faut executer le bloc
+    CommanderBloc* curb = CmdBlks.top();
+    CmdBlks.top() = curb->Parent();
+    SetCurrentPrompt("Cmd> ");
+    if (!curb->CheckBloc()) {
+      cerr << "Commander::Interpret()/syntax error - unbalenced if ... endif"
+	   << " within for/foreach/forinfile bloc ! " << endl;
+      delete curb;
+      _xstatus = 93;
+      return(93);  
+    }
+       //       cout << " *DBG* Executing bloc " << endl;
+    bool ohv = histon;
+    histon = false;
+    if (curtestresult) { 
+      // We push also CommanderBloc and testresult on the stack
+      CmdBlks.push(NULL);
+      list<char> xtx;
+      TestsStack.push(xtx);
+      rcbex = curb->Execute();
+      // And CommanderBloc and TestResult from the corresponding stacks
+      PopStack(false);
+    }
+    SetCurrentPrompt(defprompt);
+    delete curb;
+    histon = ohv;
+  }
+  else CmdBlks.top()->AddLine(s, kw); 
+  _xstatus = rcbex;
+  return(rcbex);
+}
+else if (kw == "end") {
+  cerr << "Commander::Interpret()/syntax error - end outside for/foreach/forinfile bloc \n"
+       << "line: " << s << endl;
+  _xstatus = 94;
+  return(94);  
+}
+
+// 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 << "Commander::Interpret()/syntax error - multiple else in if bloc \n"
+	   << "line: " << s << endl;
+      _xstatus = 95;
+      return(95);
+    }
+    else { 
+      const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
+      if ((*tresit)&1)  curtestresult = false;
+      SetCurrentPrompt(npr);
+      (*tresit) |= 2;
+      _xstatus = 0;
+      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;
+    SetCurrentPrompt(npr);
+    _xstatus = 0;
+    return(0);
+  }
+} 
+else if ((kw == "else") || (kw == "endif")) {
+  cerr << "Commander::Interpret()/syntax error - else,endif outside if bloc \n"
+       << "line: " << s << endl;
+  _xstatus = 91;
+  return(91);  
+}
+
+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"))  { 
+  _xstatus = 0;
+  return(0);
+}
+
+
+// Les mots cles break et return peuvent de sortir de boucles/scripts/execfile
+if (kw == "break") return CMD_BREAK_RC;
+else if (kw == "return")  { 
+  _retstr = toks; 
+  return CMD_RETURN_RC;
+}
+
+// Nous ne sommes donc pas dans un bloc ....  Substitution de variables
+string s2;
+int rcs ;
+
+rcs = SubstituteVars(s, s2);
+if (rcs) { 
+  cerr << "Commander::Interpret()/syntax error in SubstituteVars() \n"
+       << "line: " << s << endl;
+  _xstatus = 99;
+  return(99);
+}
+// >>>> Separating keyword and tokens 
+vector<string> tokens;
+vector<bool> qottoks;
+/* decoupage en mots */
+LineToWords(s2, kw, tokens, qottoks, toks, true);
+
+// Si c'est un for/foreach, on cree un nouveau bloc
+if ((kw == "foreach") || (kw == "for") || (kw == "forinfile") ) {
+  //     cout << " *DBG* We got a foreach... " << endl;
+  CommanderBloc* bloc = new CommanderBloc(this, CmdBlks.top(), kw, tokens);
+  if (!bloc->CheckOK()) {
+    cerr << "Commander::Interpret() for/foreach syntax Error ! " << endl;
+    delete bloc;
+    _xstatus = 91;
+    return(91);
+    }
+  felevel++;
+  if (CmdBlks.top())  CmdBlks.top()->AddBloc(bloc);
+  else  SetCurrentPrompt("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 << "Commander::Interpret() if syntax Error ! " << "line: " << s << endl;
+    _xstatus = 91;
+    return(91);
+  }
+  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> ";
+  SetCurrentPrompt(npr);
+}
+else if ((tokens.size() > 0) && (tokens[0] == "=")) {  
+  // x = Expression 
+  if (qottoks[1]) {  // decodage sous forme de chaine 
+    SetVariable(kw, tokens[1]);    
+  }
+  else {
+    try {
+      double res = 0.;
+      if (tokens.size() > 2) {
+	string sex = tokens[1];
+	for(int js=2; js<tokens.size(); js++)  sex += tokens[js];
+	CExpressionEvaluator cex(sex);
+	res = cex.Value();
+      }
+      else {
+	CExpressionEvaluator cex(tokens[1]);
+	res = cex.Value();
+      }
+      char cbuff[64];
+      sprintf(cbuff,"%g",res);
+      string vv = cbuff;
+      SetVariable(kw, vv);
+    }
+    catch (CExprException& cexerr) {
+      cerr << "Commander::Interpret() evaluation Error : \n " << "line: " << s 
+	   << " \n Msg=" << cexerr.Msg()  << endl;
+      _xstatus = 98;
+      return(98);
+    }
+  }
+}
+else if (kw == "defscript") {  // definition de script
+  if (tokens.size() > 0) {
+    if (tokens.size() < 2)  tokens.push_back("");
+    curscript = new CommanderScript(this, tokens[0], tokens[1]);
+    SetCurrentPrompt("Script...> ");
+    return(0);
+  }
+  else {
+    cerr << "Commander::Interpret() No script name in defscript" << "line: " << s << endl;
+    _xstatus = 91;
+    return(91);
+  }
+}
+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);
+  _xstatus = rc;
+  return(rc);
+}  
+// cout << "Commander::Do() DBG  KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
+//  for(int ii=0; ii<tokens.size(); ii++)
+//  cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
+
+return(0);
+}
+
+//! Can be called asynchronously (from a separate thread) to break (halt) execution (in loops, scripts ...) 
+void  Commander::StopExecution()
+{
+  fgexebrk = true;
+}
+
+
+/* --Methode-- */
+int Commander::LineToWords(string& line, string& kw, vector<string>& tokens, 
+			   vector<bool>& qottoks, 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)  {
+  bool swq = false;  // true -> chaine delimite par ' ou " 
+  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 << "Commander::LineToWords/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
+      return(-1);
+    }
+    p++;  swq = true;  
+  }
+  else {
+    q = toks.find_first_of(" \t",p); // la fin du token;
+  }
+  string token = toks.substr(p,q-p);
+  tokens.push_back(token); 
+  qottoks.push_back(swq);
+  nw++;
+  }
+
+return(nw);
+}
+
+/* --Methode-- */
+int Commander::SubstituteVars(string & s, string & s2)
+//  Variable substitution  
+{
+
+int iarr = -1;  // index d'element de tableau
+size_t p,q,q2,q3,l;
+bool fgvarapp = false;  //  Si true, VarApp en priorite 
+
+s2="";
+p = 0;
+l = s.length();
+string vn, vv;
+while (p < l) {
+  iarr = -1;
+  fgvarapp = false; 
+  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++;
+    fgvarapp = true;
+  }
+  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 (!Var2Str(vn, vv)) return(5);
+    vn = vv;
+    q2++;
+    }
+  else { 
+    if (s[q+1] == '#' ) q3 = q+2; // Variable in the form $#varname  
+    else q3 = q+1;
+    q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'<>^%=#@\\",q3); 
+    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 (!Var2Str(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 (fgvarapp) {
+    if (!GetVarApp(vn, vv))
+      if (!Var2Str(vn, vv)) return(5);
+    s2 += (s.substr(p, q-p) + vv);
+    p = q2;    
+  }
+  else if (iarr < 0) {
+    if (!Var2Str(vn, vv)) return(5);
+    s2 += (s.substr(p, q-p) + vv);
+    p = q2;
+  }
+  else {
+    if (! Var2Str(vn, iarr, vv) ) { 
+      cerr << " Substitution error - word index out of range in "
+	   << "$varname[iarr] : $" << vn << "[" << iarr <<"]" << endl;
+      return(4);
+    }
+    else s2 += (s.substr(p, q-p) + vv);
+    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 Commander::Var2Str(string const & vn, string & vv)
+{
+if (vn.length() < 1) {
+  cerr << " Commander::Var2Str/Error: length(varname=" << vn << ")<1 !" << endl;
+  vv = "";    return(false);
+}
+// Variable de type $# $0 $1 ... (argument de .pic ou de script)
+int ka = 0;
+char buff[32];
+  
+if (vn == "#") {
+  if (ArgsStack.empty()) {
+    cerr << " Commander::Var2Str/Error: ArgsStack empty ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = "";  return(false);
+  }
+  char buff[32];
+  long an = ArgsStack.top().size();
+  if (an > 0) an--;  // Pour se conformer a l'usage de csh : Nb args sans le $0 
+  sprintf(buff,"%ld", an);
+  vv = buff;  return(true);
+}
+else if (vn == "*") {
+  if (ArgsStack.empty()) {
+    cerr << " Commander::Var2Str/Error: ArgsStack empty ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = "";  return(false);
+  }
+  vv = ArgsStack.top()[0];
+  for(int ssk=1; ssk<ArgsStack.top().size(); ssk++)  vv += ArgsStack.top()[ssk];
+  return(true);
+}
+else if (ctoi(vn.c_str(), &ka) > 0) {  // $0 $1 $2 ...
+  if (ArgsStack.empty()) {
+    cerr << " Commander::Var2Str/Error: ArgsStack empty ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = ""; return(false);
+  }
+  if ( (ka < 0) || (ka >= ArgsStack.top().size()) ) {
+    cerr << " Commander::Var2Str/Error: ArgsStack index <0 or >=args.size()  ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = ""; return(false);
+  }
+  vv = ArgsStack.top()[ka];  return(true);
+}
+else if (vn[0] == '#') {  // Variable de type $#vname --> size(vname) 
+  CmdVarList::iterator it = variables.find(vn.substr(1));
+  if (it == variables.end()) {
+    cerr << " Commander::Var2Str/Error #vname Undefined variable " 
+	 << vn << " ! " << endl;
+    vv = "";  return(false);
+  }
+  sprintf(buff,"%d", (int)(*it).second.size());
+  vv = buff; return(true);
+} 
+else if (vn == "status") {
+  sprintf(buff,"%d", _xstatus);
+  vv = buff;
+  return true;
+}
+else if ((vn == "retstr") || (vn == "retval")) {
+  vv = _retstr;
+  return true;
+}
+else {  // Variable de l'interpreteur, ou de l'environnement application , env. global
+  if (GetVar(vn, vv))  return true;
+  else if (GetVarApp(vn, vv))  return true;
+  else if (GetVarEnv(vn, vv))  return true;
+  else { 
+    cerr << " Commander::Var2Str/Error  Undefined variable " 
+	 << vn << " ! " << endl;
+    vv = "";  return false;
+  }
+}
+
+return false;
+}
+
+/* --Methode-- */
+bool Commander::SetVariable(string const & vn, string const & vv)
+{
+  // On verifie si le nom est de type vname[idx]
+  size_t p,q,l;
+  l = vn.length();
+  p = vn.find('[');
+  if (p < l) {
+    q = vn.find(']');
+    if (q != (l-1)) {
+      cout << "Commander::Str2Var/SetVar() - Bad varname with []: " 
+	   << vn << endl;
+      return false;
+    }
+    string vna = vn.substr(0, p);
+    string sia = vn.substr(p+1, q-(p+1));
+    if (isalpha(sia[0])) {
+      string sia2;
+      if (!Var2Str(sia, sia2) || (sia2.length() < 1)) {
+	cerr << "Commander::Str2Var/SetVar() Syntax error- varname[index]:"  
+	     << vn << endl;
+	return false;	  
+      }
+      sia = sia2;
+    }
+    int iarr;
+    int rcdia = ctoi(sia.c_str(), &iarr);
+    if (rcdia < 0) {
+      cerr << "Commander::Str2Var/SetVar() Syntax error- varname[iarr]: " 
+	   << vn << endl;
+      return false;
+    }
+    return SetVar(vna, iarr, vv);
+  }
+  else { 
+    if (vn == "status") { 
+      _xstatus = atoi(vv.c_str());
+      return true;
+    }
+    else if (vn == "retstr") { 
+      _retstr = vv;
+      return true;
+    }
+    else return SetVar(vn, vv);
+  }
+}
+
+/* --Methode-- */
+bool Commander::GetVar(string const & vn, string & vv)
+{
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end()) {
+    vv = "";
+    return false;
+  }
+  vv = (*it).second[0]; 
+  if ((*it).second.size() > 1) {   
+    for(int k=1; k<(*it).second.size(); k++) {
+      vv += ' ';  vv += (*it).second[k];
+    }
+  }
+  return true;
+}
+
+/* --Methode-- */
+bool Commander::GetVar(string const & vn, int idx, string & vv)
+{
+  vv = "";
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end())  return false;
+  if ((idx < 0) || (idx > (*it).second.size()-1))
+    return false;
+  vv = (*it).second[idx];
+  return true;
+}
+
+/* --Methode-- */
+bool Commander::GetVar(string const & vn, vector<string> & vv)
+{
+  vv.clear();
+  //  vv.erase(vv.begin(),vv.end());
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end())  return false;
+  vv = (*it).second;
+  return true;
+}
+
+/* --Methode-- */
+bool Commander::SetVar(string const & vn, string const & val)
+{
+  if ( !CheckVarName(vn) )  {
+    cerr << "Commander::SetVar( " << vn << " ...) Bad VarName " << endl;
+    return(false);
+  }
+  bool fg = false;
+  vector<string> nouv;
+  nouv.push_back(val);
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end())  variables[vn] = nouv;
+  else { 
+    (*it).second = nouv;
+    fg = true;
+  }
+  return fg;
+}
+
+/* --Methode-- */
+bool Commander::SetVar(string const & vn, int idx, string const & val)
+{
+  if ( !CheckVarName(vn) )  {
+    cerr << "Commander::SetVar( " << vn << " ,idx, ...) Bad VarName " << endl;
+    return(false);
+  }
+  if ((vn == "status") || (vn == "retstr")) {
+    cerr << "Commander::SetVar(vn,idx,val) ERROR - special var status/retstr " 
+	 << endl;
+    return(false);
+  }
+  if (idx < 0) {
+    cout << "Commander::SetVar(vn," << idx << ",...) Error idx < 0" << endl;
+    return(false);
+  }
+  bool fg = false;
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end()) {
+    vector<string> nouv;
+    for(int j=0; j<idx; j++)  nouv.push_back("");
+    nouv.push_back(val);
+    variables[vn] = nouv;
+  }
+  else { 
+    if (idx >= (*it).second.size())
+      for(int j=(*it).second.size(); j<=idx; j++)  (*it).second.push_back("");
+    (*it).second[idx] = val;
+    fg = true;
+  }
+  return fg;
+}
+
+/* --Methode-- */
+bool Commander::SetVar(string const & vn, vector<string> const & val)
+{
+  if ( !CheckVarName(vn) )  {
+    cerr << "Commander::SetVar( " << vn << " ...) Bad VarName " << endl;
+    return(false);
+  }
+  if ((vn == "status") || (vn == "retstr")) {
+    cerr << "Commander::SetVar(vn, vector<string>) ERROR - special var status/retstr " 
+	 << endl;
+    return(false);
+  }
+  bool fg = false;
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end())  variables[vn] = val;
+  else { 
+    (*it).second = val;
+    fg = true;
+  }
+  return fg;
+}
+
+/* --Methode-- */
+bool Commander::CheckVarName(string const & vn)
+{
+  size_t l,k;
+  l = vn.length();
+  if (l < 1)  return false;
+  if (!isalpha(vn[0]))  return false;
+  for(k=1; k<l; k++) 
+    if ((!isalnum(vn[k])) && (vn[k] != '_'))  return false;
+  return true;  
+}
+
+/* --Methode-- */
+bool Commander::DeleteVar(string const & vn)
+{
+  CmdVarList::iterator it = variables.find(vn);
+  if (it == variables.end())  { 
+    cerr << "Commander::DeleteVar() Var " << vn << " undefined!" << endl;
+    return false;
+  }
+  variables.erase(it);
+  return true;
+}
+
+/* --Methode-- */
+void Commander::ListVar()
+{
+  cout << " ---- Commander::ListVar() List of defined variables ---- " 
+       << endl;
+  CmdVarList::iterator it;
+  for(it = variables.begin(); it != variables.end(); it++) {
+    string vn = (*it).first;  
+    int vs = (*it).second.size();
+    cout << vn << " -> Size= " << vs  << endl;
+  }
+  cout << "---------------------------------------------------------- " 
+       << endl;
+}
+
+/* --Methode-- */
+bool Commander::GetVarApp(string const & vn, string & vv)
+{
+  vv = "";
+  //  cout << " Commander::GetVarApp() Not available ! " << endl;
+  return false;
+}
+
+/* --Methode-- */
+bool Commander::SetVarApp(string const & vn, string const & vv)
+{
+  //  cout << " Commander::SetVarApp() Not available ! " << endl;
+  return false;  
+}
+
+/* --Methode-- */
+bool Commander::DeleteVarApp(string const & vn)
+{
+  //  cout << " Commander::DeleteVarApp() Not available ! " << endl;
+  return false;  
+}
+
+/* --Methode-- */
+void Commander::ListVarApp()
+{
+  //  cout << " Commander::ListVarApp() Not available ! " << endl;
+  return;  
+}
+
+
+/* --Methode-- */
+bool Commander::GetVarEnv(string const & vn, string & vv)
+{
+  char* vev = getenv(vn.c_str());
+  if (vev) {
+    vv = vev;
+    return true;
+  }
+  else { 
+    vv = "";
+    return false;
+  }
+}
+
+/* --Methode-- */
+bool Commander::SetVarEnv(string const & vn, string const & vv)
+{
+  string pev = vn;
+  pev += '=';
+  pev += vv;
+// if defined(Linux) || defined(AIX)
+// Reza - 28/04/2004 
+// putenv de Linux ne declare pas la variable char *string const
+// On ne doit meme pas utiliser une variable automatique  
+// J'alloue donc un nouveau tableau - mais qui va le liberer ?
+// Idem AIX , Reza Dec 2005 
+// Pb apparu avec g++ 4 sur darwin (Mac) - Jan 2006
+// Je fais copie pour tout le monde
+  char* bev = new char[pev.size()+1];
+  strcpy(bev, pev.c_str());
+  if (putenv(bev) == 0)  return true;  
+// else
+//  if (putenv(pev.c_str()) == 0)  return true;
+// endif
+  else return false;  
+}
+
+/* --Methode-- */
+bool Commander::DeleteVarEnv(string const & vn)
+{
+  //  cout << " Commander::DeleteVarEnv() Not available ! " << endl;
+  return false;  
+}
+
+/* --Methode-- */
+void Commander::ListVarEnv()
+{
+  cout << " Commander::ListVarEnv() Not available ! " << endl;
+  return;  
+}
+
+
+/* --Methode-- */
+string Commander::GetTmpDir()
+{
+  return("/tmp");
+}
+
+/* --Methode-- */
+void Commander::SetCurrentPrompt(const char* pr)
+{
+  curprompt = pr;
+}
+
+/* --Methode-- */
+void Commander::ShowMessage(const char * msg, int att)
+{
+  cout << msg ;
+}
+
+
+
+/* --Methode-- */
+int Commander::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);
+}
+
+  
+/* --Methode-- */
+int Commander::EvalRPNExpr(vector<string> & args, string & line)
+{
+  // A virer - Reza 15/03/2004 
+  return(0);
+}
+
+/* --Methode-- */
+void Commander::PushStack(vector<string>& args)
+{
+  // We push the argument list (args) on the stack
+  ArgsStack.push(args);
+  // We push also CommanderBloc and testresult on the stack
+  CmdBlks.push(NULL);
+  list<char> xtx;
+  TestsStack.push(xtx);
+
+}
+
+/* --Methode-- */
+void Commander::PopStack(bool psta)
+{
+  // We remove the argument list (args) from the stack
+  if (psta) ArgsStack.pop();
+  // And CommanderBloc and TestResult from the corresponding stacks
+  CommanderBloc* curb = CmdBlks.top();
+  while (curb != NULL) {
+    CommanderBloc* parb = curb->Parent();
+    delete curb;  curb = parb;
+  }
+  CmdBlks.pop();
+  TestsStack.pop();
+}
+
+/* --Methode-- */
+int Commander::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
+{
+int rc = 0;
+
+// >>>>>>>>>>> Commande d'interpreteur
+if (kw == "help") {
+  if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
+  else {  
+    string kwh = "Commander";
+    cout << GetUsage(kwh) << endl;
+    }
+  }
+else if (kw == "sleep") {
+  if (tokens.size() < 1) { 
+    cout << "Commander::Interpret() Usage: sleep nsec " << endl;  
+    return(1); 
+  }
+  int nsec = atoi(tokens[0].c_str());
+  cout << "Commander::Interpret() sleep " << nsec << " seconds" << endl;
+  sleep(nsec);
+}
+
+else if (kw == "set") {
+  if (tokens.size() < 2) { 
+    cout << "Commander::Interpret() Usage: set varname value or set vecvar ( w1 w2 ... ) " << endl;  
+    return(1); 
+  }
+  
+  if (tokens.size() == 2) 
+    SetVariable(tokens[0], tokens[1]);
+  else {
+    if ( (tokens[1] != "(") || (tokens[tokens.size()-1] != ")") ) {
+    cout << "Commander::Interpret() Usage: set vecvar ( w1 w2 ... ) " << endl;  
+    return(1); 
+    }
+    string vname = tokens[0];
+    vector<string>::iterator vit;
+    vit = tokens.begin(); tokens.erase(vit);
+    vit = tokens.begin(); tokens.erase(vit);
+    tokens.pop_back();
+    SetVar(vname, tokens);
+  }
+  return 0;
+}
+else if (kw == "var2words") {
+  if (tokens.size() < 2) { 
+    cout << "Commander::Interpret() Usage: var2words varname wordvarname [sep]" << endl;  
+    return(1); 
+  }
+  char sep = ' ';
+  if (tokens.size() > 2) sep = tokens[2][0];
+  string vv;
+  if (!GetVar(tokens[0], vv)) {
+    cout << "Commander::Interpret() var2words/Error No variable with name " << tokens[0] << endl;  
+    return 2;
+  }
+  vector<string> vs;
+  FillVStringFrString(vv, vs, sep);
+  SetVar(tokens[1], vs); 
+}
+else if (kw == "alias") {
+  if (tokens.size() < 2) { cout << "Commander::Interpret() Usage: alias aliasname string" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "Commander::Interpret()/Error alias name should start with alphabetic" << endl;
+    return(1);
+  }
+  string xx = tokens[1];
+  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk]);
+  mAliases[tokens[0]] = xx;
+}
+
+else if ( (kw == "unset") || (kw == "clearvar") ) {
+  if (tokens.size() < 1) { 
+    cout << "Commander::Interpret() Usage: unset/clearvar varname" << endl;  
+    return(1); 
+  }
+  else DeleteVar(tokens[0]);
+}
+// Evaluation d'expression en notation polonaise inverse
+else if (kw == "rpneval") {
+  try {
+    RPNExpressionEvaluator rpn(tokens, 1);
+    double res = rpn.Value();
+    char cbuff[64];
+    sprintf(cbuff,"%g",res);
+    string vv = cbuff;
+    SetVariable(tokens[0],vv);
+    return 0;
+  }
+  catch (RPNExprException& rpnerr) {
+    cerr << " rpneval: Syntax error - Msg=" << rpnerr.Msg() 
+	 << " \n Line=" << toks << endl;
+    return 98;
+  }
+}
+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 << "Commander::Interpret() Usage: echo2file filename [string ] " << endl;  
+    return(1);
+  }
+  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 << "Commander::Interpret() Usage: readstdin varname" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "Commander::Interpret()/Error Variable name should start with alphabetic" << endl;
+    return(0);
+    }
+  ShowMessage(">>> Reading From StdIn \n", _MAGENTA_);
+  cout << tokens[0] << " ? " << endl;
+  SetVar(tokens[0], GetStringFrStdin(this) );
+  }
+
+else if (kw == "listvars" || kw == "listvar") ListVar();
+else if (kw == "listalias") {
+  cout << "Commander::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 << "---- Commander::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 << "---- Commander::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 << "Commander::Interpret() Usage: clearscript scriptname" << endl;  
+    return(0); 
+  }
+  ScriptList::iterator sit = mScripts.find(tokens[0]);
+  if (sit == mScripts.end()) {
+    cout << "Commander::Interpret() No script with name" << tokens[0] << endl;
+    return(0);
+  }
+  else {
+    delete (*sit).second;
+    mScripts.erase(sit);
+    cout << "Commander::Interpret() script " << tokens[0] << " cleared" << endl;
+    return(0);
+  }
+}
+//---------------------------------------------
+//---   Commandes de gestion des threads ------
+//---------------------------------------------
+else if (kw == "thrlist") {
+  ListThreads();
+  return(0);
+}
+else if ( (kw == "killthr") || (kw == "cancelthr") )  {
+  if (tokens.size() < 1) { 
+    cout << "Commander::Interpret() Usage: killthr/cancelthr thrid" << endl;  
+    return(0); 
+  }
+  uint_8  id = atol(tokens[0].c_str());
+  bool fgkill = false;
+  if (kw == "killthr")  fgkill = true;
+  StopThr(id, fgkill);
+  return (0);
+}
+else if (kw == "waitthr") {
+  WaitThreads();
+  return (0);
+}
+else if (kw == "cleanthrlist") {
+  CleanThrList();
+  return (0);
+}  
+
+else if (kw == "traceon")  { cout << "Commander::Interpret()  -> Trace ON mode " << endl; trace = true; }
+else if (kw == "traceoff") { cout << "Commander::Interpret()  -> Trace OFF mode " << endl; trace = false; }
+else if (kw == "timingon") { 
+  cout << "Commander::Interpret()  -> Timing ON mode " << endl; 
+  if (gltimer)   delete gltimer;   gltimer = new Timer("PIA-CmdInterpreter ");   timing = true; 
+  }
+else if (kw == "timingoff") { 
+  cout << "Commander::Interpret()  -> Timing OFF mode " << endl; 
+  if (gltimer)  delete gltimer;  gltimer = NULL;  timing = false; 
+  }
+else if (kw == "exec") {
+  if (tokens.size() < 1) { cout << "Commander::Interpret() Usage: exec filename" << endl;  return(0); }
+  ExecFile(tokens[0], tokens);
+  }
+else if (kw == "autoiniranf") { 
+  Auto_Ini_Ranf(1);
+  return(0);
+}
+else if (kw == "shell") {
+  if (tokens.size() < 1) { cout << "Commander::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<<"Commander::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 Commander::ParseLineExecute(string& line, bool qw)
+  // Si qw == true, on decoupe entre '' ou "" ou espaces
+{
+vector<string> tokens;
+vector<bool> qottoks;
+string kw, toks;
+if (line.length() < 1)  return(0);
+LineToWords(line, kw, tokens, qottoks, toks, qw);
+return(ExecuteCommand(kw, tokens, toks));  
+}
+
+/* --Methode-- */
+int Commander::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) {
+      // Doit-on l'executer sous forme de thread separe ? 
+      if ( (args.size()>0) && (args[args.size()-1] == "&") ) { 
+	if ((*it).second.cex->IsThreadable(keyw) ) {
+	  ThrId++;
+	  CommandExeThr * thr = 
+	    new CommandExeThr(ThrId, (*it).second.cex, keyw, args, toks);
+	  CmdThrExeList.push_back(thr);
+	  cout << " Commander::ExecuteCommand() : Thread execution of command " << keyw << endl;
+	  thr->start();
+	  if (CmdThrExeList.size() > 5)  CleanThrList();
+	  rc = 0;
+	}
+	else {
+	  args.erase(args.end()-1);
+	  for(size_t k=toks.size()-1; k>0; k--) 
+	    if (toks[k] == '&') { toks[k] = ' '; break; }
+	  cout << " Commander::ExecuteCommand() : Thread execution NOT available for" << keyw << endl;
+	  rc = (*it).second.cex->Execute(keyw, args, toks);
+	}
+      }
+      else  rc = (*it).second.cex->Execute(keyw, args, toks);
+    }
+    else cout << "Dont know how to execute " << keyw << " ? " << endl;
+  }
+  return(rc);
+}
+
+/* --Methode-- */
+int Commander::ExecFile(string& file, vector<string>& args)
+{
+char line_buff[1024];
+FILE *fip;
+int rcc = 0;
+if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
+  if (file.find('.') >= file.length()) {
+    cout << "Commander::Exec(): Error opening file " << file << endl;
+    file += ".pic";
+    cout << "                Trying file " << file << endl;
+    fip = fopen(file.c_str(),"r");
+    }
+  }
+
+if(fip == NULL) {
+  cerr << "Commander::Exec() Error opening file " << file << endl;
+  hist << "##! Commander::Exec() Error opening file " << file << endl;
+  return(0);
+  }
+
+// hist << "### Executing commands from " << file << endl;
+PushStack(args);
+if (trace) { 
+  ShowMessage("### Executing commands from ", _MAGENTA_);
+  ShowMessage(file.c_str(), _MAGENTA_);
+  ShowMessage("\n", _MAGENTA_);
+  }
+
+bool ohv = histon;
+histon = false; 
+while (fgets(line_buff,1023,fip) != NULL)
+  {
+  if (trace) ShowMessage(line_buff, _MAGENTA_);
+  line_buff[strlen(line_buff)-1] = '\0';   /*  LF/CR de la fin */
+  string line(line_buff);
+  rcc = Interpret(line);
+  if ((rcc == CMD_RETURN_RC) || (rcc == CMD_BREAKEXE_RC)) break;
+  }
+histon = ohv; 
+
+// hist << "### End of Exec( " << file << " ) " << endl;
+if (trace) { 
+  ShowMessage("### End of Exec( ", _MAGENTA_);
+  ShowMessage(file.c_str(), _MAGENTA_);
+  ShowMessage(" ) \n", _MAGENTA_);
+  }
+
+PopStack(true);
+
+return(0);
+}
+
+/* --Methode-- */
+void Commander::ListThreads()
+{
+  cout << "--- Commander::ListThreads()- command execution threads NThread=" 
+       <<  CmdThrExeList.size() << " ---" << endl;
+  for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 
+      tit != CmdThrExeList.end(); tit++) {
+    cout << "Id=" << (*tit)->Id(); 
+    if ( (*tit)->IfRunning() )  cout << " Executing";
+    else if ( (*tit)->IfDone() )  cout << " Finished , Rc= " << (*tit)->getRC();
+    else cout << " Stopped/Canceled";
+    cout << " (Cmd= " << (*tit)->Keyword() << " " << (*tit)->Tokens().substr(0,35);
+    if ((*tit)->Tokens().length() > 35) cout << "... )" << endl;
+    else cout << " )" << endl;
+  }
+}
+/* --Methode-- */
+void Commander::StopThr(uint_8 id, bool fgkill)
+{
+  for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 
+      tit != CmdThrExeList.end(); tit++) {
+    if ( ((*tit)->Id() == id) && ((*tit)->IfRunning()) ) { 
+      if (fgkill) {
+	(*tit)->kill(SIGUSR1);  
+	cout << "Commander::StopThr()  Send signal SIGUSR1 to Thread Id= " << id << endl;
+      }
+      else {
+	(*tit)->cancel();
+	cout << "Commander::StopThr()  Canceling Thread Id= " << id << endl;
+      }
+      return;
+    }
+  }
+  cout << "Commander::StopThr()/Error: No active thread with Id= " << id << endl;
+}
+
+/* --Methode-- */
+void Commander::CleanThrList()
+{
+  cout << "---- Commander::CleanThrList()  Cleaning thrlist  ----- \n";
+  list<CommandExeThr *> thrcopie;
+  int ncl = 0;
+  for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 
+      tit != CmdThrExeList.end(); tit++) {
+    if ( ((*tit)->IfEnded() || (*tit)->IfStopped()) && (ncl < 3) ) { 
+      cout << " Thread Id= " << (*tit)->Id() << " rc= " << (*tit)->getRC() << " Cleaned" << endl;
+      delete (*tit);
+      ncl++;
+    }
+    else thrcopie.push_back((*tit));
+  }
+  CmdThrExeList = thrcopie;
+  cout << " ... " << CmdThrExeList.size() << " threads still active " << endl;
+}
+
+/* --Methode-- */
+void Commander::WaitThreads()
+{
+  cout << "---- Commander::WaitThreads()  Wait/Join command execution threads - NThread=" 
+       <<  CmdThrExeList.size() << " ----- " << endl;
+  for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 
+      tit != CmdThrExeList.end(); tit++) {
+    try {
+      if (! (*tit)->IfDone())  (*tit)->join();
+    }
+    catch (std::exception & e) {
+      cout << " Commander::WaitThreads()/Exception msg= " << e.what() << endl;
+    }
+    cout << " Joined thread Id= " << (*tit)->Id() << " rc= " << (*tit)->getRC() << endl;
+    delete (*tit);
+  }
+  CmdThrExeList.erase(CmdThrExeList.begin(), CmdThrExeList.end());
+}
+
+/* --Methode-- */
+int Commander::CShellExecute(string cmd)
+{
+ if(cmd.size()<=0) return -1;
+
+ string fname = 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 << "Commander/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& Commander::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);
+ 
+}
+
+
+/*  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} ) }
+*/
+
+// Fonction qui remplace tout caractere non alphanumerique en Z
+static void check_latex_reflabel(string & prl)
+{
+  for(int k=0; k<prl.length(); k++) 
+    if (! isalnum(prl[k]) )  prl[k] = 'Z';
+}
+
+// Fonction qui remplace _ en \_
+static string check_latex_underscore(string const & mot)
+{
+  string rs;
+  for(int k=0; k<mot.length(); k++) {
+    if (mot[k] == '_')  rs += "\\_"; 
+    else rs += mot[k];
+  }
+  return rs;
+}
+
+/* --Methode-- */
+/*!
+  \brief Produces a LaTeX file containing the registered command helps
+  The file \b fname is created and can be inserted into a LaTeX document
+  in order to produce the list of registered commands and corresponding description
+  texts.
+  The LaTeX file should contain the following definitions:
+\verbatim
+  \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} ) }
+
+\endverbatim
+*/
+void Commander::HelptoLaTeX(string const & fname)
+{
+FILE *fip;
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  cout << "Commander::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);
+string prl;
+string mol;
+CmdHGroup::iterator it;
+for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
+  if ((*it).first == "All") continue;
+  prl = (*it).first;  check_latex_reflabel(prl);
+  mol = check_latex_underscore((*it).first);
+  fprintf(fip,"\\item {\\bf %s }  (p. \\pageref{%s}) \n", 
+	  mol.c_str(), prl.c_str());
+}
+
+fputs("\\end{itemize} \n",fip);
+
+fputs("\\vspace*{10mm} \n",fip);
+
+CmdExmap::iterator ite;
+fputs("% ----- Liste de toutes les commandes et help item ----- \n",fip);
+fputs("\\vspace{5mm} \n",fip);
+// fputs("\\begin{table}[h!] \n", fip);
+fputs("\\begin{center} \n ", fip);
+fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Help items \\rule{2cm}{1mm} \\\\ \n", fip);
+fputs("\\vspace{3mm} \n",fip);
+fputs("\\begin{tabular}{llllll}  \n", fip);
+int kt = 0;
+for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
+  prl = (*ite).first;  check_latex_reflabel(prl);
+  mol = check_latex_underscore((*ite).first);
+  fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.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("\\end{table} \n", fip);
+fputs("\\newpage  \n",fip);
+
+int gid;
+for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
+  gid = (*it).second.gid;
+  if (gid == 0)  continue;
+  //  fputs("\\begin{table}[h!] \n",fip);
+  fputs("\\vspace{6mm} \n",fip);
+  fputs("\\begin{center} \n ", fip);
+  fprintf(fip, "\\rule{2cm}{0.5mm} \\makebox[60mm]{{ \\bf %s } help group} \\rule{2cm}{0.5mm} \\\\ \n", 
+	  (*it).first.c_str());
+  fputs("\\vspace{3mm} \n",fip);
+  fputs("\\begin{tabular}{llllll} \n", fip);
+  kt = 0;
+  for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
+    if ((*ite).second.group != gid)  continue;
+    prl = (*ite).first;  check_latex_reflabel(prl);
+    mol = check_latex_underscore((*ite).first);
+    fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.c_str() );
+    kt++;
+    if (kt < 3) fputs(" & ", fip);
+    else  { fputs(" \\\\  \n", fip);  kt = 0; }
+  }
+  for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
+    if ((*ite).second.group != gid)  continue;
+    prl = (*ite).first;  check_latex_reflabel(prl);
+    mol = check_latex_underscore((*ite).first);
+    fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.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("\\end{table} \n",fip);
+  //  fputs("\\vspace{5mm} \n",fip);
+}
+// fputs("\\newline \n",fip);
+
+fputs("% ----- Liste des commandes dans chaque groupe ----- \n",fip);
+fputs("\\newpage \n",fip);
+
+for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
+  gid = (*it).second.gid;
+  if (gid == 0)  continue;
+  prl = (*it).first;  check_latex_reflabel(prl);
+  fprintf(fip,"\\subsection{%s} \\label{%s} \n", 
+          (*it).first.c_str(), prl.c_str());
+  if ((*it).second.desc.length() > 0) 
+    fprintf(fip,"%s \n \\\\[2mm]  ", (*it).second.desc.c_str());
+  fprintf(fip,"\\noindent \n");
+  for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
+    if ((*ite).second.group != gid)  continue;
+    prl = (*ite).first;  check_latex_reflabel(prl);
+    mol = check_latex_underscore((*ite).first);
+    fprintf(fip,"\\piahelpitem{%s} \\label{%s} \n", 
+            mol.c_str(), prl.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;
+    prl = (*ite).first;  check_latex_reflabel(prl);
+    mol = check_latex_underscore((*ite).first);
+    fprintf(fip,"\\piacommand{%s} \\label{%s} \n", 
+            mol.c_str(), prl.c_str());
+    fputs("\\begin{verbatim} \n",fip);
+    fprintf(fip,"%s\n", (*ite).second.us.c_str());
+    fputs("\\end{verbatim} \n",fip);
+    }
+}
+
+fclose(fip);
+cout << " Commander::HelptoLaTeX() - LaTeX format help written to file " <<  fname << endl;
+ 
+return;
+}
+
+
+}  // End of namespace SOPHYA
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/commander.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/commander.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/commander.h	(revision 3445)
@@ -0,0 +1,265 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe interpreteur de commande pour piapp 
+// Reza      Aout 97 , Juillet,Aout 98
+//           Octobre 2003: de PIext -> SysTools
+// LAL-IN2P3/CNRS  DAPNIA/CEA
+
+#ifndef COMMANDER_H_SEEN
+#define COMMANDER_H_SEEN
+
+#include "machdefs.h"
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <list>
+#include <stack>
+#include <map>
+#include <functional>
+
+#include "pdlmgr.h"
+#include "dvlist.h"
+#include "ctimer.h"
+
+namespace SOPHYA {
+
+////// Classe definissant l'interface pour un interpreteur de commande
+
+/*!
+  \ingroup SysTools
+  \brief  Interface definition for a generic command interpreter.
+*/
+class CmdInterpreter {
+public:
+  virtual		~CmdInterpreter() {} ;
+//! Returns the interpreter's name
+  virtual string	Name()=0;
+//! Method to be called in order to interpret a line or string.
+  virtual int		Interpret(string& line)=0;
+};
+
+
+/////// Classe definissant l'interface pour un executeur de commande
+
+/*!
+  \ingroup SysTools
+  \brief Interface definition for command executor, to be used with Commander
+
+  A command is defined by a keyword and a number of argument
+*/
+
+class CmdExecutor {
+public:
+  virtual	~CmdExecutor() {} ;
+  // keyw : Le mot cle associe , args: Arguments de la commande
+  //! command execution method for a command defined by keyword and its arguments.
+  virtual int	Execute(string& keyw, vector<string>& args, string& toks)=0;
+  //! Return true if the command \b keyw is thread compatible (can be executed in a separate thread)
+  virtual bool  IsThreadable(string const & keyw) { return false; }
+};
+
+
+
+class CommanderBloc;    // Bloc de type foreach / for de l'interpreteur Commander
+class CommanderScript;  // Script de commandes defini ds l'interpreteur Commander
+class CommandExeThr;    // Thread d'execution de commande
+
+//! A simple command interpreter with c-shell like syntax and  dynamic load capability.
+
+class Commander : public CmdInterpreter  {
+public:
+  static Commander*	GetInterpreter();
+
+			Commander(bool fgsigzt=true);
+  virtual		~Commander();
+  virtual string	Name();
+
+  virtual void		AddHelpGroup(string& grp, string& desc);
+  virtual void		RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, 
+                                        string& grp);
+  inline  void		RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, 
+                                        char* grp)
+                        { string sgrp = grp; RegisterCommand(keyw, usage, ce, sgrp); }
+
+  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 void		StopExecution();
+
+  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);
+
+  inline  void		SetMaxLoopLimit(int_8 lim=0) { maxlooplimit = lim; }
+  inline  int_8         GetMaxLoopLimit() { return maxlooplimit; }
+
+  string		GetCurrentPrompt() { return curprompt; }
+
+
+  virtual void 		HelptoLaTeX(string const & flnm);
+
+  //! return the current selected interpreter (default : this)
+  inline  CmdInterpreter* CurrentInterpreter() { return(curcmdi); }
+
+  // ----- Action / gestion des variables propres de l'interpreteur
+  // Verifie l'existence de la variable nomme vn et retourne sa valeur ds vv
+  // Retourne false si la variable n'existe pas
+  virtual bool    GetVar(string const & vn, string & vv);
+  virtual bool    GetVar(string const & vn, int idx, string & vv);
+  virtual bool    GetVar(string const & vn, vector<string> & vv);
+  virtual bool    SetVar(string const & vn, string const & vv);
+  virtual bool    SetVar(string const & vn, int idx, string const & vv);
+  virtual bool    SetVar(string const & vn, vector<string> const & vv);
+  virtual bool    CheckVarName(string const & vn);
+  virtual bool    DeleteVar(string const & vn);
+  virtual void    ListVar();
+  // Variables de l'environnement application 
+  virtual bool    GetVarApp(string const & vn, string & vv);
+  virtual bool    SetVarApp(string const & vn, string const & vv);
+  virtual bool    DeleteVarApp(string const & vn);
+  virtual void    ListVarApp();
+  // Variables d'environnement globales 
+  virtual bool    GetVarEnv(string const & vn, string & vv);
+  virtual bool    SetVarEnv(string const & vn, string const & vv);
+  virtual bool    DeleteVarEnv(string const & vn);
+  virtual void    ListVarEnv();
+
+  //   Utilitaire pour decoupage en mot
+  static  int   LineToWords(string& line, string& kw, vector<string>& tokens,
+			    vector<bool>& qottoks, string& toks, bool uq=true);
+protected:
+  virtual int	ParseLineExecute(string& line, bool qw=true);
+
+  virtual int   ExecuteCommandLine(string & keyw, vector<string> & args,
+				   string & toks);
+
+  virtual bool	CheckHelpGrp(string& grp, int& gid, string& desc);
+  inline  bool	CheckHelpGrp(string& grp, int& gid)
+  { string desc=""; return CheckHelpGrp(grp, gid, desc); }
+
+  virtual int   SubstituteVars(string & s, string & s2);  
+  int	        EvaluateTest(vector<string> & args, 
+			     string & line, bool & res);
+  int	        EvalRPNExpr(vector<string> & args, string & line);
+
+  // variable de l'interpreteur = valeur - accepte la syntaxe de type varname[index] 
+  virtual bool    SetVariable(string const & vn, string const & vv);
+  // Acces aux variables 
+  virtual bool    Var2Str(string const & vn, string & vv);
+  inline  bool    Var2Str(string const & vn, int idx, string & vv)
+  { return GetVar(vn, idx, vv); }
+  inline  bool    Var2Str(string const & vn, vector<string> & vv)
+  { return GetVar(vn, vv); }
+
+  virtual string  GetTmpDir();
+
+  virtual void  SetCurrentPrompt(const char* pr);
+  inline void   SetCurrentPrompt(string const & pr) { SetCurrentPrompt(pr.c_str()); }
+  inline void   SetDefaultPrompt(string const & pr) { defprompt = pr; }
+
+  virtual void	ShowMessage(const char * msg, int att);
+
+  void          PushStack(vector<string> & args);
+  void          PopStack(bool psta=true);
+
+  //   Gestion des threads d'execution de commandes 
+  void          ListThreads();
+  void          StopThr(uint_8 thrid, bool fgkill=true);
+  void          CleanThrList();
+  void          WaitThreads();
+
+// ------ Attributs et variables ------ 
+  CmdInterpreter* curcmdi;
+
+// Gestion des variables
+  typedef map< string,  vector<string>, less<string> > CmdVarList;
+  CmdVarList variables;
+
+// Pour enregistrer la liste de commandes et leurs executeurs et le help
+/*! \cond   Pour supprimer la documentation par doxygen */
+//  Command executor registration - For Commander internal use
+  struct cmdex {int group; string us; CmdExecutor * cex; } ;
+//  Help text registration - For Commander internal use
+  struct hgrpst {int gid; string desc; } ;               // Identification+description d'un groupe de help
+  /*! \endcond */
+
+  typedef map<string, hgrpst, 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;                                   // Liste des commandes et leurs executeurs
+  CmdExmap helpexmap;                                  // Pour les helps sans commande
+// Pour garder la liste des threads d'execution de commande
+  list<CommandExeThr *> CmdThrExeList;
+  uint_8 ThrId;
+
+// 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, CommanderScript*, less<string> > ScriptList;
+  ScriptList mScripts;  // Liste des scripts
+  CommanderScript* curscript; // Script en cours de definition
+
+  // Code de retour execution commande
+  int _xstatus;
+  // Valeur de retour (par l'instruction return) - 
+  string _retstr;
+
+  //  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 pour les Prompts
+  stack<string> PromptStack; 
+
+  // Gestion des blocs de commandes et tests (if) 
+  stack< CommanderBloc * > CmdBlks;  // Bloc de commande courant (foreach, ...)
+  int felevel;                    // foreach-for level 
+  int_8 maxlooplimit;            // Limite maximum des boucles
+  stack< list<char> > TestsStack; // Stack des resultats de test
+  list<char>::iterator tresit;       // Test courant
+  bool curtestresult;             // Resultat courant des tests 
+
+  // Controle du flot d'execution 
+  bool fgexebrk; 
+
+  // Commande splitees sur plusieurs lignes
+  bool mulinefg;            // Bloc multi-lignes (ligne suite)
+  string mulinecmd;         // Commande multi-lignes
+
+  // Texte de prompt (attente de commande)
+  string spromptmul;        // Prompt console avant multi-ligne
+  string curprompt;         // Prompt courant
+  string defprompt;         // Prompt par defaut 
+
+  // Gestion d'historique, trace, timing des commandes
+  ofstream hist;       //  History file 
+  bool histon;        //  True ->  history file
+  bool trace;          // Trace flag
+  bool timing;         // Display CPU Time
+  Timer* gltimer;      // pour Display CPU Time
+
+friend class CommanderBloc;  
+friend class CommanderScript;  
+
+};
+
+} // namespace SOPHYA
+
+/* end of ifdef COMMANDER_H_SEEN */
+#endif  
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/ctimer.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/ctimer.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/ctimer.cc	(revision 3445)
@@ -0,0 +1,111 @@
+//
+// $Id: ctimer.cc,v 1.7 2007-07-06 12:54:12 ansari Exp $
+//
+
+#include "sopnamsp.h"
+#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.
+//--
+
+
+
+/*!
+  \class SOPHYA::Timer
+  \ingroup SysTools
+  \brief Simple chronometer for CPU and elapsed time measurements.
+  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 updates partial times and optionaly displays partial and 
+  total CPU and elapsed time. 
+  The destructor calls Split() if the object has been created with prfg=true.
+  displays the total CPU and elapsed time since timer creation.
+  The macro \b  TIMEF create a timer object with the function name.
+  The elapsed and CPU time are displayed at the end of the bloc or function.
+*/
+
+/*! 
+  \brief Constructor with the specification of a optional name or message 
+  and default print flag.
+  if \b prfg==true , a call to Split() causes the display of partial and 
+  total CPU and elapsed time.
+*/
+Timer::Timer(const char* name, bool prfg)
+  : timerName(name) , defprtflg(prfg)
+{
+  cpu0 = cpuSplit = clock();
+  elapse0 = elapseSplit = time(0);
+  cpuSecT = cpuSecP = 0.;
+  elapSecT = elapSecP = 0;
+}
+
+//! The destructor call Split() if the object has been created with prtflag=true.
+Timer::~Timer()
+{
+  if (defprtflg) Split();
+}
+
+
+/*! This method updates the CPU and elapsed time. 
+    If the prfg==true or the constructor prfg==true, it also displays (prints) 
+    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, bool prfg)
+{
+  time_t elapse = time(0);
+  clock_t cpu   = clock();
+
+  cpuSecT = ((float)cpu - (float)cpu0) / (float)(CLOCKS_PER_SEC);
+  cpuSecP = ((float)cpu - (float)cpuSplit) / (float)(CLOCKS_PER_SEC);
+  
+  elapSecP  = elapse - elapseSplit;
+  elapSecT = elapse - elapse0;
+
+
+  //  cumlcpu += (double)cpuSecP;
+  //  cumulelapse += (int_8)etm;
+
+  elapseSplit = elapse;
+  cpuSplit    = cpu;
+
+  if ( !defprtflg && !prfg )  return;
+
+  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.
+
+  int etm  = elapSecP;
+  int etmt = elapSecT; 
+  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;
+}
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/ctimer.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/ctimer.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/ctimer.h	(revision 3445)
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: ctimer.h,v 1.5 2007-07-06 12:54:12 ansari Exp $
+//
+
+
+#ifndef CTIMER_SEEN
+#define CTIMER_SEEN
+
+#include "machdefs.h"
+#include <sys/types.h>
+#include <time.h>
+#include <iostream>
+#include <stdio.h>
+#include <string>
+
+// <summary> Permet de chronometrer des fonctions. </summary>
+// 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.
+
+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, bool prfg=true);
+
+  // 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, bool prfg=false);
+
+  // Sert a eviter que GNU ne pretende qu'on utilise pas l'objet...
+  /*! To avoid not used object compiler warnings */
+  void Nop() {}
+
+  /*! \brief Return the total elapsed time (number of seconds), 
+    between the object creation and the last call to Split(). 
+  */ 
+  inline int_8 TotalElapsedTime() { return elapSecT ; }
+  /*! \brief Return the partial elapsed time (number of seconds).
+      between the last two calls to Split().
+  */ 
+  inline int_8 PartialElapsedTime() { return elapSecP ; }
+
+  /*! \brief Return the total CPU time in seconds, 
+    between the object creation and the last call to Split(). 
+  */ 
+  inline float TotalCPUTime() { return  cpuSecT; }
+  /*! \brief Return the partial CPU time in seconds, 
+      between the last two calls to Split().
+  */ 
+  inline float PartialCPUTime() { return  cpuSecP; }
+
+private:
+  clock_t cpu0, cpuSplit;
+  time_t  elapse0, elapseSplit;
+  float cpuSecT, cpuSecP;     // Total and partial CPU time 
+  int_8 elapSecT, elapSecP;    // Total and partial elapsed time 
+  string timerName;
+  bool defprtflg;
+};
+
+} // namespace SOPHYA
+
+#define TIMEF     Timer timer(__PRETTY_FUNCTION__); timer.Nop(); 
+
+#endif // CTIMER_SEEN
Index: /tags/V_Nov2007/SophyaLib/SysTools/cxxcmplnk.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/cxxcmplnk.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/cxxcmplnk.cc	(revision 3445)
@@ -0,0 +1,276 @@
+// Gestionnaire de compilation-linker C++ - R. Ansari 10/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "cxxcmplnk.h"
+#include "sspvflags.h"
+#include <iostream>
+
+/*!
+  \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 and 
+  systems:
+  - Linux + GNU compiler (g++)
+  - Linux + Intel compiler (icc)
+  - Darwin + GNU compiler (MaxOS X 10.3 and 10.4)
+  - OSF1 + cxx  (HP/Compaq/Digital OSF-Tru64 and cxx c++ compiler)
+  - IRIX64 + CC : Silicon Graphics  system and C++ compiler
+  - AIX + xlC : IBM  system and C++ compiler
+
+  \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 -fdollars-in-identifiers";
+static char * KCC_opt = 
+"-O --exceptions --rtti  --auto_instantiation --one_instantiation_per_object -D__KCC__";
+static char * icc_opt = 
+"-O -fpic -frtti";
+static char * cxx_opt = 
+"-O -no_implicit_include -pthread";
+static char * SGICC_opt =  "-O -prelink -D__SGICC__ -LANG:std";
+static char * xlC_opt = 
+"-O -qrtti=all -qeh=v6";
+
+/* --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++/"; 
+#ifndef SO_NOFPIC
+  compOptions += " -fPIC ";
+  linkOptions += " -fPIC ";
+#endif
+#endif
+#if defined( __DECCXX )
+  compCmd = "cxx ";
+  compOptions = cxx_opt;
+  linkOptions = compOptions + " -shared";
+  syscomp += "cxx/"; 
+#endif
+#if defined( __KCC__ )
+  compCmd = "KCC ";
+  compOptions = KCC_opt;
+  linkOptions = KCC_opt;
+  syscomp += "KCC/";  
+#endif
+#if defined( __SGICC__ )
+  compCmd = "CC ";
+  compOptions = SGICC_opt;
+  linkOptions = "-shared -O -LANG:std";
+  syscomp += "CC/";  
+#ifdef SO_ARCH64
+  compOptions += " -64 ";
+  linkOptions += " -64 "; 
+#endif
+#endif
+#if defined( __INTEL_COMPILER )
+  compCmd = "icpc ";
+  compOptions = icc_opt;
+  linkOptions = icc_opt + string(" -shared");
+  syscomp += "icc/";  
+#endif
+#if defined( __IBMCPP__ )
+  compCmd = "xlC ";
+  compOptions = xlC_opt;
+  linkOptions = xlC_opt + string(" -brtl -qmkshrobj ");
+  syscomp += "xlC/";  
+#ifdef SO_ARCH64
+  compOptions += " -q64 ";
+  linkOptions += " -q64 "; 
+#endif
+#endif
+
+#ifndef Darwin
+  linkCmd = compCmd;
+#else
+  linkCmd = "c++ -bundle ";
+  linkOptions = "-lSystem -lm";
+#endif
+
+  cppFlags += " -I. ";
+  compOptions += " -c ";
+
+  bool fgenv1 = false;
+  bool fgenv2 = false;
+  char* varenv=NULL;
+  varenv=getenv("SOPHYABASE");
+  string sbaserep = "./";
+  if (varenv) {
+    fgenv1 = true;
+    sbaserep = varenv; 
+    if (sbaserep[sbaserep.length()-1] != '/')  sbaserep += '/';
+    cppFlags += ( " -I" + sbaserep + "include/ ");
+    linkOptions += " -L" + sbaserep + "slb/";
+  }
+  varenv=getenv("SOPHYABASEREP");
+  if (varenv) {
+    fgenv2 = true;
+    string dpcbase = varenv; 
+    if (dpcbase[dpcbase.length()-1] != '/')  dpcbase += '/';
+    cppFlags += ( " -I" + dpcbase + "Include/ ");
+    linkOptions += " -L" + dpcbase + syscomp + "ShLibs/";
+    char * varenvextl=getenv("EXTLIBDIR");
+    if (varenvextl) {
+    string extlib = varenvextl; 
+    if (extlib[extlib.length()-1] != '/')  extlib += '/';
+    cppFlags += ( " -I" + extlib +"Include/ ");
+    }
+  }
+  if (!fgenv1 && !fgenv2) 
+    cout << " CxxCompilerLinker()/Warning : SOPHYABASE not defined" << endl;
+  if (fgenv1 && fgenv2) 
+    cout << " CxxCompilerLinker()/Warning : both SOPHYABASE and SOPHYABASEREP defined" << endl;
+
+#if defined( SO_SLBALLINONE )
+  if (fglibsophya || fglibpi) linkOptions += " -lAsophyaextPI ";
+  /*
+  cout << " +++ DBG/CxxCompilerLinker() - in AIX fglibpi= " 
+       << ((fglibpi) ? " true " : " false ")  << endl;
+  // Reza:Dec 2005 : pb avec les programmes PI sur AIX si linke avec shared lib PI
+  // (Portage sur regatta.calcul.u-psud.fr AIX 5.3 , libXm Xt X11 en .a uniquement) 
+  if (fglibpi) { 
+    linkOptions += " -L" + sbaserep + "lib/";
+    linkOptions += " -lPIext -lPIGcont -lPI -lXm -lXt -lX11 -lpthread ";
+  }
+  */
+  cout << "CxxCompilerLinker()/Warning: SINGLESLB_SOPHYA_PI_EXT -> linkOptions= " << linkOptions << endl; 
+#else
+  if (fglibsophya) linkOptions += " -lsophya ";
+  if (fglibextsophya) linkOptions += " -lextsophya ";
+  if (fglibpi) linkOptions += " -lPI ";
+#endif
+  linkOptions += " -lm ";
+
+
+  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_Nov2007/SophyaLib/SysTools/cxxcmplnk.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/cxxcmplnk.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/cxxcmplnk.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SysTools/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/objlist.list	(revision 3445)
@@ -0,0 +1,11 @@
+cexpre.o
+commander.o
+ctimer.o
+cxxcmplnk.o
+pdlmgr.o
+periodic.o
+psighand.o
+resusage.o
+rpneval.o
+timing.o
+zthread.o
Index: /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.cc	(revision 3445)
@@ -0,0 +1,343 @@
+//
+// Gestionnaire de lien dynamique   -   R. Ansari 12/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+//
+#include <machdefs.h>
+
+#include "sopnamsp.h"
+#include "pdlmgr.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+
+
+// 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, HP/Compaq/Digital OSF-Tru64, SGI IRIX, IBM AIX, Sun Solaris,
+  MacOS X/Darwin). \n
+  For MacOS X/Darwin, the NSxxx API 
+  <tt> (NSLinkModule , NSCreateObjectFileImageFromFile, ...) </tt> 
+  is used.
+  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 SO_ARCH64
+  string cmd = "LD_LIBRARYN64_PATH=";
+  varenv=getenv("LD_LIBRARYN64_PATH");
+#else
+  string cmd = "LD_LIBRARYN32_PATH=";
+  varenv=getenv("LD_LIBRARYN32_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;
+    //AIX: l'argument de putenv n'est pas const (Reza Dec 2005)
+    //On fait un new - mais qui fait le delete ?
+    char * pevc = new char [cmd.length()+1];
+    strcpy(pevc, cmd.c_str());
+    putenv(pevc);
+    }
+
+#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;
+
+string compopt = "cc -c -o ";
+#if defined(__GNUG__) 
+#ifndef SO_NOFPIC
+compopt = "cc -fPIC -c -o " ;
+#endif
+#endif
+#if defined(IRIX64) && defined(SO_ARCH64)
+compopt = "cc -64 -c -o " ;
+#endif
+#if defined(AIX) && defined(SO_ARCH64)
+compopt = "cc -q64 -c -o " ;
+#endif
+
+// Compilation du fichier
+cmd = compopt + fnameobj + " " + fname;
+
+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 SO_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;
+#ifdef SO_ARCH64
+  cmd = "cc -brtl -qmkshrobj -q64 -o " + fnameso + " " + fnameobj + " -lm -lc";;
+#else
+  cmd = "cc -brtl -qmkshrobj -o " + fnameso + " " + fnameobj + " -lm -lc";;
+#endif
+#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 ";
+  cmd = "cc -bundle -o " + fnameso + " " + fnameobj + " -lSystem -lm";
+#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)
+{
+dylok = false;
+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;
+
+string sdylerr;
+#if defined(HPUX)
+cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
+return;
+#elif defined(Darwin)
+NSObjectFileImageReturnCode nsrc = NSCreateObjectFileImageFromFile(fnameso.c_str(), &nsobjfile);
+if (nsrc == NSObjectFileImageSuccess) {
+  nsmod = NSLinkModule(nsobjfile, fnameso.c_str(),
+		       NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE | 
+		       NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+  // The second argument of NSLinkModule is the module name
+  // We might associate later a name for the module in the PDynLinkMgr object
+  if (nsmod != NULL) dylok = true;
+  else cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSLinkModule ... " << endl;
+}
+else { 
+  cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSCreateObjectFileImageFromFile ... " << endl;
+  if (nsrc == NSObjectFileImageFailure) cerr << " ErrCode= NSObjectFileImageFailure " << endl;
+  else if (nsrc == NSObjectFileImageInappropriateFile) cerr << " ErrCode= NSObjectFileImageInappropriateFile" << endl;
+  else if (nsrc == NSObjectFileImageArch ) cerr << " ErrCode= NSObjectFileImageArch" << endl;
+  else if (nsrc == NSObjectFileImageFormat) cerr << " ErrCode= NSObjectFileImageFormat" << endl;
+  else if (nsrc == NSObjectFileImageAccess) cerr << " ErrCode= NSObjectFileImageAccess" << endl;
+  }
+#else
+dlhandle = NULL;
+dlhandle =  dlopen(fnameso.c_str(), RTLD_NOW);
+if (dlhandle != NULL) dylok = true;
+else { 
+  sdylerr = "Loader Error (dlerror()):";
+  sdylerr += dlerror();
+  }
+#endif
+
+if (!dylok)  {
+  cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso 
+       << " (" << soname << ")" << endl; 
+  if (sdylerr.length() > 0) cerr << sdylerr;
+  return; 
+  }
+}
+
+/* --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;
+#elif defined(Darwin)
+if (dylok) { 
+  if (nsmod != NULL)  NSUnLinkModule(nsmod, NSUNLINKMODULE_OPTION_NONE);
+  NSDestroyObjectFileImage(nsobjfile);
+  }
+#else
+if (dylok) {
+  if (dlhandle) dlclose(dlhandle);    dlhandle = NULL;
+  }
+#endif
+if (copy) {
+  string cmd = "rm -f " + soName;
+  system(cmd.c_str());
+  }
+}
+
+/* --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 (!dylok) {
+  cerr << "PDynLinkMgr::GetFunction() Error:sharedobjet/dynamic library not open -> f=NULL" << endl;
+  return f;
+}
+#if defined(HPUX)
+cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
+return f;
+#endif
+#if defined(Darwin)
+string funame = "_" + funcname;
+NSSymbol nsf = NSLookupSymbolInModule(nsmod, funame.c_str());
+f = (DlFunction)NSAddressOfSymbol(nsf);
+#else 
+string const & funame = funcname;
+if (dlhandle != NULL)  
+  f = (DlFunction)dlsym(dlhandle, funame.c_str());
+#endif
+
+if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
+return(f);
+}
+
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/pdlmgr.h	(revision 3445)
@@ -0,0 +1,62 @@
+// 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 <mach-o/dyld.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);              
+  inline  DlFunction	GetFunction(const char * funcname) 
+    { string fname = funcname;   return GetFunction(fname); }            
+
+  inline  string        GetName() const { return soName; }
+
+protected :
+  static string&	GetTmpDir();
+  static int	  numSO;
+  static string*  tmpDir;
+
+#if defined(HPUX)
+  shl_t dlhandle;
+#elif defined(Darwin)
+  NSObjectFileImage nsobjfile;
+  NSModule nsmod;
+#else 
+  void * dlhandle;
+#endif
+  bool dylok;
+  string soName;
+  bool copy;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SysTools/periodic.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/periodic.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/periodic.cc	(revision 3445)
@@ -0,0 +1,159 @@
+/* Classe d'objets avec une methode (DoPeriodic()) appelee periodiquement */
+/*                                  Eric Aubourg     04/96                */
+/*                                  Reza Ansari      06/96                */
+/*                      LAL/IN2P3 (Orsay)  DAPNIA/CEA (Saclay)            */
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaLib/SysTools/periodic.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/periodic.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/periodic.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SysTools/psighand.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/psighand.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/psighand.cc	(revision 3445)
@@ -0,0 +1,157 @@
+//  Pour la gestion des signaux a travers des exceptions
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include "sopnamsp.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 
+   \brief Utility function for signal handling configuration.
+
+   Configures signal handling. When the flag is true, an exception 
+   \b CaughtSignalExc is thrown with the excpetion id set to the 
+   signal id. If 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  Caught SIG??? ### \n", s);
+    msg = "Caught SIG???";
+    throw ( CaughtSignalExc(msg, s) );
+  }
+
+// return;
+}
Index: /tags/V_Nov2007/SophyaLib/SysTools/psighand.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/psighand.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/psighand.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/SysTools/resusage.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/resusage.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/resusage.cc	(revision 3445)
@@ -0,0 +1,218 @@
+#include "sopnamsp.h"
+#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>
+#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.
+  \param pg: Process group RU_Self or RU_Children or RU_All
+  - pg = RU_Self : Resource usage for the process itself
+  - pg = RU_Children : Resource usage for the child processes
+  - pg = RU_All : resource usage for the process itself and its child processes
+*/
+ResourceUsage::ResourceUsage(RU_ProcGrp pg)
+{
+  procgrp = pg;
+  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;
+  /*   Avr07 (Reza) : getrlimit(RLIMIT_DATA) semble bien renvoyer la bonne valeur
+       si une limite est definie, mais ReadLinuxTotMem() PAS OK  
+#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;
+  if ((procgrp == RU_Self) || (procgrp == RU_All)) 
+    rc = getrusage(RUSAGE_SELF, &rsu);
+  else 
+    rc = getrusage(RUSAGE_CHILDREN, &rsu);
+
+  delta_tottm = cur_tottm;
+  delta_rss = cur_rss;
+  cur_usrtm = s_timeval2msec(rsu.ru_utime);
+  cur_systm = s_timeval2msec(rsu.ru_stime);
+  if (procgrp == RU_All) {
+    struct rusage rsuch;
+    rc = getrusage(RUSAGE_CHILDREN, &rsuch);
+    cur_usrtm += s_timeval2msec(rsuch.ru_utime);
+    cur_systm += s_timeval2msec(rsuch.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 = (int)(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,500); // 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_Nov2007/SophyaLib/SysTools/resusage.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/resusage.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/resusage.h	(revision 3445)
@@ -0,0 +1,124 @@
+// 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>
+
+namespace SOPHYA {
+
+//! Acces to information about resource usage (memory, CPU, ...)
+
+class ResourceUsage
+{
+public:
+/*!
+  - RU_Self : Resource usage for the process itself
+  - RU_Children : Resource usage for the child processes
+  - RU_All : resource usage for the process itself and its child processes
+*/
+  enum RU_ProcGrp {RU_Self=0, RU_Children=1, RU_All=2};
+
+  ResourceUsage(RU_ProcGrp pg=RU_Self);
+  ~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:
+  RU_ProcGrp procgrp; // Process group: self, child, all
+  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_Nov2007/SophyaLib/SysTools/rpneval.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/rpneval.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/rpneval.cc	(revision 3445)
@@ -0,0 +1,342 @@
+#include "sopnamsp.h"
+#include "rpneval.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "strutilxx.h"
+#include "srandgen.h"
+#include <iostream>
+#include <math.h>
+
+namespace SOPHYA {
+
+/*!
+  \class RPNExpressionEvaluator
+  \ingroup SysTools
+  Arithmetic expression (double precision float) evaluator 
+  in Reverse Polish Notation (RPN). This is an HP calculator 
+  like syntax. Spaces are used for separating the string 
+  expression into tokens. \n
+  The string parsed by RPNExpressionEvaluator should be 
+  formed by a set of space separated words. Each word may be
+  a numerical constant or operation or function. 
+  All numeriacl constants are pushed to stack top. 
+  The stack is limited only
+  by the available memory. The three numbers on the stack top
+  are referred to as <tt> x y z </tt>. \n
+  Available operations: 
+  - op= + - * / % : replace (x,y) by x.op.y 
+  - e pi : M_PI , M_E numerical constants
+  - f= sin cos tan asin acos atan : replace x by f(x)
+  - f= chs sqrt sq : (x<-f(x)) change-sign , square root and square (x<-x^2) operations 
+  - f= log log10 exp : replace x by f(x) 
+  - f= fabs floor ceiling : replace x by f(x) 
+  - f= deg2rad rad2deg : replace x by f(x) 
+  - f= rand01 randpm1 gaurand : pushes a random number on the stack top ([0 1] [-1 1] Gaussian)
+  - print x<>y pop push : stack operations
+  - sum product : Replace the complete stack by the sum / product of the numbers in the stack
+  - mean sigma : Replace the complete stack by the mean / sigma of the numbers in the stack
+
+  \sa CExpressionEvaluator Commander
+
+  The following output is produced by the sample code below:
+  \code
+  #include "rpneval.h"
+  ...
+  RPNExpressionEvaluator rpn1("4 2 print + 3 * ");
+  cout << "RPN1: 4 2 + 3 * -> rpn1.Value() = " << rpn1.Value() << endl;  
+  RPNExpressionEvaluator rpn2("1 2 3 4 5 sum");
+  cout << "RPN2: 1 2 3 4 5 sum -> rpn2.Value() = " << rpn2.Value() << endl;
+  \endcode
+
+  Output:
+  \verbatim
+  RPNExpressionEvaluator::PrintStack() Size()= 2
+      0:  2   (x) 
+      1:  4   (y) 
+  RPN1: 4 2 + 3 * -> rpn1.Value() = 18
+  RPN2: 1 2 3 4 5 sum -> rpn2.Value() = 15  
+  \endverbatim
+*/
+
+/*!
+  \brief Parses the string \b sex into words and perform the specified operations on the stack.
+
+  Can throw  RPNExprException 
+*/
+RPNExpressionEvaluator::RPNExpressionEvaluator(string const & sex)
+{
+  vector<string> exe;
+  FillVStringFrString(sex, exe, ' ');
+  int rc = EvalRPNExpr(exe, 0);
+  if (rc < exe.size()) { 
+    string msg = "RPNExpressionEvaluator() - syntax error near ";
+    msg += exe[rc];
+    char buff[32];
+    sprintf(buff," (word %d)",rc);
+    msg += buff;
+    throw RPNExprException(msg);
+  }
+}
+
+/*! 
+  \brief Perform the operations specified by \b on the stack, starting from element \b exe[off].  
+
+  Can throw  RPNExprException 
+*/
+RPNExpressionEvaluator::RPNExpressionEvaluator(vector<string> & exe, int off)
+{
+  int rc = EvalRPNExpr(exe, off);
+  if (rc < exe.size()) { 
+    string msg = "RPNExpressionEvaluator() - syntax error near ";
+    msg += exe[rc];
+    char buff[32];
+    sprintf(buff," (word %d)",rc);
+    msg += buff;
+    throw RPNExprException(msg);
+  }
+}
+
+RPNExpressionEvaluator::~RPNExpressionEvaluator()
+{
+}
+
+/* Operations sur le stack RPN */
+/* --Methode-- */
+//! Return the stack top (x) 
+double RPNExpressionEvaluator::Evaluate() const
+{
+  double x;
+  if ( CheckStack( x) ) 
+    throw RPNExprException("RPNExpressionEvaluator::Evaluate() EmptyStack");
+  else return x;
+}
+  
+/* --Methode-- */
+int RPNExpressionEvaluator::EvalRPNExpr(vector<string> & args, int off)
+{
+  
+  if (args.size() <= off)  return 1;
+  double x,y;
+  x = y = 0.;
+
+  for(int k=off; k<args.size(); k++) {
+    // Les 4 operations de base + - * / 
+    if (args[k] == "+") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = y+x;
+    }
+    else if (args[k] == "-") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = y-x;
+    }
+    else if (args[k] == "*") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = y*x;
+    }
+    else if (args[k] == "/") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = y/x;
+    }
+    else if (args[k] == "%") { 
+      if ( CheckStack( x, y) ) return k;
+      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 ( CheckStack( x) ) return k;
+      rpnstack_.top() = cos(x);
+    }
+    else if (args[k] == "sin") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = sin(x);
+    }
+    else if (args[k] == "tan") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = tan(x);
+    }
+    else if (args[k] == "acos") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = acos(x);
+    }
+    else if (args[k] == "asin") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = asin(x);
+    }
+    else if (args[k] == "atan") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = atan(x);
+    }
+    else if (args[k] == "chs") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = -x;
+    }
+    else if (args[k] == "sqrt") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = sqrt(x);
+    }
+    else if (args[k] == "sq") {  // x^2 
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = x*x;
+    }
+    else if (args[k] == "log") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = log(x);
+    }
+    else if (args[k] == "log10") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = log10(x);
+    }
+    else if (args[k] == "exp") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = exp(x);
+    }
+    else if (args[k] == "fabs") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = fabs(x);
+    }
+    else if (args[k] == "floor") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = floor(x);
+    }
+    else if (args[k] == "ceil") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = ceil(x);
+    }
+    // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003
+    else if (args[k] == "deg2rad") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = x*M_PI/180.;
+    }
+    else if (args[k] == "rad2deg") {
+      if ( CheckStack( x) ) return k;
+      rpnstack_.top() = x*180./M_PI;
+    }
+    // Les fonctions usuelles a 2 argument f(x,y)
+    else if (args[k] == "pow") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = pow(y,x);
+    }
+    else if (args[k] == "atan2") { 
+      if ( CheckStack( x, y) ) return k;
+      rpnstack_.top() = atan2(x,y);
+    }
+    // generateur aleatoire
+    else if (args[k] == "rand01") { 
+      double rnd = drand01();
+      rpnstack_.push(rnd);
+    }
+    else if (args[k] == "randpm1") { 
+      double rnd = drandpm1();
+      rpnstack_.push(rnd);
+    }
+    else if (args[k] == "gaurand") { 
+      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 = SumStack( sx, sx2);
+      if (args[k] == "sum") rpnstack_.push(sx);
+      else { 
+	if (nn == 0) return 1;
+	double fnn = nn;
+	double mean = sx/fnn;
+	if (args[k] == "sigma2")  rpnstack_.push(sx2/fnn-mean*mean);
+	else {
+	  if ((args[k] == "sigma") || (args[k] == "sigmean")) 
+	    rpnstack_.push(sqrt(sx2/fnn-mean*mean));
+	  if ((args[k] == "mean") || (args[k] == "sigmean"))  rpnstack_.push(mean);
+	}
+      }
+    }
+    else if (args[k] == "product") { 
+      double px;
+      int nn = ProductStack( px);
+      if (nn == 0) return k;
+      rpnstack_.push(px);
+    }
+    // Fonctions de manipulation de stack
+    else if (args[k] == "print") { 
+      PrintStack();
+    }
+    else if (args[k] == "x<>y") {
+      if ( CheckStack( x, y) ) return k;
+      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()) return k; 
+      rpnstack_.push(x);
+    }
+
+  }
+  return(args.size()+1);
+}
+
+inline void RPNExpressionEvaluator::PrintStack()
+{
+  if (rpnstack_.empty()) 
+    cout << "RPNExpressionEvaluator::PrintStack() Empty stack " << endl;
+  else {
+    stack<double> s;
+    s = rpnstack_;
+    int k = 0;
+    cout << "RPNExpressionEvaluator::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 RPNExpressionEvaluator::SumStack(double& sx, double& sx2) 
+{
+  sx = sx2 = 0.;
+  int nn = 0;
+  double x = 0.;
+  while( !rpnstack_.empty() ) {
+    x = rpnstack_.top(); rpnstack_.pop();
+    sx += x; sx2 += x*x;
+    nn++;
+  } 
+  return(nn);  
+}
+
+int RPNExpressionEvaluator::ProductStack(double& px) 
+{
+  px = 1.;
+  int nn = 0;
+  double x = 0.;
+  while( !rpnstack_.empty() ) {
+    x = rpnstack_.top(); rpnstack_.pop();
+    px *= x;  nn++;
+  } 
+  return(nn);  
+}
+
+
+} // End of namespace SOPHYA
Index: /tags/V_Nov2007/SophyaLib/SysTools/rpneval.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/rpneval.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/rpneval.h	(revision 3445)
@@ -0,0 +1,66 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe Evaluateur RPN (HP like)
+//           Mars 2004: Extrait de commander.cc
+// LAL-IN2P3/CNRS  DAPNIA/CEA
+
+#ifndef RPNEVALUATOR_H_SEEN
+#define RPNEVALUATOR_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include <string>
+#include <vector>
+#include <stack>
+
+namespace SOPHYA {
+
+/*!
+  \ingroup SysTools
+  \brief Exception class used by  RPNExpressionEvaluator
+  \sa RPNExpressionEvaluator
+*/
+class RPNExprException : public PException {
+  public:
+  explicit RPNExprException(const char * m) : PException(m) {}
+  explicit RPNExprException(const string& m) :  PException(m) {}
+};
+
+
+//! Class for evaluation of arithmetic expressions in RPN (Reverse Polish Notation)
+class RPNExpressionEvaluator {
+public:
+  explicit RPNExpressionEvaluator(string const & sex);
+  explicit RPNExpressionEvaluator(vector<string> & exe, int off=0);
+  virtual ~RPNExpressionEvaluator();
+//! Return the stack top \c (x) as the result of the expression evaluation
+  virtual double Evaluate() const;  // Return the value of the stack top
+//! Alias for Evaluate()
+  inline double Value() const { return Evaluate(); }
+
+private:
+  int EvalRPNExpr(vector<string> & args, int off=0);
+  inline bool CheckStack(double& x) const 
+  {  
+    if (rpnstack_.empty()) return true; 
+    else { x = rpnstack_.top();  return false; }
+  }
+  inline bool CheckStack(double& x, double& y)
+  {
+    if (rpnstack_.size() < 2) return true; 
+    else { 
+      x = rpnstack_.top(); rpnstack_.pop(); 
+      y = rpnstack_.top();  return false; 
+    }
+  }
+
+  void PrintStack();
+  int SumStack(double& sx, double& sx2);
+  int ProductStack(double& px); 
+  
+  stack<double> rpnstack_;
+};
+
+} // namespace SOPHYA
+
+/* end of ifdef  RPNEVALUATOR_H_SEEN */
+#endif
Index: /tags/V_Nov2007/SophyaLib/SysTools/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/SysTools/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/smakefile	(revision 3445)
@@ -0,0 +1,83 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libSysTools.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
+	rm -f $(SOPHYALIBP)libSysTools.a
+ 
+$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h \
+  cexpre.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cexpre.cc
+ 
+$(SOPHYAOBJP)commander.o: commander.cc $(SOPHYAINCP)sopnamsp.h \
+  commander.h $(SOPHYAINCP)machdefs.h pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h ctimer.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h cexpre.h \
+  $(SOPHYAINCP)pexceptions.h rpneval.h \
+  $(SOPHYAINCP)srandgen.h zthread.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  commander.cc
+ 
+$(SOPHYAOBJP)ctimer.o: ctimer.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ctimer.cc
+ 
+$(SOPHYAOBJP)cxxcmplnk.o: cxxcmplnk.cc $(SOPHYAINCP)sopnamsp.h \
+  cxxcmplnk.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sspvflags.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxcmplnk.cc
+ 
+$(SOPHYAOBJP)pdlmgr.o: pdlmgr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sopnamsp.h pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pdlmgr.cc
+ 
+$(SOPHYAOBJP)periodic.o: periodic.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h periodic.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  periodic.cc
+ 
+$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h \
+  psighand.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psighand.cc
+ 
+$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h \
+  resusage.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  resusage.cc
+ 
+$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h \
+  rpneval.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rpneval.cc
+ 
+$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h \
+  zthread.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  zthread.cc
+ 
+$(SOPHYAOBJP)timing.o: timing.c timing.h
+	$(CCOMPILE) -o $@  timing.c
+ 
Index: /tags/V_Nov2007/SophyaLib/SysTools/systools.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/systools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/systools.h	(revision 3445)
@@ -0,0 +1,24 @@
+#ifndef SYSTOOLS_H
+#define SYSTOOLS_H
+
+/*!
+   \defgroup SysTools SysTools module
+   This module contains interface to various services provided
+   by the operating system, such as threads, dynamic load, 
+   and ressource usage. It also contains various utility classes
+   such as the Commander interpreter.
+   
+*/
+
+#include "ctimer.h"
+#include "timing.h"
+#include "pdlmgr.h"
+#include "cxxcmplnk.h"
+#include "periodic.h"
+#include "psighand.h"
+#include "resusage.h"
+#include "cexpre.h"
+#include "rpneval.h"
+#include "commander.h"
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/SysTools/timing.c
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/timing.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/timing.c	(revision 3445)
@@ -0,0 +1,125 @@
+/*    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=0, CPUT=0;
+static time_t ELT0=0, ELT=0;
+/*-------  modifs Christophe 30/09/04
+On somme nous memes les temps partiels pour avoir une autre
+mesure du temps CPU total. En effet, pour des jobs longs
+clock()-CPUT0 depasse la possibilite de stockage d'un entier
+32 bits car clock() renvoit des microsecondes.
+Par exemple pour un job de 20h = 72e+9 micro-secondes > 2^32
+(Ca ne marche plus pour des jobs > 2146 sec ~= 2^32 microsec)
+Seul un entier 64 bits pourrait donner un resultat correct
+mais il n'existe pas sur toutes les plateformes.
+-------*/ 
+static double tcalt_sum = 0.; 
+/* Flag ajutes par Reza le 7 Fev 2005 */ 
+static int prttim_debug=0;  /* Pour controler l'impression de la somme des temps partiels */
+static int prttim_usesum=0;  /* >0 compteur de clock a fait un tour, on utilise tcalt_sum */
+ 
+/* 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);
+tcalt_sum = 0.;
+prttim_usesum = 0;
+return;
+}
+
+/* Nouvelle-Fonction */
+/*!
+   \ingroup SysTools
+   Actvates (dbg>0) or deactivates (dbg=0) printing of sum of partial elapsed times.
+*/
+void PrtTimSetDebug(int dbg)
+{
+  prttim_debug = dbg;
+} 
+/* Nouvelle-Fonction */
+/*!
+   \ingroup SysTools
+   Prints the values of the CPU and elapsed time, since call to \b InitTim().
+*/
+void PrtTim(const char * Comm)
+{
+double tcal,tcalt;
+clock_t cput;
+time_t elt;
+unsigned long etm,etmt;
+
+cput = clock();
+tcalt = ( (double)(cput) - (double)(CPUT0) ) / (double)(CLOCKS_PER_SEC);
+tcal = ( (double)(cput) - (double)(CPUT) ) / (double)(CLOCKS_PER_SEC);
+
+elt = time(NULL);
+etm = elt - ELT;
+etmt = elt - ELT0;
+/*-------  modifs Christophe 30/09/04
+- tcalt_sum en 1/100 ieme de seconde:
+  On imprime des Secondes que l'on somme N fois
+  -> on se donne une precision a 1/100 de Seconde
+- Au moment ou clock()>2^32 tcal devient negatif
+  ==> On ne somme donc pas tcal et on TRICHE en sommant "etm"
+      (pour etre vrai il faut que le process ait 100% du CPU !)
+-------*/
+if(tcal>0.) { 
+  tcalt_sum += tcal*100.; 
+  if (prttim_debug > 0) printf("PrtTim/Warning - tcalt_sum will now be used ...\n");
+}
+else  tcalt_sum += (double)etm*100.;
+
+if (prttim_usesum)  tcalt = tcalt_sum/100.;
+if (prttim_debug > 0) 
+  printf("%s CPUTime: Total= %g  (Sum~= %.1f) (Partial= %g) Sec. \n",
+         Comm, tcalt, tcalt_sum/100., tcal);
+else 
+  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_Nov2007/SophyaLib/SysTools/timing.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/timing.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/timing.h	(revision 3445)
@@ -0,0 +1,20 @@
+/*   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 PrtTimSetDebug(int dbg);  
+void PrtTim(const char * Comm);                                                        
+                                                                              
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Nov2007/SophyaLib/SysTools/zthread.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/zthread.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/zthread.cc	(revision 3445)
@@ -0,0 +1,254 @@
+// Interface C++ aux Thread POSIX  -   R. Ansari 02/2001
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "zthread.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <signal.h>
+
+/*!
+  \class SOPHYA::ZThread
+  \ingroup SysTools
+  \brief Simple class for creating and controlling threads.
+
+  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 two 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);
+  void zthr_sig_exit(int s);
+}
+*/
+
+static int _RCR_ = 99;
+static void * zthr_run(void * xthr)
+{
+  ZThread * thr = (ZThread *)xthr;
+  thr->run_p();
+  return &_RCR_;
+}
+
+static void zthr_cleanup(void * xthr)
+{
+  ZThread * thr = (ZThread *)xthr;
+  if(thr->_status == 1) thr->_status = 2;
+  return;
+}
+
+static int _RCS_ = 97;
+static void zthr_sig_exit(int s)
+{
+  printf("zthr_sig_exit(int s=%d)  signal received -> pthread_exit()\n",s);
+  pthread_exit(&_RCS_);
+}
+
+/* ------ Classe ZThread  -------  */
+/*!
+  Constructor, with optional specification of the thread stack size.
+*/
+ZThread::ZThread(size_t stacksize)
+{
+  _status = 0;
+  _ssize = 0;
+  _act = NULL;
+  _usp = NULL;
+  _rc = -99;
+}
+
+ZThread::~ZThread()
+{
+  // Que faut-il faire ?
+}
+
+/*!
+  Method which starts the thread.
+*/
+void ZThread::start()
+{
+  if ( IfStarted() ) 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");     
+  setRC(rc);      
+}
+
+/*!
+  Calls the pthread_cancel. Can be used to stop a running thread.
+*/
+void ZThread::cancel()
+{
+  if ( !IfStarted() ) throw ZThreadExc("ZThread::cancel() - thread not started !");
+  int rc = pthread_cancel(_thr);
+  CheckSt(rc,"ZThread::cancel() - Pb pthread_cancel() ");  
+  setRC(-77);      
+}
+
+/*!
+  Calls the pthread_kill to deliver a signal to the corresponding thread
+*/
+void ZThread::kill(int sig)
+{
+  if ( !IfStarted() ) throw ZThreadExc("ZThread::kill() - thread not started !");
+  int rc = pthread_kill(_thr, sig);
+  CheckSt(rc,"ZThread::kill() - Pb pthread_kill() ");  
+  setRC(-76);      
+}
+
+
+/*!
+  \brief Waits for the thread to terminate (call pthread_join() )
+*/
+void ZThread::join()
+{
+  if ( !IfStarted() ) throw ZThreadExc("ZThread::join() - thread not started !");
+  void * x;
+  int rc = pthread_join(_thr, &x);
+  CheckSt(rc,"ZThread::Join() - Pb pthread_join() ");
+  return;  
+}
+
+/*!
+  \brief Method which does the actual computation 
+  This virtual method can be redefined in the derived class, in order 
+  to perform the actual computation. The default implementation call
+  the action function (if defined by setAction() )
+  
+*/
+void ZThread::run()
+{
+  if (_act)  _act(_usp);
+  setRC(0);      
+  return;
+}
+
+/*!
+  \brief Method called by the function passed to pthread_create().
+  This method sets the clean-up handler, changes the status variable
+  and call the run() method, and pthread_exit() at the end.
+*/
+void ZThread::run_p()
+{
+  _status = 1;
+  pthread_cleanup_push(zthr_cleanup, (void *)this);
+  run();
+  _status = 2;
+  pthread_exit(&(_rc));
+  pthread_cleanup_pop(0);
+  return;
+}
+
+
+void ZThread::ActivateExitOnSignal(int sig)
+{
+  struct sigaction ae, ad;
+
+  ae.sa_handler = zthr_sig_exit;
+  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
+  printf(" Activating signal %d  handling for threads -> pthread_exit()\n",sig);
+  sigaction(sig, &ae, NULL);
+}
+
+
+/* ------ Classe ZMutex -------  */
+/*!
+  \class SOPHYA::ZMutex
+  \ingroup SysTools
+  \brief Wrapper for a pair of (Mutex,Cond.Var) objects.
+
+  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. 
+  When the \b signal() method is called, one of the waiting threads
+  on the corresponding mutex object (\b ZMutex::wait()) is awakened. 
+  All waiting threads on the mutex object are awakened when \b broadcast()
+  is called.
+  \sa SOPHYA::ZSync
+*/
+
+/*!
+  Constructor: Creates a associated pair of POSIX \c pthread_mutex_t 
+  and \c pthread_cond_t objects
+  \param : if fgd == true , the destructor call pthread_mutex_destroy/pthread_cond_destroy
+*/
+ZMutex::ZMutex(bool fgd)
+{
+  _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");
+  _fgd = fgd;
+}
+
+ZMutex::~ZMutex()
+{
+  if (_fgd == false) return;
+  int rc;
+  rc = pthread_mutex_destroy(_mutx);
+  CheckSt(rc,"ZMutex::~ZMutex() Pb pthread_mutex_destroy");
+  rc = pthread_cond_destroy(_condv);
+  CheckSt(rc,"ZMutex::~ZMutex() Pb pthread_cond_destroy");  
+  delete _mutx;
+  delete _condv;
+}
+
+/*!
+  \class SOPHYA::ZSync
+  \ingroup SysTools
+  \brief Wrapper/utility class ensuring synchronised execution of an instruction bloc.
+
+  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_Nov2007/SophyaLib/SysTools/zthread.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/SysTools/zthread.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/SysTools/zthread.h	(revision 3445)
@@ -0,0 +1,167 @@
+// 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 <signal.h>
+#include "pexceptions.h"
+
+
+namespace SOPHYA {
+
+typedef void (* ZThreadAction) (void *);
+
+/*!
+  \class ZThreadExc
+  \ingroup SysTools
+  \brief Exception class used by ZThread and ZMutex classes.
+*/  
+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();
+  void          kill(int sig);
+
+  void          join();
+  virtual void  run();
+
+  //! Returns true if the thread has been created / started
+  bool IfStarted() { return ((_status > 0) ? true : false); }
+  //! Returns true if the thread is running 
+  bool IfRunning() { return ((_status == 1) ? true : false); }
+  //! Returns true if the thread has ended normally 
+  bool IfEnded() { return ((_status == 2) ? true : false); }
+  //! Returns true if the thread has been stopped (killed/canceled) 
+  bool IfStopped() { return ((_status == 3) ? true : false); }
+
+  //! 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() { return(_rc);
+ }
+  //! Defines the function which is executed by the default run() method
+  inline void	setAction(ZThreadAction act, void * usp=NULL)
+       {  _act = act;  _usp = usp; }
+
+  //! Call this method to activate the stop/exit handler on signal \b sig
+  static void ActivateExitOnSignal(int sig=SIGUSR1);
+
+  /*!
+    \brief Set/changes the current thread cancelability state 
+    see pthread_setcancelstate()
+    \b st = PTHREAD_CANCEL_ENABLE  or PTHREAD_CANCEL_DISABLE
+  */
+  static inline void setCancelState(int st= PTHREAD_CANCEL_ENABLE) 
+       { int ocs; pthread_setcancelstate(st, &ocs); }
+  // PTHREAD_CANCEL_ENABLE  ou PTHREAD_CANCEL_DISABLE
+
+  /*!
+    \brief Set/changes the current thread cancelability state 
+    see pthread_setcanceltype()
+    \b ct = PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS
+  */
+  static inline void setCancelType(int ct= PTHREAD_CANCEL_DEFERRED) 
+       { int oct; pthread_setcanceltype(ct, &oct); }
+  // PTHREAD_CANCEL_DEFERRED  ou  PTHREAD_CANCEL_ASYNCHRONOUS
+
+  virtual void  run_p();
+
+  // ---- Attribute variables ----
+  pthread_t _thr;
+  size_t _ssize;
+  int _rc;
+  int _status; // 0 : not started, 1: running, 2: ended, 3:stopped 
+
+  ZThreadAction _act;
+  void * _usp;
+};
+
+
+class ZMutex {
+public:
+  explicit	ZMutex(bool fgd=false);
+  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); }
+
+protected:
+  ZMutex(ZMutex const & a) 
+    { throw ForbiddenError("ZMutex::ZMutex(ZMutex const & ) forbidden"); }
+  ZMutex& operator = (ZMutex const & a) 
+    { throw ForbiddenError("ZMutex:: operator = (ZMutex const & a) forbidden"); }
+
+  // Attributes
+  pthread_mutex_t *  _mutx;
+  pthread_cond_t *  _condv;
+  bool _fgd;
+};
+
+
+class ZSync {
+public:
+/*!
+  Constructor. Locks the associated ZMutex. 
+  
+  - <tt> sigbr==0 </tt> No calls to signal() or broadcast() 
+  in destructor 
+  - <tt> sigbr==1 </tt> destructor calls \c signal on 
+  the associated ZMutex 
+  - <tt> sigbr==2 </tt> destructor calls \c broadcast on 
+  the associated ZMutex 
+*/
+  explicit inline  ZSync(ZMutex & mtx, int sigbr=0) 
+  {_mtx = &mtx; _sigbr = sigbr; _mtx->lock(); }
+
+/*!
+  Constructor from ZMutex pointer. 
+  Locks the associated ZMutex object if non null pointer 
+*/ 
+  explicit inline  ZSync(ZMutex * mtxp, int sigbr=0) 
+  {_mtx = mtxp; _sigbr = sigbr; if (_mtx) _mtx->lock(); }
+  inline	   ~ZSync() 
+  { 
+    if (_mtx) { 
+      if (_sigbr == 1) _mtx->signal(); 
+      else  if (_sigbr == 2) _mtx->broadcast(); 
+      _mtx->unlock(); 
+    }
+  }
+//! Calls the wait method on the associated ZMutex object
+  inline void wait() { if (_mtx) _mtx->wait(); }
+//! To avoid warnings about unused variables 
+  inline int NOp() { return _sigbr; } 
+
+private:
+  ZMutex * _mtx;
+  int _sigbr;
+  inline	ZSync() {_mtx = NULL; _sigbr = 0; }
+
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/Makefile	(revision 3445)
@@ -0,0 +1,196 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libTArray.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basarr.o $(SOPHYAOBJP)fioarr.o $(SOPHYAOBJP)matharr.o $(SOPHYAOBJP)sopemtx.o $(SOPHYAOBJP)tarray.o $(SOPHYAOBJP)tarrinit.o $(SOPHYAOBJP)tmatrix.o $(SOPHYAOBJP)tvector.o $(SOPHYAOBJP)utilarr.o
+	rm -f $(SOPHYALIBP)libTArray.a
+ 
+$(SOPHYALIBP)libTArray.a : $(SOPHYAOBJP)basarr.o $(SOPHYAOBJP)fioarr.o $(SOPHYAOBJP)matharr.o $(SOPHYAOBJP)sopemtx.o $(SOPHYAOBJP)tarray.o $(SOPHYAOBJP)tarrinit.o $(SOPHYAOBJP)tmatrix.o $(SOPHYAOBJP)tvector.o $(SOPHYAOBJP)utilarr.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)basarr.o: basarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basarr.cc
+ 
+$(SOPHYAOBJP)fioarr.o: fioarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h fioarr.h \
+  $(SOPHYAINCP)machdefs.h tarray.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h tmatrix.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fioarr.cc
+ 
+$(SOPHYAOBJP)matharr.o: matharr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h matharr.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  matharr.cc
+ 
+$(SOPHYAOBJP)sopemtx.o: sopemtx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h sopemtx.h tmatrix.h \
+  tarray.h basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopemtx.cc
+ 
+$(SOPHYAOBJP)tarray.o: tarray.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tarray.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tarray.cc
+ 
+$(SOPHYAOBJP)tarrinit.o: tarrinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h fioarr.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h tmatrix.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tarrinit.cc
+ 
+$(SOPHYAOBJP)tmatrix.o: tmatrix.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tmatrix.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmatrix.cc
+ 
+$(SOPHYAOBJP)tvector.o: tvector.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tvector.h tmatrix.h \
+  tarray.h basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tvector.cc
+ 
+$(SOPHYAOBJP)utilarr.o: utilarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utilarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)stsrand.h \
+  $(SOPHYAINCP)ndatablock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utilarr.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/TArray/Makefile.am
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/Makefile.am	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/Makefile.am	(revision 3445)
@@ -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_Nov2007/SophyaLib/TArray/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/Makefile.mgr	(revision 3445)
@@ -0,0 +1,111 @@
+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 \
+ $(INC)datatype.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_Nov2007/SophyaLib/TArray/array.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/array.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/array.h	(revision 3445)
@@ -0,0 +1,16 @@
+// 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"
+#include "arrctcast.h"
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/arrctcast.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/arrctcast.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/arrctcast.h	(revision 3445)
@@ -0,0 +1,137 @@
+#ifndef ARRCTCAST_SEEN
+#define ARRCTCAST_SEEN
+//----------------------------------------------------
+//    SOPHYA class library 
+// (C) LAL-IN2P3/CNRS         (C) DAPNIA-CEA  
+//             R. Ansari - Oct 2006
+//----------------------------------------------------
+
+#include "tarray.h"
+
+namespace SOPHYA {
+
+//-----------------------------------------------------------------------
+// Classe de Bridge et fonctions utilitaires pour permettre des 
+// cast de type de donnees - sans conversion - pour des tableaux (TArray)
+//-----------------------------------------------------------------------
+
+//******************************************
+// Classe NDCBridge : Bridge sur NDataBlock, utile pour cast - sans conversion - de type 
+/*! 
+  \class NDCBridge
+  \brief Special Bridge class to be used the ArrayCast class 
+  \ingroup TArray 
+*/
+template <class T>
+class NDCBridge : public Bridge {
+ public:
+  NDCBridge(NDataBlock< T > & db) : dbcs_(db) { 
+  //DBG cout << "+++ NDCBridge() this= " << hex << (long int)this << dec << endl; 
+  }
+  virtual ~NDCBridge() {
+  //DBG cout << "--- ~NDCBridge() this= " << hex << (long int)this << dec << endl; 
+  }
+ protected:
+  NDataBlock< T > dbcs_;
+};
+
+//******************************************
+// Fonction de cast de type de contenu - sans conversion - de tableaux
+// pour tableau packe en memoire
+/*! 
+  \ingroup TArray 
+  \brief Function to handle Array content cast without conversion (shared data)
+*/
+template <class T1, class T2>								    
+TArray< T2 > ArrayCast( TArray< T1 > & a, T2 ct, sa_size_t doff=0, sa_size_t dstep=1) 
+{
+  NDCBridge< T1 > * db = new NDCBridge< T1 >(a.DataBlock());
+  //      if (a.AvgStep() != 1)
+  if (a.IsPacked() == false)
+    throw ParmError("ArrayCast - Pb: Not a packed array");
+  float rs = (float)sizeof(T1)/(float)sizeof(T2);
+  //DBG cout << "--DBG-ArrayCast SizeOf T1= " << sizeof(T1)
+  //DBG     << " T2= " << sizeof(T2) << " rs=T1/T2= " << rs << endl;
+  
+  int_4 ndim = a.Rank();
+  sa_size_t sz[BASEARRAY_MAXNDIMS];
+  for(int_4 k=0; k<BASEARRAY_MAXNDIMS; k++)   sz[k] = 0;
+  for(int_4 k=0; k<ndim; k++)  sz[k] = a.Size(k);
+  // Pour gerer correctement les vecteurs colonnes
+  int kszsc = 0;
+  if ((sz[0] == 1) && (sz[1] > 1))   kszsc = 1;
+  if (dstep > 1) 
+    sz[kszsc] = sz[kszsc]*sizeof(T1)/sizeof(T2)/dstep;
+  else 
+    sz[kszsc] = sz[kszsc]*sizeof(T1)/sizeof(T2);
+  //DBG  cout << " --DBG-ArrayCast SzX=" << a.SizeX() 
+  //     << " rs=" << rs << " dstep=" << dstep << " --> SzX=" << sz[0] << endl;
+  
+  sa_size_t step = dstep; 
+  sa_size_t off = doff; 
+  TArray< T2 > ac(ndim, sz, (T2 *)(a.Data()), step, off, db);
+  ac.SetMemoryMapping(a.GetMemoryMapping());
+  ac.SetTemp(true);
+  return ac;
+}
+
+
+//******************************************
+// cast de contenu - sans conversion - tableau complex vers float
+/*! 
+  \ingroup TArray 
+  \brief Complex to real array cast - without conversion (shared data) 
+*/
+template <class T>
+TArray<T> ArrCastC2R(TArray< complex<T> > & a)  
+{
+  T x = 0;
+  return ArrayCast(a, x);
+}
+
+//******************************************
+// cast de contenu - sans conversion - tableau float vers complex
+/*! 
+  \ingroup TArray 
+  \brief Real to complex array cast - without conversion (shared data)
+*/
+template <class T>
+TArray< complex<T> > ArrCastR2C(TArray< T > & a)  
+{
+  complex<T> x = 0;
+  //  return ArrayCast< TArray< T > , complex<T> > (a, x);
+  return ArrayCast(a, x);
+}
+
+
+//******************************************
+// Acces a la partie reelle d'un tableau complex - en shared data
+// To access real part of a complex array (shared data)
+/*! 
+  \ingroup TArray 
+  \brief Return the real part of a complex array (shared data)
+*/
+template <class T>
+TArray<T> SDRealPart(TArray< complex<T> > & a)  
+{
+  T x = 0;
+  return ArrayCast(a, x, 0, 2);
+}
+
+//******************************************
+// Acces a la partie imaginaire d'un tableau complex - en shared data
+// To access imaginary part of a complex array (shared data)
+/*! 
+  \ingroup TArray 
+  \brief Return the imaginary part of a complex array (shared data)
+*/
+template <class T>
+TArray<T> SDImagPart(TArray< complex<T> > & a)  
+{
+  T x = 0;
+  return ArrayCast(a, x, 1, 2);
+}
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/basarr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/basarr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/basarr.cc	(revision 3445)
@@ -0,0 +1,755 @@
+//      Base class for numerical arrays 
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "sopnamsp.h"
+#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;
+uint_2 BaseArray::matrix_product_optim = 1;
+
+// ------ Methodes statiques globales --------
+
+//! Set optimization strategy for matrix product
+/*!
+  \param opt : bit coded optimization strategy
+  \warning Default is opt=1
+  \verbatim
+  bit 0 : choose matrix product optimization or not
+        0=no optimization, 1=optimization
+  bit 1 : force optimization in any case (only if bit0=1)
+          (if not the TMatrix::Multiply method decide or
+           not if the product should be optimized)
+        0=do not force and let the method decide, 1=force
+  bit 2 : optimize the product A * B when A-columns and
+          B-rows are not packed (for example if the product
+          is C = ("A Fortran-like" * "B C-like").
+        . That will do a copy of one of the two matrices,
+          so that will result in an increase of the memory
+          space needed.
+        . For big matrices that decrease the computing time.
+        . Do not use this optimisation for small matrices
+          because that would increase the computing time.
+        0=do not optimze that way, 1=optimze that way
+  \endverbatim
+  \verbatim
+   Sumary of the allowed values for "opt"
+           0 = no optimization at all (whatever the other bits are)
+           1 = optimize but let the method decides if optimization
+               is needed regarding the sizes of the matrices.
+           3 = force optimization whatever the sizes of the matrices are.
+           5 = optimisation with method decision ("1")
+               AND optimize by copying when A-columns and B-rows
+               are not packed
+           7 = force optimization ("3")
+               AND optimize by copying when A-columns and B-rows
+               are not packed
+  \endverbatim
+*/
+void BaseArray::SetMatProdOpt(uint_2 opt)
+{
+  matrix_product_optim = opt;
+}
+
+//! 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()
+{
+  if (mInfo) { delete mInfo; mInfo = NULL; }
+}
+
+
+//! 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);
+  }
+}
+
+//! Compact arrays - supresses size=1 axes.
+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;
+}
+
+//! Compact array taling dimensions, for size=1 traling axes.
+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[k] = size_[k];
+    step[k] = step_[k];
+    if (size_[k] > 1)  ndim=k+1;
+  }
+  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]={0,0,0,0,0};
+  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 << "#--- " << BaseArray::InfoString() << " Unallocated Array ! " << endl;
+    return;
+  } 
+  os << "#--- " << 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 information for sub-array \b ra
+/*!
+  \param ra : sub-array for which size information has to be computed 
+  \param ndim : number of dimensions for \b ra
+  \param siz[ndim],pos[ndim],step[ndim] : number of elements, offset and step along each dimension,
+   relative to the original array.
+  \warning throw SzMismatchError in case of incompatible dimensions.
+ */
+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]-1)*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;
+}
+
+//! Set the array sizes to zero, corresponding to an unallocated array
+void BaseArray::SetZeroSize()
+{
+  ndim_ = 0;
+  for(int_4 k=0; k<BASEARRAY_MAXNDIMS; k++) step_[k] = size_[k] = 0;
+  totsize_ = 0;
+  minstep_ = 0;
+  moystep_ = 0;
+  offset_ = 0;
+  // On ne change pas l'organisation memoire, le type de vecteur
+  // et le array type
+}
+
Index: /tags/V_Nov2007/SophyaLib/TArray/basarr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/basarr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/basarr.h	(revision 3445)
@@ -0,0 +1,254 @@
+// 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>
+#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; }
+
+  //! Optimization choice for matrix product
+  static void SetMatProdOpt(uint_2 opt=1);
+  static inline uint_2 GetMatProdOpt(void) {return matrix_product_optim;}
+  
+  // Creator / destructor
+  BaseArray();
+  virtual ~BaseArray();
+
+  // Returns true if ndim and sizes are equal
+  virtual bool CompareSizes(const BaseArray& a, bool& smo) const;
+
+  // 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;
+  virtual MuTyV & ValueAtPositionDB(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 ;
+  // Compacts size=1 array dimensions
+  void CompactAllDim(); // suppresses all size==1 dimensions 
+  void CompactTrailingDim(); // suppresses size==1 dimensions after the last size>1 dimension
+  // 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;
+
+  // Pour mettre les tailles a zero
+  virtual void SetZeroSize();
+
+  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
+  static uint_2 matrix_product_optim; //!< optimization level for matrix product
+};
+
+// --------------------------------------------------
+//        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_Nov2007/SophyaLib/TArray/fioarr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/fioarr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/fioarr.cc	(revision 3445)
@@ -0,0 +1,247 @@
+//     Persistence manager for template numerical arrays
+//               R. Ansari, C.Magneville   03/2000
+
+#include "sopnamsp.h"
+#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<uint_4>
+#pragma define_template FIO_TArray<uint_8>
+#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<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)
+namespace SOPHYA {
+// Instances des delegues FileIO (PPersist)
+// template class FIO_TArray<uint_1>;
+template class FIO_TArray<uint_2>;
+template class FIO_TArray<uint_4>;
+template class FIO_TArray<uint_8>;
+template class FIO_TArray<int_2>;
+template class FIO_TArray<int_4>;
+template class FIO_TArray<int_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_Nov2007/SophyaLib/TArray/fioarr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/fioarr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/fioarr.h	(revision 3445)
@@ -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>
+#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); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/matharr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/matharr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/matharr.cc	(revision 3445)
@@ -0,0 +1,498 @@
+//  Usuall mathematical functions and operations on arrays
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "sopnamsp.h"
+#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>::ApplyFunctionInPlaceF(TArray<T> & a, Arr_FloatFunctionOfX f)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("MathArray<T>::ApplyFunctionInPlaceF(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>::ApplyFunctionF(TArray<T> const & a, Arr_FloatFunctionOfX f)
+{
+  TArray<T> ra;
+  ra = a;
+  ApplyFunctionInPlaceF(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;
+  if (dsz > 1.5) {
+    sig = sig/dsz - mean*mean;
+    sig *= (dsz/(dsz-1));
+    if (sig >= 0.) sig = sqrt(sig);
+  }
+  else sig = 0.;
+  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)
+namespace SOPHYA {
+template class MathArray<r_4>;
+template class MathArray<r_8>;
+template class ComplexMathArray<r_4>;
+template class ComplexMathArray<r_8>;
+}
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/matharr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/matharr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/matharr.h	(revision 3445)
@@ -0,0 +1,183 @@
+// 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:
+  virtual ~MathArray(void) {};
+
+// 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>&  ApplyFunctionInPlaceF(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>  ApplyFunctionF(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:
+  virtual ~ComplexMathArray(void) {};
+
+// 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_Nov2007/SophyaLib/TArray/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/objlist.list	(revision 3445)
@@ -0,0 +1,9 @@
+basarr.o
+fioarr.o
+matharr.o
+sopemtx.o
+tarray.o
+tarrinit.o
+tmatrix.o
+tvector.o
+utilarr.o
Index: /tags/V_Nov2007/SophyaLib/TArray/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libsophya.so
Index: /tags/V_Nov2007/SophyaLib/TArray/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/smakefile	(revision 3445)
@@ -0,0 +1,196 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libTArray.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basarr.o $(SOPHYAOBJP)fioarr.o $(SOPHYAOBJP)matharr.o $(SOPHYAOBJP)sopemtx.o $(SOPHYAOBJP)tarray.o $(SOPHYAOBJP)tarrinit.o $(SOPHYAOBJP)tmatrix.o $(SOPHYAOBJP)tvector.o $(SOPHYAOBJP)utilarr.o
+	rm -f $(SOPHYALIBP)libTArray.a
+ 
+$(SOPHYALIBP)libTArray.a : $(SOPHYAOBJP)basarr.o $(SOPHYAOBJP)fioarr.o $(SOPHYAOBJP)matharr.o $(SOPHYAOBJP)sopemtx.o $(SOPHYAOBJP)tarray.o $(SOPHYAOBJP)tarrinit.o $(SOPHYAOBJP)tmatrix.o $(SOPHYAOBJP)tvector.o $(SOPHYAOBJP)utilarr.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
+ 
+$(SOPHYAOBJP)basarr.o: basarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basarr.cc
+ 
+$(SOPHYAOBJP)fioarr.o: fioarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h fioarr.h \
+  $(SOPHYAINCP)machdefs.h tarray.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h tmatrix.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fioarr.cc
+ 
+$(SOPHYAOBJP)matharr.o: matharr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h matharr.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  matharr.cc
+ 
+$(SOPHYAOBJP)sopemtx.o: sopemtx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h sopemtx.h tmatrix.h \
+  tarray.h basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)smathconst.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopemtx.cc
+ 
+$(SOPHYAOBJP)tarray.o: tarray.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tarray.h basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tarray.cc
+ 
+$(SOPHYAOBJP)tarrinit.o: tarrinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h fioarr.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h tmatrix.h \
+  tmatrix_tsnl.h tvector.h tvector_tsnl.h \
+  $(SOPHYAINCP)ppersist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tarrinit.cc
+ 
+$(SOPHYAOBJP)tmatrix.o: tmatrix.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tmatrix.h tarray.h \
+  basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmatrix.cc
+ 
+$(SOPHYAOBJP)tvector.o: tvector.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h tvector.h tmatrix.h \
+  tarray.h basarr.h $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)ndatablock.h utilarr.h \
+  tmatrix_tsnl.h tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tvector.cc
+ 
+$(SOPHYAOBJP)utilarr.o: utilarr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h utilarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)stsrand.h \
+  $(SOPHYAINCP)ndatablock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  utilarr.cc
+ 
Index: /tags/V_Nov2007/SophyaLib/TArray/sopemtx.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/sopemtx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/sopemtx.cc	(revision 3445)
@@ -0,0 +1,778 @@
+//                         C.Magneville, R.Ansari        03/2000
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <iostream>
+#include <complex>
+#include <math.h>
+#include "sopemtx.h"
+#include "smathconst.h"
+
+////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------- //
+//  La classe de gestion des lignes et colonnes d'une matrice //
+// ---------------------------------------------------------- //
+////////////////////////////////////////////////////////////////
+
+/*! \cond
+  \class SOPHYA::TMatrixRC
+  \ingroup TArray
+  Class for representing rows, columns and diagonal of a matrix.
+  \sa TMatrix TArray
+*/
+
+/*! \endcond */
+
+namespace SOPHYA {
+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, sa_size_t index=0);
+  virtual ~TMatrixRC() {}
+
+  // Acces aux rangees et colonnes de matrices
+  static TMatrixRC<T> Row(TMatrix<T> & m, sa_size_t r);
+  static TMatrixRC<T> Col(TMatrix<T> & m, sa_size_t c);
+  static TMatrixRC<T> Diag(TMatrix<T> & m);
+
+  int_4 SetCol(int_4 c);
+  int_4 SetRow(int_4 r);
+  int_4 SetDiag();
+
+  static sa_size_t Step(const TMatrix<T>& m, TRCKind rckind);
+  static T* Org(const TMatrix<T>&, TRCKind rckind, sa_size_t ind=0);
+
+  //! Return the kind of TMatrix (line,column,diagonal)
+  TRCKind Kind() const { return kind; }
+  sa_size_t NElts() const;
+  T& operator()(sa_size_t i);
+  T  operator()(sa_size_t i) const;
+
+
+   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, sa_size_t first=0);
+  TMatrixRC<T>& LinComb(T b, const TMatrixRC<T>& rc, sa_size_t first=0);
+
+  sa_size_t IMaxAbs(sa_size_t 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 sa_size_t
+  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
+  sa_size_t      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(sa_size_t 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 sa_size_t 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, sa_size_t 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 sa_size_t 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()(sa_size_t i) {return data[i*step];}
+//! access of element \b i
+template <class T>
+inline T  TMatrixRC<T>::operator()(sa_size_t 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,sa_size_t 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, sa_size_t 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, sa_size_t 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;
+}
+
+
+
+//! 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;
+}
+
+
+//! Operator to multiply by constant \b x
+template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x)
+{
+for(sa_size_t 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(sa_size_t 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, sa_size_t first)
+{
+if ( NElts() != rc.NElts() )
+  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
+if ( kind != rc.kind )
+  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
+for(sa_size_t 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, sa_size_t first)
+{
+if ( NElts() != rc.NElts() )
+  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
+if ( kind != rc.kind )
+  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
+for(sa_size_t 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> sa_size_t TMatrixRC<T>::IMaxAbs(sa_size_t first)
+{
+if (first>NElts())
+  throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n"));
+sa_size_t imax = first;
+double vmax = Abs_Value((*this)(first));
+for(sa_size_t 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(sa_size_t 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(sa_size_t 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);}
+{
+sa_size_t 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(sa_size_t iii=0; iii<a.NRows(); iii++) {
+    sa_size_t 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(sa_size_t iii=0; iii<a.NRows(); iii++)
+    for(sa_size_t 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(sa_size_t k=0; k<n-1; k++) {
+  sa_size_t 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 (sa_size_t 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(sa_size_t 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(sa_size_t 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(sa_size_t 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,
+                       sa_size_t nf, T (*f)(sa_size_t,T), TVector<T>& c)
+{
+sa_size_t n = x.NElts();
+if (n != y.NElts()) 
+  throw SzMismatchError("LinFitter<T>::LinFit(x,y,nf,f,c)/Error x.NElts() <> y.Nelts() ");
+ 
+TMatrix<T> fx(nf,n);
+
+for(sa_size_t i=0; i<nf; i++)
+  for(sa_size_t 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)
+{
+sa_size_t n = y.NElts();
+if (n != fx.NCol()) 
+  throw SzMismatchError("LinFitter<T>::LinFit(fx, y, c)/Error y.NElts() <> fx.Nelts() ");
+
+sa_size_t nf = fx.NRows();
+
+TMatrix<T> a(nf,nf);
+
+for(sa_size_t j=0; j<nf; j++)
+  for(sa_size_t 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 SingMatrixExc("LinFitter<T>::LinFit(fx, y, c) - Non invertible matrix (by GausPiv())");
+
+r_8 xi2 = 0., ax;
+T x;
+for(sa_size_t k=0; k<n; k++) {
+  x = (T) 0;
+  for(sa_size_t 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, sa_size_t nf, T (*f)(sa_size_t,T),
+                                  TVector<T>& c, TVector<T>& errC)
+{
+sa_size_t n = x.NElts();
+if (n != y.NElts()) 
+  throw SzMismatchError("LinFitter<T>::LinFit(x,y,errY2,nf,f,c,errC)/Error x.NElts() <> y.Nelts() ");
+
+TMatrix<T> fx(nf, n);
+for(sa_size_t i=0; i<nf; i++)
+  for(sa_size_t 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)
+{
+sa_size_t n = y.NElts();
+if( n != errY2.NElts()) 
+  throw SzMismatchError("LinFitter<T>::LinFit(fx,y,errY2,c,errC)/Error y.NElts() <> errY2.Nelts() ");
+if( n != fx.NCol()) 
+  throw SzMismatchError("LinFitter<T>::LinFit(fx,y,errY2,c,errC)/Error y.NElts() <> fx.NCols() ");
+sa_size_t nf = fx.NRows();
+
+TMatrix<T> a(nf,nf);
+
+c.Realloc(nf);
+errC.Realloc(nf);
+
+for(sa_size_t j=0; j<nf; j++)
+  for(sa_size_t k=j; k<nf; k++) {
+    T x=0;
+    // Matrice a inverser
+    for(sa_size_t 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(sa_size_t k=0; k<nf; k++) {
+  T x = (T) 0;
+  // Second membre 1ere colonne
+  for(sa_size_t l=0; l<n; l++) x += fx(k,l)*y(l)/errY2(l);             
+  d(k,0) = x;
+  // Reste second membre = Id.
+  for(sa_size_t m=1; m<=nf; m++) d(k,m) = (k==m)?1:0;
+}
+
+if(SimpleMatrixOperation<T>::GausPiv(a,d)==(T) 0) 
+  throw SingMatrixExc("LinFitter<T>::LinFit(...ErrY2...) - Non invertible matrix (by GausPiv())");
+
+
+for(sa_size_t 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(sa_size_t jj=0; jj<n; jj++) {
+  x = (T) 0;
+  for(sa_size_t 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;
+}
+
+} // Fin namespace SOPHYA 
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+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)
+namespace SOPHYA {
+// 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_Nov2007/SophyaLib/TArray/sopemtx.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/sopemtx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/sopemtx.h	(revision 3445)
@@ -0,0 +1,185 @@
+// 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
+  \brief Class for simple operation on TMatrix
+  This class provides presently a basic implementation of the Gauss 
+  pivoting for linear system solving and matrix inversion. 
+
+  \warning For large or ill conditioned matrices, use the methods 
+  from LinAlg module. 
+  \sa SOPHYA::LapackServer  SOPHYA::TMatrix 
+*/
+//! 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,
+	   sa_size_t nf, T (*f)(sa_size_t,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,
+           sa_size_t nf,T (*f)(sa_size_t,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_Nov2007/SophyaLib/TArray/tarray.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tarray.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tarray.cc	(revision 3445)
@@ -0,0 +1,1674 @@
+//      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 <iomanip>
+
+#include "pexceptions.h"
+#include "tarray.h"
+
+namespace SOPHYA {
+
+/*!
+  \class TArray
+  \ingroup TArray
+  Class for template arrays with numerical data types (int, float, complex).
+
+  This class handles arrays with number of dimensions up to
+  \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS" (=5). The class has a performant 
+  memory management system, including reference sharing for the array data.
+  (copy constructor and sub-arrays (or slices)). 
+
+  An important feature of this class is the transparent handling of sub-arrays,
+  or slices. Arbitrary sub-arrays or slices can be defined, provided regular 
+  spacing along each array axe (or dimension). 
+  The second example below illustrate the use of this possibility.
+  
+  Standard arithmetic operations, sum or product as well as application of usual
+  math functions (Sin, Cos ...) on numerical arrays are implemented.
+  These operations usually provide high performance, despite of the complex 
+  memory management pattern.
+
+  ASCII input/output (or read write) and binary I/O (persistence) in different
+  formats are also provided through helper (or handler) classes.
+
+  This class is mainly intented for arrays with large number of data elements.
+  (Size() \> 100 .. 1000). Arrays with few data elements (\< 10) have significant 
+  memory overhead, due to variables describing array shape and memory organisation.
+  However, a single higher dimensional array can be used to represent a large number 
+  of identical size small arrays. For example, TArray<T> tab(2,2, 1000) can be used
+  to hold 1000 2x2 matrices.
+
+  \warning Notice that array elements along the X axis are contiguous in memory, 
+  independent of the array rank (number of dimensions), for packed arrays.
+
+  \b Array is a typedef for double precision floating point arrays ( TArray<r_8> )
+
+  \sa SOPHYA::Range
+  \sa SOPHYA::Sequence
+  \sa SOPHYA::MathArray
+  \sa SOPHYA::NDataBlock
+
+  \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 = \n" << 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 = \n" << d;  
+  \endcode
+
+  Example for sub-arrays, or slices
+  \code 
+  // Creating and initialising a 2-D (6 x 4) array of integers
+  TArray<int> iaa(6, 4);
+  iaa = RegularSequence(1,2);
+  cout << "Array<int> iaa = \n" << iaa;
+  // We extract a sub-array - data is shared with iaa
+  TArray<int> iae = iaa(Range(1, Range::lastIndex(), 3) ,
+                        Range::all(), Range::first() );
+  cout << "Array<int> iae=subarray(iaa) = \n" << iae;
+  // Changing iae elements changes corresponding iaa elements
+  iae = 0;
+  cout << "Array<int> iae=0 --> iaa = \n" << iaa;
+  \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)
+  \param fzero : if \b true , set array elements to zero 
+ */
+template <class T>
+TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, sa_size_t step, bool fzero)
+  : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), fzero)
+{
+  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
+  \param fzero : if \b true , set array elements to zero 
+ */
+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, bool fzero)
+  : 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() < (size_t)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)
+  \param fzero : if \b true , set array elements to zero 
+ */
+template <class T>
+void TArray<T>::ReSize(int_4 ndim, sa_size_t * siz, sa_size_t step, bool fzero)
+{
+  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_, fzero);    
+}
+
+//! 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.
+  \param pack : if \b true , create a packed array, else same memory layout as \b a. 
+  \param fzero : if \b true , set array elements to zero 
+ */
+template <class T>
+void TArray<T>::ReSize(const BaseArray& a, bool pack, bool fzero)
+{
+  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 (pack) {
+    sa_size_t siz[BASEARRAY_MAXNDIMS];
+    int ksz;
+    for(ksz=0; ksz<a.NbDimensions(); ksz++) siz[ksz] = a.Size(ksz);
+    for(ksz=a.NbDimensions(); ksz<BASEARRAY_MAXNDIMS; ksz++) siz[ksz] = 1;
+    if (!UpdateSizes(a.NbDimensions(), siz, 1, 0, exmsg))  throw( ParmError(exmsg) );
+    SetMemoryMapping(a.GetMemoryMapping());
+    mNDBlock.ReSize(totsize_, fzero);        
+  }
+  else {
+    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);    
+}
+
+  //! To clear the array sizes - corresponding to an unallocated array.
+template <class T>
+TArray<T>&  TArray<T>::ZeroSize()
+{
+  if (NbDimensions() == 0)  return (*this);  
+  SetZeroSize();
+  mNDBlock.Dealloc();
+  return (*this); 
+}
+
+/*!
+  \brief Compact arrays - supresses size=1 axes.
+  Changes the array rank (number of dimensions), suppressing all axes with size equal 1.
+  Example: 
+  Compacting Rank=NDim=5  Sizes=3x1x6x1x1  =====\>  Rank=NDim=2  Sizes=3x6 
+*/
+template <class T>
+TArray<T>& TArray<T>::CompactAllDimensions()
+{
+  CompactAllDim();
+  return(*this);
+}
+
+/*!
+  \brief Compact array taling dimensions, for size=1 traling axes.
+  Changes the array rank (number of dimensions), suppressing all axes with size equal 1,
+  after the last axe with size \> 1
+  Example: 
+  Compacting Rank=NDim=5  Sizes=3x1x6x1x1  =====\>  Rank=NDim=3  Sizes=3x1x6 
+*/
+template <class T>
+TArray<T>& TArray<T>::CompactTrailingDimensions()
+{
+  CompactTrailingDim();
+  return(*this);
+}
+
+/*! 
+  \brief Return the value (as a MuTyV) for element at position \b ip in the array.
+  This method is used for conversion between arrays of different types. 
+  \param ip : element position in the array 
+ */
+template <class T>
+MuTyV & TArray<T>::ValueAtPosition(sa_size_t ip) const
+{
+#ifdef SO_BOUNDCHECKING
+  if ( (ip >= totsize_) || (ip < 0) )   
+    throw( ParmError("TArray<T>::ValueAtPosition(sa_size_t ip) Out-of-bound Error") );
+#endif
+  my_mtv = *(mNDBlock.Begin()+Offset(ip));
+  return( my_mtv );
+}
+
+/*! 
+  \brief Return the value (as a MuTyV) for element at position \b ip in the datablock.
+  This method is used for conversion between arrays of different types. 
+  \param ip : element position in the array DataBlock, regardless of 
+   the array memory organisation
+ */
+template <class T>
+MuTyV & TArray<T>::ValueAtPositionDB(sa_size_t ip) const
+{
+#ifdef SO_BOUNDCHECKING
+  if ( (ip >= mNDBlock.Size() ) || (ip < 0) )   
+    throw( ParmError("TArray<T>::ValueAtPositionDB(sa_size_t ip) Out-of-bound Error") );
+#endif
+  my_mtv = *(mNDBlock.Begin()+ip);
+  return( my_mtv );
+}
+
+/*!
+  \brief Return a new array with elements packed in memory
+
+
+  \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
+  \param compact : if \b compact == true, compact trailing dimensions (suppressed if =1)
+  (See CompactTrailingDimensions() )
+  \sa SOPHYA::Range
+ */
+template <class T>
+TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru, bool compact) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
+  int_4 ndim = 0;
+
+  // Updating Range objects using actual array size
+  rx.Update(SizeX());
+  ry.Update(SizeY());
+  rz.Update(SizeZ());
+  if (NbDimensions() > 3)  rt.Update(Size(3));
+  else rt.Update(0);
+  if (NbDimensions() > 4)  ru.Update(Size(4));
+  else  ru.Update(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());
+  if (compact) ra.CompactTrailingDim();
+  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++)  seq(j*gpas+k).Convert(pe[k*step]);
+//REMPLACE suite pb compil gcc4    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>::SetCst(T x)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SetCst(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 the source array and store the result in \b res. 
+/*! 
+Add a constant to the source array \b this and store the result in \b res (res = *this+x).  
+
+If not initially allocated, and if the source array (this) is not flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and (this) is temporary, data is shared between \b res and this.
+
+Returns a reference to the output array \b res. 
+
+\param x : constant to add to the array elements
+\param res : Output array containing the result (res=this+x). 
+*/
+template <class T>
+TArray<T>& TArray<T>::AddCst(T x, TArray<T>& res) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::AddCst(T,res)  - Not allocated source array ");
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else res.SetSize(*this, true, false);
+  }
+  bool smo;
+  if (!CompareSizes(res, smo)) 
+    throw(SzMismatchError("TArray<T>::AddCst(T, res) SizeMismatch(this,res) ")) ;
+
+  const T * pe;
+  T * per;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (res.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    per = res.Data();
+    for(k=0; k<maxx; k++)  *per++ = *pe++ + x;  
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axr;
+    sa_size_t step, stepr;
+    sa_size_t gpas, naxa;
+    GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = *pe+x; 
+    }
+  }
+  return(res);
+}
+
+//! Subtract a constant value \b x from the source array and store the result in \b res. 
+/*! 
+Subtract a constant from the source array \b this and store the result in \b res (res = *this-x).  
+
+If not initially allocated, and if the source array (this) is not flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and (this) is temporary, data is shared between \b res and this.
+
+Returns a reference to the output array \b res. 
+
+\param x : constant to subtract from the array elements
+\param res : Output array containing the result (res=this+x or res=x-this). 
+\param fginv == true : Invert subtraction argument order (res = x-(*this)) 
+*/
+template <class T>
+TArray<T>& TArray<T>::SubCst(T x, TArray<T>& res, bool fginv) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SubCst(T,res)  - Not allocated source array ");
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else res.SetSize(*this, true, false);
+  }
+  bool smo;
+  if (!CompareSizes(res, smo)) 
+    throw(SzMismatchError("TArray<T>::SubCst(T, res) SizeMismatch(this,res) ")) ;
+
+  const T * pe;
+  T * per;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (res.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    per = res.Data();
+    if (!fginv) 
+      for(k=0; k<maxx; k++)  *per++ = *pe++ - x;  
+    else 
+      for(k=0; k<maxx; k++)  *per++ = x - *pe++; 
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axr;
+    sa_size_t step, stepr;
+    sa_size_t gpas, naxa;
+    GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      if (!fginv) 
+        for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = *pe-x; 
+       else
+        for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = x-*pe; 
+    }
+  }
+  return(res);
+}
+
+//! Multiply the source array by a constant value \b x and store the result in \b res. 
+/*! 
+Multiply the source array \b this by a constant \b x and store the result in \b res (res = *this*x).  
+
+If not initially allocated, and if the source array (this) is not flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and (this) is temporary, data is shared between \b res and this.
+
+Returns a reference to the output array \b res. 
+
+\param x : Array elements are multiplied by x
+\param res : Output array containing the result (res=this*x). 
+*/
+template <class T>
+TArray<T>& TArray<T>::MulCst(T x, TArray<T>& res) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::MulCst(T,res)  - Not allocated source array ");
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else res.SetSize(*this, true, false);
+  }
+  bool smo;
+  if (!CompareSizes(res, smo)) 
+    throw(SzMismatchError("TArray<T>::MulCst(T, res) SizeMismatch(this,res) ")) ;
+
+  const T * pe;
+  T * per;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (res.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    per = res.Data();
+    for(k=0; k<maxx; k++)  *per++ = *pe++ * x;  
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axr;
+    sa_size_t step, stepr;
+    sa_size_t gpas, naxa;
+    GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = (*pe)*x; 
+    }
+  }
+  return(res);
+}
+
+//! Divide the source array by a constant value \b x and store the result in \b res.
+/*! 
+Divide the source array \b this by a constant \b x and store the result in \b res (res = *this/x).  
+
+If not initially allocated, and if the source array (this) is not flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and (this) is temporary, data is shared between \b res and this.
+
+Returns a reference to the output array \b res. 
+
+\param x : Array elements are divied by x
+\param res : Output array containing the result (res=(*this)/x or res=x/(*this)). 
+\param fginv == true : Invert the division argument order (res = x/(*this)) 
+*/
+template <class T>
+TArray<T>& TArray<T>::DivCst(T x, TArray<T>& res, bool fginv) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::DivCst(T,res)  - Not allocated source array ! ");
+  if (!fginv && (x == (T) 0) ) 
+    throw MathExc("TArray<T>::DivCst(T,res)  - Divide by zero ! ");
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else res.SetSize(*this, true, false);
+  }
+  bool smo;
+  if (!CompareSizes(res, smo)) 
+    throw(SzMismatchError("TArray<T>::DivCst(T, res) SizeMismatch(this,res) ")) ;
+
+  const T * pe;
+  T * per;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (res.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    per = res.Data();
+    if (!fginv) 
+      for(k=0; k<maxx; k++)  *per++ = *pe++ / x;  
+    else 
+      for(k=0; k<maxx; k++) *per++ = x / *pe++; 
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axr;
+    sa_size_t step, stepr;
+    sa_size_t gpas, naxa;
+    GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      if (!fginv) 
+        for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = (*pe)/x; 
+       else
+        for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = x/(*pe); 
+    }
+  }
+  return(res);
+}
+
+
+//! Stores the opposite of the source array in \b res (res=-(*this)). 
+/*! 
+If not initially allocated, and if the source array (this) is not flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and (this) is temporary, data is shared between \b res and this.
+
+Returns a reference to the output array \b res. 
+*/
+template <class T>
+TArray<T>& TArray<T>::NegateElt(TArray<T>& res) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::NegateElt(res)  - Not allocated source array ");
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else res.SetSize(*this, true, false);
+  }
+  bool smo;
+  if (!CompareSizes(res, smo)) 
+    throw(SzMismatchError("TArray<T>::NegateElt(res) SizeMismatch(this,res) ")) ;
+
+  const T * pe;
+  T * per;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (res.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    per = res.Data();
+    for(k=0; k<maxx; k++)  *per++ = -(*pe++);  
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axr;
+    sa_size_t step, stepr;
+    sa_size_t gpas, naxa;
+    GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      for(k=0;  k<gpas;  k+=step, pe+=step, per+=stepr)  *per = -(*pe); 
+    }
+  }
+  return(res);
+}
+
+//  >>>> Operations avec 2nd membre de type tableau
+
+//! Two TArrays element by element addition
+/*! 
+Perform element by element addition of the source array (this) and the \b a array 
+and store the result in \b res (res = *this+a). The source and argument arrays (this, a)
+should have the same sizes.
+
+If not initially allocated, and if none of the source arrays is flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and one of the source array is temporary,
+data is shared between \b res and the temporary source array.
+
+Returns a reference to the output array \b res. 
+
+\param a : Array to be added to the source array.
+\param res : Output array containing the result (res=this+a). 
+*/
+template <class T>
+TArray<T>& TArray<T>::AddElt(const TArray<T>& a, TArray<T>& res) const 
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::AddElt(...) - Not allocated source array ! ");
+  bool smoa;
+  if (!CompareSizes(a, smoa)) 
+    throw(SzMismatchError("TArray<T>::AddElt(...) SizeMismatch(this,a)")) ;
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else if ( a.IsTemp() ) res.Share(a);
+    else res.SetSize(*this, true, false);
+  }
+  bool smor;
+  if (!CompareSizes(res, smor)) 
+    throw(SzMismatchError("TArray<T>::AddElt(...) SizeMismatch(this,res) ")) ;
+
+  bool smora;
+  a.CompareSizes(res, smora);
+
+  bool smo = smoa && smor;  // The three arrays have same memory organisation
+
+  const T * pe;
+  const T * pea;
+  T * per;
+  sa_size_t j,k;
+  if (smo && IsPacked() && a.IsPacked() && res.IsPacked() )   {  // All packed arrays
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    pea = a.Data();
+    per = res.Data();
+    //    for(k=0; k<maxx;  k++, pe++, pea++, per++)  *per = *pe + *pea ;
+    for(k=0; k<maxx;  k++)  *per++ = *pe++ + *pea++ ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa,axr;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    sa_size_t stepr, stgpas;
+    if ( !smo && smora ) {   // same mem-org for a,res , different from this
+      a.GetOpeParams(*this, smo, axa, ax, stepa, step, gpas, naxa);
+      a.GetOpeParams(res, smo, axa, axr, stepa, stepr, gpas, naxa);
+      stgpas = stepa;
+    }
+    else { // same mem-org for all, or same (this,a) OR same(this,res)
+      GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+      GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+      stgpas = step;
+    }
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr) *per = *pe + *pea ; 
+    }
+  }
+  return(res);
+}
+
+//! Two TArrays element by element subtraction
+/*! 
+Perform element by element subtraction of the source array (this) and the \b a array 
+and the store result in \b res (res = *this-a or res=a-(*this)). 
+The source and argument arrays (this, a) should have the same sizes.
+
+If not initially allocated, and if none of the source arrays is flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and one of the source array is temporary,
+data is shared between \b res and the temporary source array.
+
+Returns a reference to the output array \b res. 
+
+\param a : Array to be added to the source array.
+\param res : Output array containing the result (res=*this+x). 
+\param fginv == true : Invert subtraction argument order (res = a-(*this))  
+*/
+
+template <class T>
+TArray<T>& TArray<T>::SubElt(const TArray<T>& a, TArray<T>& res, bool fginv) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SubElt(...) - Not allocated source array ! ");
+  bool smoa;
+  if (!CompareSizes(a, smoa)) 
+    throw(SzMismatchError("TArray<T>::SubElt(...) SizeMismatch(this,a)")) ;
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else if ( a.IsTemp() ) res.Share(a);
+    else res.SetSize(*this, true, false);
+  }
+  bool smor;
+  if (!CompareSizes(res, smor)) 
+    throw(SzMismatchError("TArray<T>::SubElt(...) SizeMismatch(this,res) ")) ;
+
+  bool smora;
+  a.CompareSizes(res, smora);
+
+  bool smo = smoa && smor;  // The three arrays have same memory organisation
+
+  const T * pe;
+  const T * pea;
+  T * per;
+  sa_size_t j,k;
+  if (smo && IsPacked() && a.IsPacked() && res.IsPacked() )   {  // All packed arrays
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    pea = a.Data();
+    per = res.Data();
+    if (!fginv) 
+      for(k=0; k<maxx;  k++)  *per++ = *pe++ - *pea++ ;
+    else 
+      for(k=0; k<maxx;  k++)  *per++ = *pea++ - *pe++ ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa,axr;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    sa_size_t stepr, stgpas;
+    if ( !smo && smora ) {   // same mem-org for a,res , different from this
+      a.GetOpeParams(*this, smo, axa, ax, stepa, step, gpas, naxa);
+      a.GetOpeParams(res, smo, axa, axr, stepa, stepr, gpas, naxa);
+      stgpas = stepa;
+    }
+    else { // same mem-org for all, or same (this,a) OR same(this,res)
+      GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+      GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+      stgpas = step;
+    }
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      if (!fginv) 
+        for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr) *per = *pe - *pea ; 
+      else 
+        for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr) *per = *pea - *pea ; 
+    }
+  }
+  return(res);
+}
+
+
+//! Two TArrays element by element multiplication
+/*! 
+Perform element by element multiplication of the source array (this) and the \b a array 
+and store the result in \b res (res = *this*a). The source and argument arrays (this, a)
+should have the same sizes.
+
+If not initially allocated, and if none of the source arrays is flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and one of the source array is temporary,
+data is shared between \b res and the temporary source array.
+
+Returns a reference to the output array \b res. 
+
+\param a : Array to be added to the source array.
+\param res : Output array containing the result (res=(*this)*a). 
+*/
+template <class T>
+TArray<T>& TArray<T>::MulElt(const TArray<T>& a, TArray<T>& res) const 
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::MulElt(...) - Not allocated source array ! ");
+  bool smoa;
+  if (!CompareSizes(a, smoa)) 
+    throw(SzMismatchError("TArray<T>::MulElt(...) SizeMismatch(this,a)")) ;
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else if ( a.IsTemp() ) res.Share(a);
+    else res.SetSize(*this, true, false);
+  }
+  bool smor;
+  if (!CompareSizes(res, smor)) 
+    throw(SzMismatchError("TArray<T>::MulElt(...) SizeMismatch(this,res) ")) ;
+
+  bool smora;
+  a.CompareSizes(res, smora);
+
+  bool smo = smoa && smor;  // The three arrays have same memory organisation
+
+  const T * pe;
+  const T * pea;
+  T * per;
+  sa_size_t j,k;
+  if (smo && IsPacked() && a.IsPacked() && res.IsPacked() )   {  // All packed arrays
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    pea = a.Data();
+    per = res.Data();
+    for(k=0; k<maxx;  k++)  *per++ = *pe++ * *pea++ ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa,axr;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    sa_size_t stepr, stgpas;
+    if ( !smo && smora ) {   // same mem-org for a,res , different from this
+      a.GetOpeParams(*this, smo, axa, ax, stepa, step, gpas, naxa);
+      a.GetOpeParams(res, smo, axa, axr, stepa, stepr, gpas, naxa);
+      stgpas = stepa;
+    }
+    else { // same mem-org for all, or same (this,a) OR same(this,res)
+      GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+      GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+      stgpas = step;
+    }
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr) *per = (*pe) * (*pea); 
+    }
+  }
+  return(res);
+}
+
+
+//! Two TArrays element by element division
+/*! 
+Perform element by element division of the source array (this) and the \b a array 
+and store the result in \b res (res = *this/a). The source and argument arrays (this, a)
+should have the same sizes.
+
+If not initially allocated, and if none of the source arrays is flagged as 
+temporary, the output array \b res is automatically 
+resized as a packed array with the same sizes as the source (this) array.
+If \b res is not allocated and one of the source array is temporary,
+data is shared between \b res and the temporary source array.
+
+Returns a reference to the output array \b res. 
+
+\param a : Array to be added to the source array.
+\param res : Output array containing the result (res=*this/a). 
+\param fginv == true : Inverts the division argument order (res = a/(*this)) 
+\param divzero == true : Result is set to zero (res(i)=0) if the operation's 
+second argument is equal to zero (a(i)/(*this)(i)==0) 
+*/
+template <class T>
+TArray<T>& TArray<T>::DivElt(const TArray<T>& a, TArray<T>& res, bool fginv, bool divzero) const 
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::DivElt(...) - Not allocated source array ! ");
+  bool smoa;
+  if (!CompareSizes(a, smoa)) 
+    throw(SzMismatchError("TArray<T>::DivElt(...) SizeMismatch(this,a)")) ;
+  if (res.NbDimensions() < 1)  {
+    if ( IsTemp() )  res.Share(*this);
+    else if ( a.IsTemp() ) res.Share(a);
+    else res.SetSize(*this, true, false);
+  }
+  bool smor;
+  if (!CompareSizes(res, smor)) 
+    throw(SzMismatchError("TArray<T>::DivElt(...) SizeMismatch(this,res) ")) ;
+
+  bool smora;
+  a.CompareSizes(res, smora);
+
+  bool smo = smoa && smor;  // The three arrays have same memory organisation
+
+  const T * pe;
+  const T * pea;
+  T * per;
+  sa_size_t j,k;
+  if (smo && IsPacked() && a.IsPacked() && res.IsPacked() )   {  // All packed arrays
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    pea = a.Data();
+    per = res.Data();
+    if(divzero) {
+      if (!fginv) 
+        for(k=0; k<maxx;  k++)  
+          if (*pea==(T)0) *per = (T)0;  else   *per++ = *pe++ / *pea++ ;
+      else 
+        for(k=0; k<maxx;  k++)  
+          if (*pe==(T)0)  *per = (T)0;  else   *per++ = *pea++ / *pe++ ;
+    }
+    else {
+      if (!fginv) 
+        for(k=0; k<maxx;  k++)  *per++ = *pe++ / *pea++ ;
+      else
+        for(k=0; k<maxx;  k++)  *per = *pea++ / *pe++ ;
+    }
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa,axr;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    sa_size_t stepr, stgpas;
+    if ( !smo && smora ) {   // same mem-org for a,res , different from this
+      a.GetOpeParams(*this, smo, axa, ax, stepa, step, gpas, naxa);
+      a.GetOpeParams(res, smo, axa, axr, stepa, stepr, gpas, naxa);
+      stgpas = stepa;
+      }
+    else { // same mem-org for all, or same (this,a) OR same(this,res)
+      GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+      GetOpeParams(res, smo, ax, axr, step, stepr, gpas, naxa);
+      stgpas = step;
+     }
+    // DBG cout << "DBG-A-DIVELT naxa=" << naxa << " gpas= " << gpas 
+    //	 << " step=" << step << " stepa=" << stepa << " stepr=" << stepr 
+    //	 << " ax= " << ax << " axa= " << axa << " axr= " << axr << endl;
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      per = res.DataBlock().Begin()+res.Offset(axr,j);
+      if(divzero) {
+        if (!fginv) 
+          for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr)  
+            if (*pea==(T)0) *per = (T)0;  else   *per = *pe / *pea ;
+	else
+          for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr)  
+            if (*pe==(T)0)  *per = (T)0;  else   *per = *pea / *pe ;
+      }
+      else {
+        if (!fginv) 
+	  for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr)  
+	    *per = *pe / *pea ;
+	else
+          for(k=0; k<gpas; k+=stgpas, pe+=step, pea+=stepa, per+=stepr)  
+	    *per = *pea / *pe ;
+      }
+    }
+  }
+  return(res);
+}
+
+
+//! 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;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) )   {  // regularly spaced elements
+    if (IsPacked() && a.IsPacked())  memcpy(Data(), a.Data(), totsize_*sizeof(T)); // Packed arrays
+    else {
+      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;  k<maxx;  k+=step, pe+=step, pea+=stepa )  *pe = *pea ;
+    }
+  }
+  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;  k<gpas;  k+=step, pe+=step, pea+=stepa)  *pe = *pea; 
+    }
+  }
+  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 
+*/
+    /*  ----- Janvier 2006 ------
+      Un bug important etait semble-t-il present depuis longtemps
+      On appelait a.ValueAtPosition(ip) qui renvoie l'element ip en tenant compte
+      de la structure du tableau , alors qu'on veut acceder l'element ip du datablock
+      Methode ValueAtPositionDB(ip) ajoute et utilisee a la place de  ValueAtPosition(ip)
+     */
+    for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa) 
+      a.ValueAtPositionDB(offa+ka).Convert(pe[k]); 
+      //REMPLACE Suite pb compil gcc4   pe[k] = a.ValueAtPosition(offa+ka).operator T(); 
+  }
+  return(*this);
+}
+
+//! Return the the scalar product of the two arrays (Sum_k[(*this)(k)*a(k)])
+template <class T>
+T TArray<T>::ScalarProduct(const TArray<T>& a)  const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::ScalarProduct(...)  - Not allocated source array ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::ScalarProduct(...) SizeMismatch(this,a) ")) ;
+
+  T res = (T)(0);
+  const T * pe;
+  const T * pea;
+  sa_size_t j,k;
+  if (smo && (IsPacked() > 0) && (a.IsPacked() > 0))   {  // regularly spaced elements
+    sa_size_t maxx = totsize_;
+    pe = Data();
+    pea = a.Data();
+    for(k=0; k<maxx; k++)  res += *pe++ * *pea++;
+  }
+  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;  k<gpas; k+=step, pe+=step, pea+=stepa)  res += (*pe)*(*pea);
+    }
+  }
+  return(res);
+}
+
+
+// Somme et produit des elements
+//! Returns the sum of all array 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;
+}
+
+//! Return the product of 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 array elements squared (Sum_k((*this)(k)*(*this)(k)).
+template <class T>
+T TArray<T>::SumSq() const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SumSq()  - 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;
+}
+
+/*!
+\brief Returns the array norm squared, defined as  Sum_k [ el(k)* el(k) ] 
+  For arrays with integer or real data, this method calls SumSq(), which computes
+  the sum of array elements squared. For complex arrays, it computes and returns 
+  the sum of array elements module squared (= Sum_k [el(k)*conj(el(k))]
+*/
+template <class T>
+T TArray<T>::Norm2() const
+{
+  return SumSq();
+}
+
+
+// Fonction auxiliaire pour specialisation de la methode Norm2() pour tableaux complexes
+template <class T> 
+complex<T>  _ComputeComplexNorm_Private_(TArray< complex<T> > const & ca) 
+{
+  if (ca.NbDimensions() < 1) 
+    throw RangeCheckError("TArray< complex<T> >::Norm2()  - Not Allocated Array ! ");
+  complex<T> ret= complex<T>(0., 0.);
+  const complex<T> * pe;
+  sa_size_t j,k;
+  if (ca.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = ca.AvgStep();
+    sa_size_t maxx = ca.Size()*step;
+    pe = ca.Data();
+    for(k=0; k<maxx; k+=step )  ret += pe[k]*conj(pe[k]);
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = ca.MaxSizeKA();
+    sa_size_t step = ca.Step(ka);
+    sa_size_t gpas = ca.Size(ka)*step;
+    sa_size_t naxa = ca.Size()/ca.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = ca.DataBlock().Begin()+ca.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  ret += pe[k]*conj(pe[k]) ;
+    }
+  }
+  return ret;
+
+}
+
+// --- Specialisation de la methode Norm2() pour tableaux complexes ---
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+complex<r_4> TArray< complex<r_4> >::Norm2() const
+{
+  return  _ComputeComplexNorm_Private_(*this);
+}
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+complex<r_8> TArray< complex<r_8> >::Norm2() const
+{
+  return  _ComputeComplexNorm_Private_(*this);
+}
+//-------------------
+
+//! 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;
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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");
+}
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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;
+  // keep stream's io flags 
+  // ios_base::fmtflags ioflg = os.flags(); compile pas sur OSF-cxx
+  // os << right ;   compile pas sur OSF-cxx
+  
+  Show(os, si);
+  if (ndim_ < 1) return;
+
+  // Calcul de la largeur d'impression pour chaque element
+  int fprtw = os.precision()+7;
+  int prtw = 5;
+
+  if ( (typeid(T) == typeid( int_4 )) || (typeid(T) == typeid( uint_4 )) ) prtw = 8;
+  else if ( (typeid(T) == typeid( int_8 )) || (typeid(T) == typeid( uint_8 )) ) prtw = 11;
+  else if ( typeid(T) == typeid( r_4 ) ) prtw = fprtw;
+  else if ( typeid(T) == typeid( r_8 ) ) prtw = fprtw;
+  else if ( typeid(T) == typeid(complex<r_4>) ) prtw = fprtw;
+  else if ( typeid(T) == typeid(complex<r_8>) ) prtw = fprtw;
+
+
+  sa_size_t k0,k1,k2,k3,k4;
+  for(k4=0; k4<size_[4]; k4++) {
+    if ((size_[4] > 1) && !ascd) 
+      os << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
+    for(k3=0; k3<size_[3]; k3++) {
+      if ((size_[3] > 1) && !ascd) 
+	os << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
+      for(k2=0; k2<size_[2]; k2++) {
+	if ((size_[2] > 1) && !ascd) 
+	  os << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
+	for(k1=0; k1<size_[1]; k1++) {
+	  if ( (size_[1] > 1) && (size_[0] > 10) && !ascd) 
+	    os << "----- Dimension 2 (Y) K1= " << k1 << endl;
+	  for(k0=0; k0<size_[0]; k0++) {
+            if(k0 > 0) os << " ";  
+            os << setw(prtw) << Elem(k0, k1, k2, k3, k4);     npr++;
+	    if (npr >= (sa_size_t) maxprt)  {
+	      if (npr < totsize_)  os << "\n     .... " << endl; return;
+	    }
+	  }
+          os << endl;
+	}
+      }
+    }
+  }
+  os <<  endl;
+  //compile pas sur OSF-cxx os.flags(ioflg);  // reset stream io flags
+}
+
+//! 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<uint_2>
+#pragma define_template TArray<uint_4>
+#pragma define_template TArray<uint_8>
+#pragma define_template TArray<int_2>
+#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<uint_2>;
+template class TArray<uint_4>;
+template class TArray<uint_8>;
+template class TArray<int_2>;  
+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
+
+} // FIN namespace SOPHYA 
Index: /tags/V_Nov2007/SophyaLib/TArray/tarray.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tarray.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tarray.h	(revision 3445)
@@ -0,0 +1,485 @@
+// 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>
+#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, bool fzero=true);
+  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, bool fzero=true);
+  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, bool fzero=true);
+  void ReSize(const BaseArray& a, bool pack=false, bool fzero=true);
+  //! a synonym (alias) for method ReSize(int_4, ...)
+  inline void SetSize(int_4 ndim, sa_size_t * siz, sa_size_t step=1, bool fzero=true)
+		{ ReSize(ndim, siz, step, fzero); }
+  //! a synonym (alias) for method ReSize(const BaseArray&)
+  inline void SetSize(const BaseArray& a, bool pack=false, bool fzero=true)
+		{ ReSize(a, pack, fzero); }
+  void Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step=1, bool force=false);
+
+  //! To clear the array sizes - corresponding to an unallocated array.
+  virtual TArray<T>& ZeroSize();
+
+  // 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, bool compact=true) const ;
+
+  //! Extract the first 3D subarray specified by rx, ry, rz. (see SubArray() )
+  inline TArray<T> operator () (Range rx, Range ry, Range rz) const
+                   { return  SubArray(rx, ry, rz, Range::first(), Range::first()); }
+  //! Extract the first 4D subarray specified by rx, ry, rz. (see SubArray() )
+  inline TArray<T> operator () (Range rx, Range ry, Range rz, Range rt) const
+                   { return  SubArray(rx, ry, rz, rt, Range::first()); }
+  //! Extract the subarray specified by rx, ry, rz. (see SubArray() )
+  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;
+  virtual MuTyV & ValueAtPositionDB(sa_size_t ip) const;
+
+  // Data Access: operator overloaded inline acces methods 
+  inline T const& operator()(sa_size_t ix, sa_size_t iy=0) const ;
+  inline T&       operator()(sa_size_t ix, sa_size_t iy=0);
+  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>&  SetCst(T x);
+  //! Fill an array with a constant value \b x ( alias for \b SetCst() method )
+  inline  TArray<T>&  SetT(T x) { return SetCst(x); }
+  //! Fill TArray with all elements equal to \b x
+  inline  TArray<T>&  operator = (T x)             { return SetT(x); }
+
+// addition et soustraction de constante 
+  virtual TArray<T>&  AddCst(T x, TArray<T>& res) const ;
+  virtual TArray<T>&  SubCst(T x, TArray<T>& res, bool fginv=false) const ;
+// Multiplication et division par une  constante 
+  virtual TArray<T>&  MulCst(T x, TArray<T>& res) const ;
+  virtual TArray<T>&  DivCst(T x, TArray<T>& res, bool fginv=false) const ;
+
+// A += -= *= /= x (ajoute, soustrait, ... x a tous les elements)
+  // Methodes Add/Sub/Mul/Div() sont la pour compatibilite avant V=2 (1.818)
+  // Faut-il les garder ? Reza, Juillet 2004
+  inline  TArray<T>&  Add(T x)                     { return AddCst(x, *this); }
+  inline  TArray<T>&  Sub(T x, bool fginv=false)   { return SubCst(x, *this, fginv); }
+  inline  TArray<T>&  Mul(T x)                     { return MulCst(x, *this); }
+  inline  TArray<T>&  Div(T x, bool fginv=false)   { return DivCst(x, *this, fginv); }
+
+  //! Add \b x to all elements
+  inline  TArray<T>&  operator += (T x)            { return AddCst(x, *this); }
+  //! Substract \b x to all elements
+  inline  TArray<T>&  operator -= (T x)            { return SubCst(x, *this); }
+  //! Multiply all elements by \b x
+  inline  TArray<T>&  operator *= (T x)            { return MulCst(x, *this); }
+  //! Divide all elements by \b x
+  inline  TArray<T>&  operator /= (T x)            { return DivCst(x, *this); }
+
+// applique le signe moins a tous les elements
+  virtual TArray<T>&  NegateElt(TArray<T>& res) const ;
+//! Replace array elements values by their opposite ( (*this)(i) -> -(*this)(i) )
+  inline  TArray<T>&  NegateElt()                  { return NegateElt(*this); }
+
+// A += -=  (ajoute, soustrait element par element les deux tableaux )
+  virtual TArray<T>&  AddElt(const TArray<T>& a, TArray<T>& res) const ;
+  virtual TArray<T>&  SubElt(const TArray<T>& a, TArray<T>& res, bool fginv=false) const ;
+// Multiplication, division element par element les deux tableaux 
+  virtual TArray<T>&  MulElt(const TArray<T>& a, TArray<T>& res) const ;
+  virtual TArray<T>&  DivElt(const TArray<T>& a, TArray<T>& res, bool fginv=false, bool divzero=false) const ;
+
+  //! Operator TArray += TArray (element by element addition in place)
+  inline  TArray<T>&  operator += (const TArray<T>& a)  { return AddElt(a, *this); }
+  //! Operator TArray -= TArray (element by element subtraction in place)
+  inline  TArray<T>&  operator -= (const TArray<T>& a)  { return SubElt(a, *this); }
+
+  // Doit-on definir les operateur *= /= TArray ?  Reza, Juillet 2004
+  //! Element by element multiplication in place TArray *= TArray (element by element)
+  inline  TArray<T>&  Mul(const TArray<T>& a)           { return MulElt(a, *this); }
+  //! Element by element division in place TArray *= TArray (element by element)
+  inline  TArray<T>&  Div(const TArray<T>& a, bool divzero=false)   
+                                                        { return DivElt(a, *this, false, divzero); }
+
+// 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);
+
+// Calcul du produit scalaire ( Somme_i (*this)(i)*a(i) )
+  virtual T ScalarProduct(const TArray<T>& a) const ;
+
+// Somme et produit des elements
+  virtual T Sum() const ;
+  virtual T Product() const ;
+// Somme du carre des elements
+  virtual T SumSq() const;
+//  Norme^2 , identique a SumSq pour tableaux reels/integer , sum[el * conj(el)] pour complexe
+  virtual T Norm2() const; 
+// Valeur min et max des elements (sauf tableaux complexes -> exception)
+  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;
+
+//! assign a new object Id (or DataRef Id) - useful for PPF write operations 
+  inline void RenewObjId() { mNDBlock.RenewObjId(); }
+//  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.SetTemp(true); 
+    a.AddCst(b, result); 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.SetTemp(true); 
+    a.AddCst(b, result); 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.SetTemp(true); 
+    a.SubCst(b,result); 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.SetTemp(true); 
+    a.SubCst(b,result,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.SetTemp(true); 
+    a.MulCst(b, result); 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.SetTemp(true); 
+    a.MulCst(b,result); 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.SetTemp(true); 
+    a.DivCst(b,result); 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.SetTemp(true); 
+    a.DivCst(b, result, 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.SetTemp(true); 
+    a.NegateElt(result); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (+,-,&&,/) B
+
+/*! \ingroup TArray \fn operator+(const TArray<T>&,const TArray<T>&)
+  \brief Operator TArray = TArray + TArray (element by element addition) */
+template <class T>
+inline TArray<T> operator + (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    a.AddElt(b, result);    return result; }
+
+/*! \ingroup TArray \fn operator-(const TArray<T>&,const TArray<T>&)
+  \brief Operator TArray = TArray - TArray (element by element subtraction) */
+template <class T>
+inline TArray<T> operator - (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    a.SubElt(b, result);    return result; }
+
+/*! \ingroup TArray \fn operator && (const TArray<T>&,const TArray<T>&)
+  \brief Element by element multiplication of two arrays TArray = TArray * TArray */
+
+template <class T>
+inline TArray<T> operator && (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    a.MulElt(b, result);    return result; }
+
+/*! \ingroup TArray \fn operator / (const TArray<T>&,const TArray<T>&)
+  \brief Element by element division of two arrays TArray = TArray / TArray */
+template <class T>
+inline TArray<T> operator / (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    a.DivElt(b, result, false, false);    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));
+}
+
+//=======>  a(ix,iy) OR a(ix) accees operators  
+//! Return the value of the element (ix,iy) 
+template <class T>
+inline T const& TArray<T>::operator()(sa_size_t ix, sa_size_t iy) const
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] ) );
+}
+
+//! Return a reference to the element (ix,iy) 
+template <class T>
+inline T & TArray<T>::operator()(sa_size_t ix, sa_size_t iy) 
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] ) );
+}
+
+//=======>  a(ix,iy,iz) accees operators  
+//! Return the value of the element (ix,iy,iz) 
+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 a reference to the element (ix,iy,iz) 
+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]) );
+}
+
+//=======>  a(ix,iy,iz,it,iu) or a(ix,iy,iz,it) accees operators  
+//! Return the value of the element  (ix,iy,iz,it,iu) 
+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]) );
+}
+
+//! Return a reference to the element  (ix,iy,iz,it,iu) 
+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_Nov2007/SophyaLib/TArray/tarrinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tarrinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tarrinit.cc	(revision 3445)
@@ -0,0 +1,99 @@
+// Classe d'initialisation du module TArray (template Arrays)
+#include "sopnamsp.h"
+#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;
+
+// Module version number - 2.0 , Jul 2006
+//   V= 2.04 , Jan/Fev 2007: Ajout TArray::ZeroSize() , RenewObjId() et methodes de cast (arrctcast.h)
+//   V= 2.1 , Avr/Jul 2007: Constr.copie/extrac sous-tableaux thread-safe
+#define MOD_VERS   2.1
+
+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>);
+  DObjRegister(FIO_TArray<int_2>, TMatrix<int_2>);
+  DObjRegister(FIO_TArray<int_2>, TVector<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>);
+  DObjRegister(FIO_TArray<uint_4>, TMatrix<uint_4>);
+  DObjRegister(FIO_TArray<uint_4>, TVector<uint_4>);
+
+  PPRegister(FIO_TArray<uint_8>);
+  DObjRegister(FIO_TArray<uint_8>, TArray<uint_8>);
+  DObjRegister(FIO_TArray<uint_8>, TMatrix<uint_8>);
+  DObjRegister(FIO_TArray<uint_8>, TVector<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> >);
+
+  SophyaInitiator::RegisterModule("TArray", MOD_VERS);  // Module name and version number registration
+}
+
+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_Nov2007/SophyaLib/TArray/tarrinit.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tarrinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tarrinit.h	(revision 3445)
@@ -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_Nov2007/SophyaLib/TArray/tmatrix.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tmatrix.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tmatrix.cc	(revision 3445)
@@ -0,0 +1,699 @@
+// $Id: tmatrix.cc,v 1.37 2006-11-02 14:57:20 ansari Exp $
+//                         C.Magneville          04/99
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#include <iomanip>
+#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.
+
+  Sub-matrices, in particular matrix rows and columns can easily and 
+  efficiently be extracted and manipulated.
+  It should be noted that a significant memory overhead is associated with
+  small matrices (typically less than 10x10=100 elements).However, 
+  higher dimension arrays (3D for examples) can be used to represent large 
+  number of small matrices or vectors.
+
+  \warning Matrix row, column indices (r,c) correspond to array indices
+  (r=jy, c=ix) for CMemoryMapping and to (r=ix, c=jy) for FortranMemoryMapping.
+
+  \b Matrix is a typedef for double precision floating point matrix ( TMatrix<r_8> ).
+
+  \sa SOPHYA::TArray  SOPHYA::TVector
+  \sa SOPHYA::Range   SOPHYA::Sequence
+  \sa SOPHYA::MathArray  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
+  \param fzero : if \b true , set matrix elements to zero 
+  \sa ReSize
+ */
+template <class T>
+TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c, short mm, bool fzero)
+// 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, fzero);
+}
+
+//! 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
+/*!
+  \param a : TArray to be copied or shared
+  \param share : if true, share data. If false copy data
+ */
+template <class T>
+TMatrix<T>::TMatrix(const TArray<T>& a, bool share)
+: 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, SameMemoryMapping);
+}
+
+//! 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)
+  \param fzero : if \b true , set matrix elements to zero 
+ */
+template <class T>
+void TMatrix<T>::ReSize(sa_size_t r, sa_size_t c, short mm, bool fzero)
+{
+  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, fzero);
+  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
+{
+  Range rx=Range::first();
+  Range ry=Range::first();
+  short mm = GetMemoryMapping();
+  if (mm == CMemoryMapping)  { rx = rcol;  ry = rline; }
+  else { ry = rcol;  rx = rline; }
+  TMatrix sm(SubArray(rx, ry, Range::first(), Range::first(), Range::first(), false), true);
+  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() const
+{
+  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) const
+{
+  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) const 
+{
+  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;
+
+  // keep stream's io flags 
+  // ios_base::fmtflags ioflg = os.flags(); compil pas sur OSF-cxx
+  // os << right ;   compile pas sur OSF-cxx
+
+  Show(os, si);
+  if (ndim_ < 1)  return;
+  // Calcul de la largeur d'impression pour chaque element
+  int fprtw = os.precision()+7;
+  int prtw = 5;
+
+  if ( (typeid(T) == typeid( int_4 )) || (typeid(T) == typeid( uint_4 )) ) prtw = 8;
+  else if ( (typeid(T) == typeid( int_8 )) || (typeid(T) == typeid( uint_8 )) ) prtw = 11;
+  else if ( typeid(T) == typeid( r_4 ) ) prtw = fprtw;
+  else if ( typeid(T) == typeid( r_8 ) ) prtw = fprtw;
+  else if ( typeid(T) == typeid(complex<r_4>) ) prtw = fprtw;
+  else if ( typeid(T) == typeid(complex<r_8>) ) prtw = fprtw;
+
+  sa_size_t kc,kr;  
+  for(kr=0; kr<size_[marowi_]; kr++) {
+    if ( (size_[marowi_] > 1) && (size_[macoli_] > 10) && !ascd) 
+      os << "----- Line= " << kr << endl;
+    for(kc=0; kc<size_[macoli_]; kc++) {
+      if(kc > 0) os << " ";  
+      os << setw(prtw) << (*this)(kr, kc);   npr++; 
+      if (npr >= (sa_size_t) maxprt) {
+	if (npr < totsize_)  os << "\n     .... " << endl; return;
+      }
+    }
+    os << endl;
+  }
+  os << endl;
+  //compile pas sur OSF-cxx os.flags(ioflg);  // reset stream io flags
+}
+
+//////////////////////////////////////////////////////////
+/////////////// Multiplication matricielle ///////////////
+//////////////////////////////////////////////////////////
+
+//! Return the matrix product C = (*this)*B
+/*!
+  \param mm : define the memory mapping type for the return matrix
+ */
+////////////// Routine de base sans optimisation //////////////
+/*
+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;
+}
+*/
+
+////////////// Routine optimisee //////////////
+template <class T>
+TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
+// Calcul de C= rm = A*B   (A=*this)
+// Remember: C-like      matrices are column packed
+//           Fortan-like matrices are line   packed
+{
+  if (NCols() != b.NRows()) 
+    throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
+
+  // Commentaire: pas de difference de vitesse notable selon le mapping de la matrice produit "rm"
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();
+  TMatrix<T> rm(NRows(), b.NCols(), mm);
+
+  // Les "steps" pour l'adressage des colonnes de A et des lignes de B
+  sa_size_t stepa = Step(ColsKA());
+  sa_size_t stepb = b.Step(b.RowsKA());
+
+  // Taille totale des matrices A et B
+  size_t totsiza = this->DataBlock().Size();
+  size_t totsizb = b.DataBlock().Size();
+
+
+  ///////////////////////////////////////////////////////////////////
+  // On decide si on optimise ou non selon les dimensions de A et B //
+  // (il semble que optimiser ou non ne degrade pas                 //
+  //  beaucoup la vitesse pour les petites matrices)                //
+  ////////////////////////////////////////////////////////////////////
+
+  uint_2 popt = GetMatProdOpt();
+  bool no_optim = false; // optimization demandee par default
+  if( (popt&(uint_2)1) == 0 ) { // pas d'optimization explicitement demande
+    no_optim = true;
+  } else if( (popt&(uint_2)2) == 0 ) { // pas d'optimization forcee, la methode decide
+    // On part sur une disponibilite dans le cache processeur de 100 ko
+    // (A et B peuvent etre stoquees dans le cache)
+    if((totsiza+totsizb)*sizeof(T)<100000) no_optim = true;
+  }
+
+  sa_size_t r,c,k;
+  T sum;
+  const T * pe;
+
+
+  /////////////////////////////////
+  // Pas d'optimisation demandee //
+  /////////////////////////////////
+
+  if( no_optim ) {
+    //cout<<"no_optim("<<no_optim<<") "<<stepa<<" "<<stepb<<endl;
+    const T * pea;
+    const T * peb;
+    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));
+        peb = &(b(0,c));
+	// On gagne un peu en remplacant "pea[k*stepa]" par "pea+=stepa" pour les grosses matrices
+        //for(k=0; k<NCols(); k++)  sum += pea[k*stepa]*peb[k*stepb];
+        for(k=0; k<NCols(); k++) {sum += (*pea)*(*peb); pea+=stepa; peb+=stepb;}
+        rm(r,c) = sum;
+      }
+    }
+    return rm;
+  }
+
+
+  //////////////////////////////////////////////////////////////////////////////////
+  // A.col est packed  et  B.row est packed (on a interet a optimiser quand meme) //
+  //////////////////////////////////////////////////////////////////////////////////
+
+  if(stepa==1 && stepb==1) {
+    //cout<<"A.col packed && B.row packed "<<stepa<<" "<<stepb<<endl;
+     T * pea = new T[NCols()];
+    const T * peb;
+    for(r=0; r<rm.NRows(); r++) {     // Boucle sur les lignes de A
+      pe = &((*this)(r,0));
+      for(k=0; k<NCols(); k++) {pea[k] = *(pe++);}
+      for(c=0; c<rm.NCols(); c++) {   // Boucle sur les colonnes de B
+        sum = 0;
+        peb = &(b(0,c));
+        for(k=0; k<NCols(); k++) sum += *(peb++)*pea[k];
+        rm(r,c) = sum;
+      }
+    }
+    delete [] pea;
+    return rm;
+  }
+
+
+  //////////////////////////////////////////////////
+  // A.col est packed  et  B.row n'est pas packed //
+  //////////////////////////////////////////////////
+
+  if(stepa==1 && stepb!=1) {
+    //cout<<"A.col packed && B.row not packed "<<stepa<<" "<<stepb<<endl;
+    const T * pea;
+    T * peb = new T[NCols()];
+    for(c=0; c<rm.NCols(); c++) {     // Boucle sur les colonnes de B
+      pe = &(b(0,c));
+      for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;}
+      for(r=0; r<rm.NRows(); r++) {   // Boucle sur les lignes de A
+        sum = 0;
+        pea = &((*this)(r,0));
+        for(k=0; k<NCols(); k++) sum += pea[k]*peb[k];
+        rm(r,c) = sum;
+      }
+    }
+    delete [] peb;
+    return rm;
+  }
+
+
+  //////////////////////////////////////////////////
+  // A.col n'est pas packed  et  B.row est packed //
+  //////////////////////////////////////////////////
+
+  if(stepa!=1 && stepb==1) {
+    //cout<<"A.col not packed && B.row packed "<<stepa<<" "<<stepb<<endl;
+    T * pea = new T[NCols()];
+    const T * peb;
+    for(r=0; r<rm.NRows(); r++) {     // Boucle sur les lignes de A
+      pe = &((*this)(r,0));
+      for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;}
+      for(c=0; c<rm.NCols(); c++) {   // Boucle sur les colonnes de B
+        sum = 0;
+        peb = &(b(0,c));
+        for(k=0; k<NCols(); k++) sum += pea[k]*peb[k];
+        rm(r,c) = sum;
+      }
+    }
+    delete [] pea;
+    return rm;
+  }
+
+
+  ////////////////////////////////////////////////////////
+  // A.col n'est pas packed  et  B.row n'est pas packed //
+  ////////////////////////////////////////////////////////
+
+  //---- On demande l'optimization par copie d'une des matrices
+
+  if( (popt&(uint_2)4) ) {
+    // On copie la plus petite
+    if(totsiza<totsizb) {   // on copie A
+      //cout<<"A.col not packed && B.row not packed ==> copy A to optimize "<<stepa<<" "<<stepb<<endl;
+      // Acopy doit etre C-like pour etre column-packed
+      TMatrix<T> acopy(NRows(),NCols(),BaseArray::CMemoryMapping);
+      acopy = *this;
+      rm = acopy.Multiply(b,mm);
+    } else {               // on copie B
+      //cout<<"A.col not packed && B.row not packed ==> copy B to optimize "<<stepa<<" "<<stepb<<endl;
+      // Bcopy doit etre Fortran-like pour etre column-packed
+      TMatrix<T> bcopy(b.NRows(),b.NCols(),BaseArray::FortranMemoryMapping);
+      bcopy = b;
+      rm = Multiply(bcopy,mm);
+    }
+    return rm;
+  }
+ 
+  //---- stepb>stepa
+
+  if(stepa!=1 && stepb!=1 && stepb>stepa) {
+    //cout<<"A.col not packed && B.row not packed ==> optimize on B "<<stepa<<" "<<stepb<<endl;
+    const T * pea;
+    T * peb = new T[NCols()];
+    for(c=0; c<rm.NCols(); c++) {     // Boucle sur les colonnes de B
+      pe = &(b(0,c));
+      for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;}
+      for(r=0; r<rm.NRows(); r++) {     // Boucle sur les lignes de A
+        sum = 0;
+        pea = &((*this)(r,0));
+        for(k=0; k<NCols(); k++) {sum += (*pea)*peb[k]; pea+=stepa;}
+        rm(r,c) = sum;
+      }
+    }
+    delete [] peb;
+    return rm;
+  }
+
+  //---- stepa>=stepb
+
+  if(stepa!=1 && stepb!=1) {
+    //cout<<"A.col not packed && B.row not packed ==> optimize on A "<<stepa<<" "<<stepb<<endl;
+    T * pea = new T[NCols()];
+    const T * peb;
+    for(r=0; r<rm.NRows(); r++) {     // Boucle sur les lignes de A
+      pe = &((*this)(r,0));
+      for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;}
+      for(c=0; c<rm.NCols(); c++) {     // Boucle sur les colonnes de B
+        sum = 0;
+        peb = &(b(0,c));
+        for(k=0; k<NCols(); k++) {sum += pea[k]*(*peb); peb+=stepb;}
+        rm(r,c) = sum;
+      }
+    }
+    delete [] pea;
+    return rm;
+  }
+
+
+  //////////////////////////////////////////////////
+  // Cas non prevu, on ne doit JAMAIS arriver ici //
+  //////////////////////////////////////////////////
+  cout<<"TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! "<<endl;
+  throw(SzMismatchError("TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! ") );
+  return rm;
+
+}
+
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template TMatrix<uint_2>
+#pragma define_template TMatrix<uint_4>
+#pragma define_template TMatrix<uint_8>
+#pragma define_template TMatrix<int_2>
+#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)
+namespace SOPHYA {
+template class TMatrix<uint_2>;
+template class TMatrix<uint_4>;
+template class TMatrix<uint_8>;
+template class TMatrix<int_2>;
+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_Nov2007/SophyaLib/TArray/tmatrix.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tmatrix.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tmatrix.h	(revision 3445)
@@ -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:
+
+#include "tmatrix_tsnl.h"  /* For two level name look-up gcc >= 3.4 */
+
+  // Creation / destruction 
+  TMatrix();
+  TMatrix(sa_size_t r,sa_size_t c, short mm=BaseArray::AutoMemoryMapping, bool fzero=true);
+  TMatrix(const TMatrix<T>& a);
+  TMatrix(const TMatrix<T>& a, bool share);
+  TMatrix(const TArray<T>& a,  bool share=true);
+  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, bool fzero=true);
+  //! 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, bool fzero=true)
+                 { ReSize(r, c, mm, fzero); }
+  // 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() const;
+  //mm = SameMemoryMapping or CMemoryMapping or FortranMemoryMapping 
+  TMatrix<T>  Transpose(short mm) const ; 
+  // Rearranging Matrix Elements
+  TMatrix<T>  Rearrange(short mm) const;
+
+  // 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)            { AddCst(x,*this); return(*this); }
+  //! -= : substract constant value \b x to matrix
+  inline  TMatrix<T>&  operator -= (T x)            { SubCst(x,*this); return(*this); }
+  //! *= : multiply matrix by constant value \b x
+  inline  TMatrix<T>&  operator *= (T x)            { MulCst(x,*this); return(*this); }
+  //! /= : divide matrix by constant value \b x
+  inline  TMatrix<T>&  operator /= (T x)            { DivCst(x,*this); return(*this); }
+
+  //  operations avec matrices 
+  //! += : add a matrix
+  inline  TMatrix<T>&  operator += (const TMatrix<T>& a)  { AddElt(a,*this); return(*this); }
+  //! -= : substract a matrix
+  inline  TMatrix<T>&  operator -= (const TMatrix<T>& a)  { SubElt(a,*this); return(*this); }
+
+  TMatrix<T>  Multiply(const TMatrix<T>& b, short mm=BaseArray::SameMemoryMapping) const;
+  //A supprimer ? Reza Juillet 2004 ! *= : 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.SetTemp(true); 
+    a.AddCst(b,result); 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.SetTemp(true); 
+    a.AddCst(b,result); 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.SetTemp(true); 
+    a.SubCst(b,result); 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.SetTemp(true); 
+    a.SubCst(b,result,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.SetTemp(true); 
+    a.MulCst(b,result); 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.SetTemp(true); 
+    a.MulCst(b,result); 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.SetTemp(true); 
+    a.DivCst(b,result); 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.SetTemp(true); 
+    a.Div(b,result,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.SetTemp(true); 
+    a.NegateElt(result); 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); 
+    a.AddElt(b, result);     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); 
+    a.SubElt(b, result);     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_Nov2007/SophyaLib/TArray/tmatrix_tsnl.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tmatrix_tsnl.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tmatrix_tsnl.h	(revision 3445)
@@ -0,0 +1,55 @@
+#ifdef TSNMLUPG4
+/* This is a specific declaration file to cope with two level 
+   name look-up scheme , introduced by gcc >= 3.4 
+   THIS FILE SHOULD NOT NORMALLY BE INCLUDED IN USER PROGRAMS 
+   R. Ansari -  Jan 2006 
+*/
+using SOPHYA::TArray<T>::MemoryMapping  ;
+using SOPHYA::TArray<T>::AutoMemoryMapping  ;
+using SOPHYA::TArray<T>::SameMemoryMapping  ;
+using SOPHYA::TArray<T>::CMemoryMapping  ;
+using SOPHYA::TArray<T>::FortranMemoryMapping  ;
+
+using SOPHYA::TArray<T>::VectorType  ;
+using SOPHYA::TArray<T>::AutoVectorType  ;
+using SOPHYA::TArray<T>::SameVectorType  ;
+using SOPHYA::TArray<T>::ColumnVector  ;
+using SOPHYA::TArray<T>::RowVector  ;
+
+using SOPHYA::TArray<T>::NbDimensions  ;
+using SOPHYA::TArray<T>::RowsKA  ;
+using SOPHYA::TArray<T>::ColsKA  ;
+using SOPHYA::TArray<T>::VectKA  ;
+using SOPHYA::TArray<T>::Size  ;
+
+using SOPHYA::TArray<T>::GetMatProdOpt  ;
+using SOPHYA::TArray<T>::SetMemoryMapping  ;
+using SOPHYA::TArray<T>::GetMemoryMapping ;
+using SOPHYA::TArray<T>::GetDefaultMemoryMapping ;
+using SOPHYA::TArray<T>::UpdateMemoryMapping  ;
+
+using SOPHYA::TArray<T>::SubArray  ;
+
+// using SOPHYA::TArray<T>::  ;
+
+using SOPHYA::TArray<T>::max_nprt_ ;
+using SOPHYA::TArray<T>::ndim_ ;
+using SOPHYA::TArray<T>::size_ ;
+using SOPHYA::TArray<T>::totsize_ ;
+using SOPHYA::TArray<T>::offset_ ;
+using SOPHYA::TArray<T>::step_ ;
+using SOPHYA::TArray<T>::minstep_ ;
+using SOPHYA::TArray<T>::moystep_ ;
+
+using SOPHYA::TArray<T>::marowi_  ;
+using SOPHYA::TArray<T>::macoli_ ;
+using SOPHYA::TArray<T>::veceli_  ;
+using SOPHYA::TArray<T>::arrtype_  ;
+
+using SOPHYA::TArray<T>::mNDBlock ;
+
+using SOPHYA::TArray<T>::SetSeq ;
+using SOPHYA::TArray<T>::SetBA ;
+using SOPHYA::TArray<T>::Show ;
+
+#endif  /* TSNMLUPG4 */
Index: /tags/V_Nov2007/SophyaLib/TArray/triangmtx.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/triangmtx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/triangmtx.h	(revision 3445)
@@ -0,0 +1,192 @@
+// 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
+  \brief Class for inferior triangular matrix (base class for the class Alm)
+  The inferior triangular matrix is represented in memory as column packed,
+  as illustrated below for a 5x5 triangular matrix.
+  \verbatim
+  5x5 Inf.Triang.Matrix, Size= 15 elements (0 ... 14) 
+  | 0                  |
+  | 1   5              |
+  | 2   6   9          |
+  | 3   7   10  12     |
+  | 4   8   11  13  14 |
+  \endverbatim 
+*/
+
+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(sa_size_t rowSize)  : long_diag_(rowSize) 
+  {
+    elem_.ReSize((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(sa_size_t 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()(sa_size_t l, sa_size_t m) 
+  {
+      return  elem_(indexOfElement(l,m));
+  }
+
+inline T& operator()(sa_size_t index) 
+  {
+      return  elem_(index);
+  }
+
+
+//! () operator : access to elements row \b l and column \b m
+inline T const& operator()(sa_size_t l, sa_size_t m) const 
+  {
+      return *(elem_.Begin()+ indexOfElement(l,m));
+  }
+
+inline T const& operator()(sa_size_t 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_;
+    sa_size_t 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  sa_size_t rowNumber() const {return (int_4)long_diag_;}
+
+//! Return size of the total array
+  inline sa_size_t Size() const {return elem_.Size();}
+
+  inline bool CheckRelativeIndices(sa_size_t l, sa_size_t m) const 
+   {
+     if ( l < m ) 
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckRelativeIndices: indices out of range " );
+       }
+     return true;
+   }
+  inline bool CheckAbsoluteIndice(sa_size_t l, sa_size_t m) const 
+   {
+     if ( indexOfElement(l,m) >= elem_.Size() )
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
+       }
+   }
+  inline bool CheckAbsoluteIndice(sa_size_t ind) const 
+   {
+     if ( ind >= elem_.Size() )
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
+       }
+   }
+
+  //! ASCII dump of the matrix (set nbLignes=-1) for dumping the complete matrix
+void Print(ostream& os, sa_size_t nbLignes=0) const
+  {
+    os << "TriangularMatrix< " << typeid(T).name() 
+       << " > NRow=" << long_diag_ << " NbElem<>0 : " << Size() << endl;
+    if (nbLignes == 0) return;
+    if (nbLignes < 0 ) nbLignes = long_diag_;
+    if (nbLignes > long_diag_ ) nbLignes = long_diag_;
+    for (sa_size_t k=0; k < nbLignes; k++)  {
+      os << "L[" << k << "]: " ;
+      for (sa_size_t kc = 0; kc <= k ; kc++) 
+	os << " " << elem_(indexOfElement(k,kc));
+      os << endl;
+    }
+    if (nbLignes < long_diag_)  os << " ... ... ... " << endl;
+    return;
+  }
+
+inline void Print(sa_size_t nbLignes=0) const  { Print(cout, nbLignes); }
+
+
+//! Return the pointer to the first non zero element in column \b j = &(tmmtx(j,j)) 
+inline const T* columnData(sa_size_t j)  const {return elem_.Begin()+(long_diag_*j-j*(j-1)/2) ;}
+
+//! Return the pointer to the first non zero element in column \b j = &(tmmtx(j,j)) 
+inline T* columnData(sa_size_t j) {return elem_.Begin()+(long_diag_*j-j*(j-1)/2) ;}
+
+//! compute the address of an element in the single array representing the matrix
+inline sa_size_t indexOfElement(sa_size_t i,sa_size_t 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: 
+
+sa_size_t long_diag_;    //!< size of the square matrix
+NDataBlock<T> elem_;  //!< Data block
+
+  };
+
+template <class T>
+inline ostream& operator << (ostream& os, const TriangularMatrix<T>& a)
+                            { a.Print(os, 0);    return(os);    }
+  
+}   // namespace SOPHYA
+
+#endif
Index: /tags/V_Nov2007/SophyaLib/TArray/tvector.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tvector.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tvector.cc	(revision 3445)
@@ -0,0 +1,273 @@
+// $Id: tvector.cc,v 1.22 2006-04-03 08:55:26 ansari Exp $
+//                         C.Magneville          04/99
+#include "sopnamsp.h"
+#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
+  \param fzero : if \b true , set vector elements to zero 
+  \sa SelectVectorType
+ */
+template <class T>
+TVector<T>::TVector(sa_size_t n, short lcv, short mm, bool fzero)
+// Constructeur 
+  : TMatrix<T>(1,1,mm,false)
+{
+  arrtype_ = 2;   // Type = Vector
+  lcv = SelectVectorType(lcv);
+  ReSize(n,lcv,fzero);
+}
+
+//! 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 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 lcv : line or column vector ?
+  \sa SelectVectorType
+ */
+template <class T>
+TVector<T>::TVector(const TArray<T>& a, bool share, short lcv)
+: TMatrix<T>(a, share)
+{
+  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
+}
+
+//! Constructor from a STL vector
+template <class T>
+TVector<T>::TVector(const vector<T>& v, short lcv)
+{
+ sa_size_t n = v.size();
+ if(n==0)
+    throw SzMismatchError("TVector<T>::TVector(const vector<T>& v) size()==0 ");
+ arrtype_ = 2;   // Type = Vector
+ ReSize(n,lcv,false);
+ for(sa_size_t i=0;i<n;i++) (*this)(i) = v[i];
+}
+
+//! 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, bool fzero)
+{
+  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,BaseArray::SameMemoryMapping,fzero);
+  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=Range::first();
+  Range cr=Range::first();
+  if (GetVectorType() == ColumnVector )  rr = relt; 
+  else cr = relt;
+  TMatrix<T> const & mtx = (*this);
+  TVector sv( mtx(rr, cr) , true, GetVectorType() );
+  return(sv);  
+}
+
+//! 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);  
+
+}
+
+//! Fill from a STL vector
+/*!
+  \param v : STL vector to copy
+  \param noresize : "true" means TVector keeps its size
+  \warning Filling is always done starting at TVector(0)
+ */
+template <class T>
+sa_size_t TVector<T>::FillFr(const vector<T>& v,bool noresize)
+{
+ sa_size_t n = v.size();
+ if(n==0) return 0; //STL vector de taille nulle!
+ if(!noresize) ReSize(n,SameVectorType,false);
+ if(Size()<n) n = Size();
+ if(n==0) return 0; //TVector de taille nulle sans resize!
+ for(sa_size_t i=0;i<n;i++) (*this)(i) = v[i];
+ return n;
+}
+
+//! Fill a STL vector
+/*!
+  \param v : STL vector to fill
+  \param addtoend : "true" means TVector will be added at the end of "v"
+ */
+template <class T>
+sa_size_t TVector<T>::FillTo(vector<T>& v,bool addtoend)
+{
+ sa_size_t n = Size();
+ if(n==0) return 0; //TVector de taille nulle!
+ if(!addtoend) v.resize(0);
+ for(sa_size_t i=0;i<n;i++) v.push_back((*this)(i));
+ return n;
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template TVector<uint_2>
+#pragma define_template TVector<uint_4>
+#pragma define_template TVector<uint_8>
+#pragma define_template TVector<int_2>
+#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)
+namespace SOPHYA {
+template class TVector<uint_2>;
+template class TVector<uint_4>;
+template class TVector<uint_8>;
+template class TVector<int_2>;
+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_Nov2007/SophyaLib/TArray/tvector.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tvector.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tvector.h	(revision 3445)
@@ -0,0 +1,127 @@
+// 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:
+
+#include "tvector_tsnl.h"  /* For two level name look-up gcc >= 3.4 */
+
+  // Creation / destruction 
+  TVector();
+  TVector(sa_size_t n, short lcv=BaseArray::AutoVectorType, short mm=BaseArray::AutoMemoryMapping, bool fzero=true);
+  TVector(const TVector<T>& v);
+  TVector(const TVector<T>& v, bool share);
+  TVector(const TArray<T>& a,  bool share=true, short lcv=BaseArray::AutoVectorType);
+  TVector(const BaseArray& a);
+  TVector(const vector<T>& v, short lcv=BaseArray::AutoVectorType);
+
+  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=BaseArray::SameVectorType, bool fzero=true); 
+  //! a synonym (alias) for method ReSize(sa_size_t, short)
+  inline void SetSize(sa_size_t n, short lcv=BaseArray::SameVectorType, bool fzero=true)
+              { ReSize(n, lcv, fzero); }
+  void Realloc(sa_size_t n, short lcv=BaseArray::SameVectorType, bool force=false);
+    
+  // Remplissage from/to a STL vector
+  sa_size_t FillFr(const vector<T>& v,bool noresize=false);
+  sa_size_t FillTo(vector<T>& v,bool addtoend=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)            { AddCst(x,*this); return(*this); }
+  //! Substract constant value \b x to vector elements
+  inline  TVector<T>&  operator -= (T x)            { SubCst(x,*this); return(*this); }
+  //! Multiply vector elements by constant value \b x
+  inline  TVector<T>&  operator *= (T x)            { MulCst(x,*this); return(*this); }
+  //! Divide vector elements by constant value \b x
+  inline  TVector<T>&  operator /= (T x)            { DivCst(x,*this); return(*this); }
+
+  //  operations avec matrices 
+  //! += : add a vector in place
+  inline  TVector<T>&  operator += (const TVector<T>& a)  { AddElt(a,*this); return(*this); }
+  //! += : substract a vector in place
+  inline  TVector<T>&  operator -= (const TVector<T>& a)  { SubElt(a,*this); return(*this); }
+
+  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_Nov2007/SophyaLib/TArray/tvector_tsnl.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/tvector_tsnl.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/tvector_tsnl.h	(revision 3445)
@@ -0,0 +1,65 @@
+#ifdef TSNMLUPG4
+/* This is a specific declaration file to cope with two level
+   name look-up scheme , introduced by gcc >= 3.4
+   THIS FILE SHOULD NOT NORMALLY BE INCLUDED IN USER PROGRAMS
+   R. Ansari -  Jan 2006
+*/
+
+using SOPHYA::TMatrix<T>::MemoryMapping  ;
+using SOPHYA::TMatrix<T>::AutoMemoryMapping  ;
+using SOPHYA::TMatrix<T>::SameMemoryMapping  ;
+using SOPHYA::TMatrix<T>::CMemoryMapping  ;
+using SOPHYA::TMatrix<T>::FortranMemoryMapping  ;
+
+using SOPHYA::TMatrix<T>::VectorType  ;
+using SOPHYA::TMatrix<T>::AutoVectorType  ;
+using SOPHYA::TMatrix<T>::SameVectorType  ;
+using SOPHYA::TMatrix<T>::ColumnVector  ;
+using SOPHYA::TMatrix<T>::RowVector  ;
+
+using SOPHYA::TMatrix<T>::SelectVectorType  ;
+using SOPHYA::TMatrix<T>::GetDefaultVectorType  ;
+using SOPHYA::TMatrix<T>::GetVectorType  ;
+
+
+using SOPHYA::TMatrix<T>::NbDimensions  ;
+using SOPHYA::TMatrix<T>::RowsKA  ;
+using SOPHYA::TMatrix<T>::ColsKA  ;
+using SOPHYA::TMatrix<T>::VectKA  ;
+using SOPHYA::TMatrix<T>::Size  ;
+
+using SOPHYA::TMatrix<T>::GetMatProdOpt  ;
+using SOPHYA::TMatrix<T>::SetMemoryMapping  ;
+using SOPHYA::TMatrix<T>::GetMemoryMapping ;
+using SOPHYA::TMatrix<T>::GetDefaultMemoryMapping ;
+using SOPHYA::TMatrix<T>::UpdateMemoryMapping  ;
+
+using SOPHYA::TMatrix<T>::SubArray  ;
+
+using SOPHYA::TMatrix<T>::NRows  ;
+using SOPHYA::TMatrix<T>::NCols  ;
+
+// using SOPHYA::TMatrix<T>::  ;
+
+using SOPHYA::TMatrix<T>::max_nprt_ ;
+using SOPHYA::TMatrix<T>::ndim_ ;
+using SOPHYA::TMatrix<T>::size_ ;
+using SOPHYA::TMatrix<T>::totsize_ ;
+using SOPHYA::TMatrix<T>::offset_ ;
+using SOPHYA::TMatrix<T>::step_ ;
+using SOPHYA::TMatrix<T>::minstep_ ;
+using SOPHYA::TMatrix<T>::moystep_ ;
+
+using SOPHYA::TMatrix<T>::marowi_  ;
+using SOPHYA::TMatrix<T>::macoli_ ;
+using SOPHYA::TMatrix<T>::veceli_  ;
+using SOPHYA::TMatrix<T>::arrtype_  ;
+
+using SOPHYA::TMatrix<T>::mNDBlock ;
+
+using SOPHYA::TMatrix<T>::SetSeq ;
+using SOPHYA::TMatrix<T>::SetBA ;
+using SOPHYA::TMatrix<T>::Show ;
+
+#endif  /* TSNMLUPG4 */
+
Index: /tags/V_Nov2007/SophyaLib/TArray/utilarr.cc
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/utilarr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/utilarr.cc	(revision 3445)
@@ -0,0 +1,460 @@
+//     Utility classes for template numerical arrays
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "utilarr.h"
+#include "stsrand.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)
+ */
+static RandomGenerator* uarg_ = NULL;
+RandomSequence::RandomSequence(int typ, double m, double s)
+{
+  typ_ = (typ == Flat) ? Flat : Gaussian;
+  mean_ = m;
+  sig_ = s;
+  if (uarg_ == NULL) uarg_ = new RandomGenerator(1024, true);
+}
+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(uarg_->Flatpm1()*sig_ + mean_);
+  else return(uarg_->Gaussian(sig_, mean_));
+}
+
+MuTyV & RandomSequence::Value(sa_size_t k) const 
+{
+  if (typ_ == Flat) retv_ = uarg_->Flatpm1()*sig_ + mean_;
+  else retv_ = uarg_->Gaussian(sig_, mean_);
+  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()) {
+  /* Reza, Juin 2005 : Remplace par getline(istream, string) - plus sur
+     is.clear(); 
+     is.getline(buff, 256);    line += buff;  nel = 0; */
+    line = "";
+    getline(is, line);
+    if (is.good() || is.eof()) {
+      if ((line.length() > 0) && (line[0]!=clm)) {
+	nel = Append(line, nbad, sep);
+	if (nel > 0)  { 
+	  nr++;  n += nel;
+	}
+	nbadtot += nbad;
+      }
+    }
+  }
+/* Reza, Juin 2005 : plus necessaire
+  if ((line.length() > 0) && (line[0]!=clm)) {
+    nel = Append(line, nbad, sep);
+    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
+  This class can be used to define a range of indices. Range objects are used to extract 
+  sub-arrays and slices, from arrays and matrices. 
+  \sa SOPHYA::TArray SOPHYA::TMatrix
+*/
+
+/*!
+  Constructor defining a range corresponding to the single index \b start
+  \param start : start=end index 
+*/
+Range::Range(sa_size_t start)
+{
+  start_ = start;
+  end_ = start;
+  size_ = 1;
+  step_ = 1;
+}
+
+/*!
+  Constructor defining defining the range of indices, from \b start to \b end
+  \param start : start index (inclusive)
+  \param end : end index (inclusive)
+*/
+Range::Range(sa_size_t start, sa_size_t end)
+{
+  start_ = start;
+  end_ = end;
+  if (end >= start)   size_ = end-start+1;
+  else size_ = 0;
+  step_ = 1;
+}
+
+/*!
+  Constructor defining defining the range of indices, from \b start to \b end
+  \param start : start index (inclusive)
+  \param end : end index (inclusive)
+  \param step : step (or stride) = index increment
+*/
+Range::Range(sa_size_t start, sa_size_t end, sa_size_t step)
+{
+  start_ = start;
+  end_ = end;
+  step_ = (step > 0) ? step : 1;
+  if (step < 1) step = 1;
+  if (end >= start) 
+    size_ = (end-start)/step_+1;
+  else size_ = 0;
+}
+
+/*!
+  Define a range of indices
+  \param start : start index (inclusive)
+  \param end : end index (inclusive, used if size \<= 0 and end \>= start)
+  \param size : size (number of elements, used if \>= 1 )
+  \param step : step (or stride) = index increment
+
+  \warning If \b size \>= 1 , \b end index computed automatically. 
+  If \b size \< 1 and \b end < \b start , equivalent to \b end = Range()::lastIndex() 
+ */
+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 (size > 0) {  // Nb d'elements fixe
+    size_ = size;
+    if ( (start == end) && (end == Range::lastIndex()) ) start_ = end_ = end;
+    else end_ = start_+(size_-1)*step_;    
+  }
+  else {
+    if (end >= start) {  // Indice de fin fixe 
+      end_ = end;
+      size_ = (end-start)/step_+1;
+    }
+    else {  // rien fixe
+      size_ = 0;
+      end_ = Range::lastIndex();
+    }
+  }
+}
+
+/*
+Range::Range(Range const& a)
+{
+  start_ = a.start_;
+  end_ = a.end_;
+  size_ = a.size_;
+  step_ = a.step_;
+}
+*/
+
+/*!
+  This method is called to recompute index ranges, specifying the original array size
+  by the TArray<T> (or derived classes) sub array extraction methods
+*/ 
+void Range::Update(sa_size_t osz)
+{
+  if (end_ >= 0)  return; 
+  if (osz == 0) {
+    start_ = end_ = 0;
+    size_ = step_ = 1;
+    return;
+  }
+  if (end_ == start_) {
+    end_ = osz-1; 
+    if ((size_ > 0) && (size_ <= osz/step_)) 
+      start_ = end_ - (size_-1)*step_;
+    else {
+      start_ = end_; 
+      size_ = 1;
+    }
+  }
+  else {
+    end_ = osz-1; 
+    size_ = (end_-start_)/step_+1;
+  }
+  //DBG  cout << ">>> DBG/Update start=" << start_ << " end=" << end_ 
+  //DBG     << " size=" << size_ << " step=" << step_ << endl;
+  return;
+}
+
+/*
+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. This class is mainly intented for 
+  initializing TMatrix<T> objects, proportional to the identity matrix. 
+*/
+
+//! Constructor representing a square matrix (\b n x \b n) with value \b diag on the diagonal
+IdentityMatrix::IdentityMatrix(double diag, sa_size_t n)
+{
+  size_ = n;
+  diag_ = diag;
+}
Index: /tags/V_Nov2007/SophyaLib/TArray/utilarr.h
===================================================================
--- /tags/V_Nov2007/SophyaLib/TArray/utilarr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaLib/TArray/utilarr.h	(revision 3445)
@@ -0,0 +1,186 @@
+// 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:
+  //! Index range containing a single index = \b start 
+  Range(sa_size_t start);
+  //! Index range start \<= index \<= end
+  Range(sa_size_t start, sa_size_t end); 
+  //! Index range start \<= index \<= end with increment step 
+  Range(sa_size_t start, sa_size_t end, sa_size_t step);
+  //! General Index range specification, using size or start/end and increment
+  Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step);
+  //! 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_; }
+  //! return a constant value defining the first element
+  inline static sa_size_t firstIndex() { return 0; }
+  //! return a constant value as a placeholder for the last valid index 
+  inline static sa_size_t lastIndex() { return -1; }
+  //! return a Range object specifing all indices, from first to last
+  inline static Range all() 
+  { return Range(Range::firstIndex() , Range::lastIndex()); }
+  //! return a Range object specifing the first index
+  inline static Range first()
+  { return Range(Range::firstIndex() , Range::firstIndex(), 1, 1); }
+  //! return a Range object specifing the last valid index
+  inline static Range last()
+  { return Range(Range::lastIndex() , Range::lastIndex(), 1, 1); }
+
+  //! For internal TArray module use.
+  void Update(sa_size_t osz);
+
+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_Nov2007/SophyaPI/DemoPIApp/CONTENT
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/CONTENT	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/CONTENT	(revision 3445)
@@ -0,0 +1,72 @@
+====== SOPHYA/piapp demo scripts and programs ======
+===============================================================
+              (C) LAL-IN2P3/CNRS   1998-2007 
+              (C) DAPNIA/CEA       1998-2007
+===============================================================
+
+See http://www.sophya.org and the SOPHYA overview manual and piapp 
+user's guide for more information.
+
+1/ script demo.pic and associated demo.ppf data file
+   demo script showing general piapp features 
+csh> spiapp -exec demo
+OR 
+csh> spiapp 
+# Execute the piapp command :
+piapp> exec demo.pic
+
+2/ script tarc.pic 
+  Drawing text, arcs and arrows ...
+piapp> exec demo.pic
+
+3/ fft2d.pic and fft2.cc 
+  c++ execution in piapp 
+piapp> exec fft2d.pic
+
+4/ multicurve.pic
+  Drawing example, superposition of several functions
+piapp> exec multicurve  
+ OR exec multicurve.pic
+
+5/ axel.pic :  Some options for axes
+
+6/ addelts.pic : How to add some graphic objects (circles, rectangles, text) 
+   to a plot, in this case a function plot
+
+7/ pnbpays.pic : How to make and draw a bargraph
+
+8/ resonance.pic : How to make complex plots/drawings , in this case
+   the resonance curve of an harmonic oscillator, using the piapp 
+   scripting capabilities
+
+9/ oh_xva_spring.pic : An other example of complex drawing ...
+
+10/ user.cc : example of function which can be called from piapp
+10.a/ Create the shared/loadable object user.so
+csh> make user.so
+10.b/ in piapp, link the module and call the function
+piapp> link user.so user
+piapp> call user
+#  --> creates NTuple usernt
+# Can be called again [with different arguments]
+piapp> call user aaa 1 2 bbb
+
+
+
+Loadable modules 
+----------------
+piapp capabilities can be extended using loadable modules
+
+11/ exmod.pic , exmodule.cc 
+11.a/ Create the loadable module exmodule.so 
+csh> make exmodule.so 
+11.b/ Execute the script exmod.pic 
+  ---> new commands are added to piapp
+
+12/ exmoddrw.pic exmoddrw.cc 
+csh> make exmoddrw.so 
+ in piapp> exec exmoddrw.pic
+  ---> extends piapp graphic capability by a new drawer
+
+
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/Makefile	(revision 3445)
@@ -0,0 +1,28 @@
+#   ---- Makefile for SOPHYA/DemoPIApp module ----
+#  User functions and loadable modules 
+include $(SOPHYABASE)/include/sophyamake.inc
+
+all : user.so exmodule.so exmoddrw.so
+
+clean : 
+	rm  user.so exmodule.so exmoddrw.so  user.o exmodule.o exmoddrw.o
+
+user.so: user.o
+	$(CXXDLL) -o  user.so  user.o $(SOPHYAALLSLBLIST)
+user.o : user.cc
+	$(CXXCOMPILE) -c -o user.o user.cc
+
+exmodule.so: exmodule.o
+	$(CXXDLL) -o  exmodule.so  exmodule.o $(SOPHYAALLSLBLIST)
+exmodule.o : exmodule.cc
+	$(CXXCOMPILE) -c -o exmodule.o exmodule.cc
+
+exmoddrw.so: exmoddrw.o
+	$(CXXDLL) -o  exmoddrw.so  exmoddrw.o $(SOPHYAALLSLBLIST)
+exmoddrw.o : exmoddrw.cc
+	$(CXXCOMPILE) -c -o exmoddrw.o exmoddrw.cc
+
+
+dump :
+	echo $(SOPHYAALLSLBLIST)
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/addelts.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/addelts.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/addelts.pic	(revision 3445)
@@ -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_Nov2007/SophyaPI/DemoPIApp/axel.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/axel.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/axel.pic	(revision 3445)
@@ -0,0 +1,7 @@
+openppf demo.ppf
+zone 1
+disp h1d 
+setaxelabels 'Axe X - Bins' 'Axe Y - Content' 'blue font=helvetica,bold,16 fixedfontsize'
+newwin
+disp h1d 'finecenteredaxes'
+setaxelabels 'Axe X - Bins' 'Axe Y - Content' 'blue font=helvetica,bold,16 fixedfontsize'
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/demo.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/demo.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/demo.pic	(revision 3445)
@@ -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_Nov2007/SophyaPI/DemoPIApp/exlink.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/exlink.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/exlink.pic	(revision 3445)
@@ -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_Nov2007/SophyaPI/DemoPIApp/exmod.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/exmod.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/exmod.pic	(revision 3445)
@@ -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 make 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_Nov2007/SophyaPI/DemoPIApp/exmoddrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/exmoddrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/exmoddrw.cc	(revision 3445)
@@ -0,0 +1,189 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+
+
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "timing.h"
+#include "srandgen.h"
+#include "nobjmgr.h"
+#include "pistdimgapp.h"
+
+
+//  Exemple de module chargeable ds piapp 
+
+// Classe Drawer de Test 
+class TstSpeedDrw : public PIDrawer {
+public:
+                     TstSpeedDrw(int npt, int nblk);
+  virtual           ~TstSpeedDrw();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+       
+protected:
+  int _npt, _nblk;
+  double * _mesx;
+  double * _mesy;
+};
+
+/* --Methode-- */
+TstSpeedDrw::TstSpeedDrw(int npt, int nblk)
+    : PIDrawer()
+{
+  if (nblk > 1) {
+    int q = npt / nblk;  npt = q*nblk; 
+  }
+  _npt = npt; _nblk = nblk;
+  _mesx = new double[npt];
+  _mesy = new double[npt];
+  double dx = 3./npt;
+  for(int i=0; i<npt; i++) {
+    double x =  i*dx;
+    _mesx[i] = x;
+    _mesy[i] = x*x + 3*drandpm1();
+  }
+  mName = "TstSpeedDrw";
+  cout << " TstSpeedDrw::TstSpeedDrw(" << npt << "," << nblk << ")" << endl;
+} 
+
+/* --Methode-- */
+TstSpeedDrw::~TstSpeedDrw()
+{
+  delete[] _mesx;
+  delete[] _mesy;
+}
+
+/* --Methode-- */
+void TstSpeedDrw::UpdateLimits()
+{
+  double xmin = -0.1 ; 
+  double xmax = 3.1;
+  double ymin = -2.;
+  double ymax = 11.;
+  PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+  PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+  SetLimits(xmin,xmax,ymin,ymax);
+  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+}
+
+
+/* --Methode-- */
+void TstSpeedDrw::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  /*
+  PIMarker mrk = GetGraphicAtt().GetMarker();
+  mrk = (mrk != PI_NotDefMarker) ? mrk : PI_DotMarker;
+  int msz = GetGraphicAtt().GetMarkerSz(); 
+  if (msz < 1) msz = 1;
+  g->SelMarker(msz, mrk);
+  */
+   PrtTim("TstSpeedDrw::Draw() START");
+  if (_nblk < 2) {
+    for(int i=0; i<_npt; i++) 
+      g->DrawMarker(_mesx[i], _mesy[i]);      
+    PrtTim("TstSpeedDrw::Draw() Blk=1 done");
+  }
+  else {
+    int q = _npt/_nblk;
+    PIGrCoord* grx = new PIGrCoord[_nblk];
+    PIGrCoord* gry = new PIGrCoord[_nblk];
+    for(int k=0; k<q; k++) {
+      int off = k*_nblk;
+      for(int j=0; j<_nblk; j++) {
+	grx[j] = _mesx[off+j];
+ 	gry[j] = _mesy[off+j];
+      }
+      g->DrawMarkers(grx, gry, _nblk);
+    }
+    PrtTim("TstSpeedDrw::Draw() Blk>1 done");    
+  }
+}
+
+
+//  Declaration de la fonction d'activation et de desactivation du module
+extern "C" {
+void exmoddrw_init();
+void exmoddrw_end();
+}
+
+
+//  Une classe commande-executor, permettant d'enregistrer de 
+//  nouvelles commandes a piapp
+class exmoddrwExecutor : public CmdExecutor {
+public:
+                exmoddrwExecutor();
+  virtual       ~exmoddrwExecutor();
+  // Execute s'occupe de l'execution effective des commandes
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+/* --Methode-- */
+exmoddrwExecutor::exmoddrwExecutor()
+{
+
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+// On enregistre deux nouvelles commandes 
+string hgrp = "ExModDrw";
+// commande excmd1
+string kw = "tspeeddrw";
+string usage = "tspeeddrw npt nblk gr_opt \n" ;
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+}
+
+/* --Methode-- */
+exmoddrwExecutor::~exmoddrwExecutor()
+{
+}
+
+/* --Methode-- */
+int exmoddrwExecutor::Execute(string& kw, vector<string>& tokens, string&)
+{
+
+NamedObjMgr omg;
+if (kw == "tspeeddrw") {
+  if (tokens.size() < 2) {
+    cout << "Usage: tspeeddrw npt nblk gr_opt" << endl;
+    return(0);
+    }
+  int npt = atoi(tokens[0].c_str());
+  int nblk = atoi(tokens[1].c_str());
+  string opt = "";
+  if (tokens.size() > 2) opt = tokens[2];
+  TstSpeedDrw* drw = new TstSpeedDrw(npt, nblk);
+  string name = "TstSpeedDrw";
+  omg.GetImgApp()->DispScDrawer(drw, name, opt); 
+  }
+
+return(0);
+
+}
+
+static exmoddrwExecutor * tdrwex = NULL;
+/* Nouvelle-Fonction */
+void exmoddrw_init()
+{
+// Fonction d'initialisation du module
+// Appele par le gestionnaire de modules de piapp (PIACmd::LoadModule())
+if (tdrwex) delete tdrwex;
+tdrwex = new exmoddrwExecutor;
+}
+
+/* Nouvelle-Fonction */
+void exmoddrw_end()
+{
+// Desactivation du module
+if (tdrwex) delete tdrwex;
+tdrwex = NULL;
+}
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/exmoddrw.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/exmoddrw.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/exmoddrw.pic	(revision 3445)
@@ -0,0 +1,15 @@
+#  Exemple de macro de commandes pour charger un module
+# Mode trace
+traceon
+#  On passe une commande shell pour fabriquer le module
+# shell make exmoddrw.so
+# On charge le module
+loadmodule exmoddrw.so exmoddrw
+#  Nouvelles commande definie
+help tspeeddrw
+
+#  On fabrique deux vecteurs
+zone 1 2
+tspeeddrw 100000 1
+tspeeddrw 100000 100
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/exmodule.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/exmodule.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/exmodule.cc	(revision 3445)
@@ -0,0 +1,107 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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_Nov2007/SophyaPI/DemoPIApp/fft2d.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/fft2d.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/fft2d.cc	(revision 3445)
@@ -0,0 +1,62 @@
+#define TF r_8
+
+int nlig = 128; int ncol = 128;      
+TMatrix<TF> in(nlig,ncol);          
+int l,c;                             
+for(l=40; l<80; l++)                 
+  for(c=40; c<80; c++) {             
+    double r2 = (l-60.5)*(l-60.5)+(c-60.5)*(c-60.5);   
+    in(l,c) = (TF)30.*exp(-r2/9.);        
+}                                
+//  Le dernier argument de RandomSequence est le sigma du bruit   
+//  Si on veut rajouter du bruit, decommenter les 3 lignes suivantes  
+  TMatrix<TF> noise(nlig,ncol);                                
+  noise = RandomSequence(RandomSequence::Gaussian, 0., 0.5);     
+  in += noise;                                                  
+TMatrix< complex<TF> > fftin;       
+FFTWServer ffts;                     
+ffts.setNormalize(true);             
+cout << " FFTServer info string= " << ffts.getInfo() << endl;
+cout << " Calling ffts.FFTForward(in, fftin) : " << endl;    
+ffts.FFTForward(in, fftin);                                  
+//  On garde les tableau in et fftin avec KeepObj()             
+KeepObj(in);                                                 
+KeepObj(fftin);                                              
+//  On fait un filtre passe-haut     
+//  Il faut savoir que les frequences negatives sont rangees    
+//  dans la seconde moitie du tableau en numero de ligne        
+int kx, ky;                                     
+TMatrix< complex<TF> > fftfb(fftin.NRows(), fftin.NCols());           
+TMatrix< complex<TF> > fftfd(fftin.NRows(), fftin.NCols());           
+// fb : Filtrage brutal , fd :  Filtrage doux 
+for(ky=0; ky<fftin.NRows(); ky++)             
+  for(kx=0; kx<fftin.NCols(); kx++) {
+    int kyy = ky;
+    // deuxieme  partie du tableau - Frequences negatives en y 
+    if (ky > fftin.NRows()/2) kyy = fftin.NRows()-ky;
+    double kr = sqrt((double)kx*kx+kyy*kyy);              
+    complex<TF> att;
+    // Filtrage brutal  fonction en escalier 
+    if (kr < 10)  att = complex<TF>((TF)0.5, (TF)0.);
+    else att = complex<double>(1., 0.);
+    fftfb(ky, kx) = fftin(ky, kx) * att ;   
+    // Filtrage doux sous forme de 1-exp(-alpha k_r)
+    att = complex<TF>((TF)(1.-exp(-kr*0.1)), (TF)0.);   
+    fftfd(ky, kx) = fftin(ky, kx) * att ;   
+  }
+TMatrix<TF> infb(nlig,ncol);          
+TMatrix<TF> infd(nlig,ncol);          
+// FFTBackward -- Attention, le tableau des coefficient de Fourier 
+// est modifie - On en fait une copie 
+TMatrix< complex<TF> > fftf(fftin.NRows(), fftin.NCols());   
+// Pour le filtre brutal
+fftf = fftfb;
+ffts.FFTBackward(fftf, infb);       
+// Pour le filtre doux
+fftf = fftfd;
+ffts.FFTBackward(fftf, infd);       
+//  On garde les tableaux fft filtre et signal filtre
+KeepObj(infb);                                             
+KeepObj(infd);                                             
+KeepObj(fftfb);                                                  
+KeepObj(fftfd);
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/fft2d.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/fft2d.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/fft2d.pic	(revision 3445)
@@ -0,0 +1,29 @@
+#  Exemple de commandes pour creer un tableau de bruit 
+#  et calculer son FFT 
+#  On supprime tous les objets presents ds le repertoire courant
+delobjs *
+#  On a besoin du module IFFTW 
+c++import IFFTW
+#  On execute un bout de code c++ qui cree un tableau 2D (matrice)
+#  avec une etoile au milieu et calcule son FFT , et on fait un filtrage
+#  Ce bout de code se trouve ds le fichier fft2d.cc
+#  et on garde des objets (matrices) cree ds ce bout de code au sein 
+#  de piapp avec KeepObj()
+c++execfrf fft2d.cc
+#  On affiche le resultat
+zone 2 3
+disp in 'notitle'
+addtitle 'Input' ' ' boldfont
+disp fftin 'notitle'
+addtitle 'FFT(Input)' ' ' boldfont
+disp infb 'notitle'
+addtitle 'Filt_Brutal(Input)' ' ' boldfont
+disp fftfb 'notitle'
+addtitle 'FFT(Input)*Filt_Brutal' ' ' boldfont
+disp infd 'notitle'
+addtitle 'Filt_Doux(Input)' ' ' boldfont
+disp fftfd 'notitle'
+addtitle 'FFT(Input)*Filt_Doux' ' ' boldfont
+
+
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/multicurve.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/multicurve.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/multicurve.pic	(revision 3445)
@@ -0,0 +1,17 @@
+#  ---- multicurve.pic -----
+# Trace de courbes multiples en utilisant les
+# possibilites de boucles et variables de type
+# tableau de l'interpreteur de piapp 
+#
+set col ( blue red green yellow violet )
+set a ( 1.0 0.9 0.8 0.7 0.6 )
+setaxesatt 'helveticafont bolditalicfont minorticks intticks'
+zone 1
+func 1.1*sin(1.1*x)/x 0.1 20 50 'black notitle'
+setaxelabels 'Axe X' 'Axe Y = sin(x)/x' 'darkviolet helveticafont bigbolditalicfont'
+for i 0:$#a
+  func $a[i]*sin($a[i]*x)/x 0.1 20.0 50 "same $col[i]" 
+end
+
+setinsetlimits 0.5 0.75 0.5 0.75
+func exp(-x*x) -3 3 40 'inset red stdaxes'
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/oh_xva_spring.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/oh_xva_spring.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/oh_xva_spring.pic	(revision 3445)
@@ -0,0 +1,88 @@
+#  Illustration de cours S1SM - Oscillateur harmonique
+#                             Reza Ansari - Decembre 2003
+
+#  Script de trace de ressort vertical 
+
+defscript spring 'trace de ressort '
+#  $1 : Nombre de zigzag
+#  $2 : Position de ressort en X
+#  $3,$4 : Position YMin,YMax du ressort
+  set ns  $1
+  rpneval x1  $2 0.2 -
+  rpneval x2  $2 0.2 +
+  set ymin  $3
+  set ymax  $4
+  rpneval dy  $ymax $ymin - $ns 2 * .5 + /
+  set yc  $ymin
+  for i 0:$ns
+    set y1  $yc
+    rpneval y2  $y1 $dy +
+    addline $x1 $y1 $x2 $y2 
+    rpneval y1  $y1 $dy +
+    rpneval y2  $y2 $dy +
+    addline $x2 $y1 $x1 $y2
+    rpneval yc  $yc $dy 2 * + 
+  end
+  rpneval x2  $x2 0.2 -
+  set y1  $yc
+  rpneval y2  $yc $dy 0.5 * +
+  addline $x1 $y1 $x2 $y2
+endscript
+
+#  Illustration cours Mouvement oscillateur harmonique
+#  Trace position,vitesse,acceleration x(t), v(t), a(t)
+zone 1
+
+func sin(x) -0.5 10. 100 'axesnone xylimits=-1,10.5,-7,1.5 normalline blue'
+func cos(x) -0.5 10. 100 'same xylimits=-1,10.,-7,1.5 normalline magenta'
+func -sin(x) -0.5 10. 100 'same xylimits=-1,10.5,-7,1.5 normalline red'
+addtext 2 1.2 'Position' 'blue bigboldfont helveticafont horizcenter'
+addtext 6.5 1.2 'Vitesse' 'magenta bigboldfont helveticafont horizcenter'
+addtext 3.7 0.5 'Acc/Force' 'red bigboldfont helveticafont horizcenter vertcenter'
+
+#  Trace d'axes
+addarrow -1 0 10 0 'ftrianglearrow7'
+addtext 7 -0.5 'Temps' 'bigboldfont helveticafont horizcenter'
+addfrect -1 -6.5 10 -6. 'grey normalline'
+addline -1 -6.5 10 -6.5 'normalline'
+addline -1 -6. 10 -6. 'normalline'
+
+#  Trace vecteur vitesse, acceleration pour t=2pi/kk
+for kk 0:7
+  rpneval x  pi 2 / $kk *
+  rpneval ym  $x sin 3 -
+  addmarker $x $ym 'blue marker=fbox,11'
+  spring 8 $x -6 $ym 
+  rpneval vv  $x cos 1 *
+  rpneval avv  $vv fabs
+  set yv0  $ym
+  rpneval yv1  $yv0 $vv +
+  rpneval xv  $x 0.3 -
+  if ( $avv > 0.5 ) then
+    addarrow $xv $yv0 $xv $yv1 'magenta ftrianglemarker9 normalline'   
+    rpneval xv  $xv 0.05 -
+    rpneval yv0  $yv0 $yv1 + 0.5 *
+    addtext $xv $yv0 'V' 'magenta bigboldfont helveticafont horizright vertcenter'
+  else 
+    rpneval yv0  $yv0 $yv1 + 0.5 *
+    addtext $xv $yv0 'V=0' 'magenta bigboldfont helveticafont horizright vertcenter'
+  endif
+  rpneval aa  $x sin -1 *
+  rpneval aaa  $aa fabs
+  set ya0  $ym 
+  rpneval ya1  $ya0 $aa +
+  rpneval xa  $x 0.3 +
+  if ( $aaa > 0.5 ) then
+    addarrow $xa $ya0 $xa $ya1 'red ftrianglemarker9 normalline'   
+    rpneval xa  $xa 0.05 +
+    rpneval ya0  $ya0 $ya1 + 0.5 *
+    addtext $xa $ya0 'F' 'red bigboldfont helveticafont horizleft vertcenter'
+  else 
+    rpneval ya0  $ya0 $ya1 + 0.5 *
+    addtext $xa $ya0 'F=0' 'red bigboldfont helveticafont horizleft vertcenter'
+  endif
+end
+
+#  On en fait un fichier postscript 
+w2eps oh_xva_spring.eps
+
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/pnbpays.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/pnbpays.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/pnbpays.pic	(revision 3445)
@@ -0,0 +1,8 @@
+#  Script de demo piapp 
+#  Representation du PNB (en $, 2003) pour quelques pays
+set pays ( Allemagne Espagne France Italie Pays-Bas Suisse UK USA )
+set pnbh ( 22670 14430 22010 18960 23960 37930 25250 35060 )
+setaxesatt 'font=times,bold,16'
+bargraph pnbh pays - 'blue horizontalbars fill packfrac=0.65 font=helvetica,bold,14'
+setaxelabels 'PNB / Hab , $ 2003' ' ' 'font=times,bold,16'
+w2eps pnbbargraph.eps 
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/resonance.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/resonance.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/resonance.pic	(revision 3445)
@@ -0,0 +1,102 @@
+#  Cours S1SM - Oscillateur harmonique - Courbe de resonance 
+#          Variation en fonction de la courbe d'amortissement
+#                                  Reza Ansari - Janvier 2003 
+
+#  ...........................................................
+#  Script Calcul/trace frequence / gain de resonance
+# Frequence OH non amorti $1 : Omega0
+# Amortissement $2 : Lambda
+# Force exterieur $3 : F0/m
+# $4 : graphic_att
+# $5 : if $5 < 0 --> Pas de trace, calcul omrlast et gainreslast uniquement
+# 
+
+defscript omegares ' Calcul frequence / gain de resonance '
+  rpneval omres  $1 sq 2 $2 sq * - sqrt
+  rpneval gainres  2. $2 * $1 sq $2 sq - sqrt * $3 x<>y / 
+  echo "OmegaRes= $omres  GainRes= $gainres"
+  if ( $5 > -1 ) then  
+    addmarker $omres $gainres "$4"
+    addline $omrlast $gainreslast  $omres $gainres 'black dottedline'
+  endif
+  set omrlast $omres
+  set gainreslast $gainres
+endscript 
+#  ...........................................................
+
+#  ...........................................................
+#  Script trace de courbe de Gain = f (omega)
+# Frequence OH non amorti $1 : Omega0
+# Amortissement $2 : Lambda
+# Force exterieur $3 : F0/m
+# $4 $5: Limite Min,Max en Omega 
+# $6: graphic_att
+
+defscript plotgain ' Trace de courbe de resonance - Gain '
+  func $3/sqrt(($1*$1-x*x)*($1*$1-x*x)+4*$2*$2*x*x) $4 $5 200 "$6" 
+endscript 
+#  ...........................................................
+
+#  ...........................................................
+#  Script trace de courbe de Phase = f (omega)
+# Frequence OH non amorti $1 : Omega0
+# Amortissement $2 : Lambda
+# Force exterieur $3 : F0/m
+# $4 $5: Limite Min,Max en Omega 
+# $6: graphic_att
+
+defscript plotphase
+  func atan2(-2*$2*x,$1*$1-x*x) $4 $5 200 "$6" 
+endscript 
+#  ...........................................................
+
+
+#  Choix des parametres   
+om0 = 1.
+lambda = 0.45
+f0om = 3.
+omegares $om0 $lambda $f0om "boxmarker5 $col" -1
+
+#  Choix de la liste de couleurs et des valeurs d'amortissement
+set colors ( red siennared orange yellow green blue blueviolet )
+set lambdas ( 0.4 0.3   0.2   0.15  0.1  0.075 0.05 )
+setaxesatt 'minorticks timesfont bolditalicfont fixedfontsize'
+
+# echo "DBG222 ------ " 
+
+#  On trace courbe de gain et courbe de phase l'une sur l'autre 
+zone 1 2
+gratt = 'notitle xylimits=0.,2.2,0.25,32. '
+for i 0:7
+  set col $colors[i]
+  set gratt "$gratt $col"
+  set lambda $lambdas[i]
+  plotgain $om0 $lambda $f0om 0. 3. "$gratt"
+  omegares $om0 $lambda $f0om "boxmarker5 $col" $i
+  if ( $i < 1 ) then 
+    setaxelabels 'Frequence' 'Gain' 'timesfont bigbolditalicfont'
+  endif
+  addctext 1.6 $gainres 'l/w' '' '0' "symbolfont bigfont horizright vertcenter $col"
+  rap = $lambda/$om0  
+  addtext 1.65 $gainres "= $rap"  "timesfont bigboldfont horizleft vertcenter $col"
+  gratt = 'same '
+end
+
+
+gratt = 'notitle xylimits=0.,2.2,-3.2,0.2 '
+for i 0:7
+  set col $colors[i]
+  set gratt "$gratt $col"
+  set lambda $lambdas[i]
+  plotphase $om0 $lambda $f0om 0. 3. "$gratt"
+  if ( $i < 1 ) then 
+    setaxelabels 'Frequence' 'Phase' 'timesfont bigbolditalicfont'
+  endif
+  yt = -0.2-0.3*$i 
+  addctext 1.5 $yt 'l/w' '' '0' "symbolfont bigfont horizright vertcenter $col"
+  rap = $lambda/$om0  
+  addtext 1.55 $yt "= $rap"  "timesfont bigboldfont horizleft vertcenter $col"
+  gratt = 'same '
+end
+
+w2eps resonance.eps
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/tarc.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/tarc.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/tarc.pic	(revision 3445)
@@ -0,0 +1,31 @@
+#  ---------- tarc.pic -----------
+#  Essai de trace d'elements graphiques
+# et d'arcs en particulier 
+zone 1
+drpanel -1 1 -1 1
+addline -2 0 2 0 
+addline 0 -0.5 0 0.5 
+addmarker 0 -0.5 'red boxmarker7'
+addmarker 0.5 0. 'red boxmarker7'
+addmarker 0. 0.5 'red boxmarker7'
+addarc  0 -0.5 0.5 0. 0 0.5 'red' 
+
+addmarker 0 -1 'blue boxmarker5'
+addmarker 0.5 0. 'blue boxmarker5'
+addmarker 0 1 'blue boxmarker5'
+addarc 0 -1 0.5 0 0 1 'blue thickline'
+
+addmarker -0.8 0.6 'magenta circlemarker9'
+addmarker -0.4 0.7 'magenta circlemarker9'
+addmarker -0.1 0.65 'magenta circlemarker9'
+addarc -0.8 0.6 -0.4 0.7 -0.1 0.65 'magenta normalline'
+
+# addarc 0 1 0.5 0 0 -1 'green'
+
+addfarc -0.7 0. -0.60 0.15 -0.5 0.2 'yellow normalline'
+addtext -1 1 'Test Trace Arc - Fleches' 'timesfont bigboldfont verttop blueviolet'
+addtext -0.25 0. 'Added Vertical Text' 'timesfont hugeboldfont vertcenter horizcenter textdirvertup'
+addarrow -0.25 -0.5 -0.25 0.9 'thinline gold basicarrow9'
+addarrow -1 -1 -0.3 -0.3 'navyblue normalline ftrianglearrow11'
+addarrow 1 1 0.2  0.2 'orange arrowshapedarrow9'
+addarrow -1 1 -0.1 0.1 'turquoise trianglearrow9'
Index: /tags/V_Nov2007/SophyaPI/DemoPIApp/user.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/DemoPIApp/user.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/DemoPIApp/user.cc	(revision 3445)
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <string>
+
+#include "sopnamsp.h"
+#include "nobjmgr.h"
+
+#include "tvector.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+
+#include "srandgen.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_Nov2007/SophyaPI/PI/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Makefile	(revision 3445)
@@ -0,0 +1,506 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPI.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)lut.o $(SOPHYAOBJP)parradapter.o $(SOPHYAOBJP)pi3ddrw.o $(SOPHYAOBJP)pi3dwdg.o $(SOPHYAOBJP)piapplgen.o $(SOPHYAOBJP)piapplx.o $(SOPHYAOBJP)piaxes.o $(SOPHYAOBJP)piaxestools.o $(SOPHYAOBJP)pibargraph.o $(SOPHYAOBJP)pibwdggen.o $(SOPHYAOBJP)pibwdgx.o $(SOPHYAOBJP)picmap.o $(SOPHYAOBJP)picmapgen.o $(SOPHYAOBJP)picmapview.o $(SOPHYAOBJP)picmapx.o $(SOPHYAOBJP)picons.o $(SOPHYAOBJP)picontainergen.o $(SOPHYAOBJP)picontainerx.o $(SOPHYAOBJP)pidrawer.o $(SOPHYAOBJP)pidrawwin.o $(SOPHYAOBJP)pidrwtools.o $(SOPHYAOBJP)pieldrw.o $(SOPHYAOBJP)pierrdisp.o $(SOPHYAOBJP)pievthandler.o $(SOPHYAOBJP)pifilechogen.o $(SOPHYAOBJP)pifilechox.o $(SOPHYAOBJP)pifontgen.o $(SOPHYAOBJP)pifontx.o $(SOPHYAOBJP)pigraph3d.o $(SOPHYAOBJP)pigraphgen.o $(SOPHYAOBJP)pigraphps.o $(SOPHYAOBJP)pigraphuc.o $(SOPHYAOBJP)pigraphx.o $(SOPHYAOBJP)pigratt.o $(SOPHYAOBJP)pigrcoord.o $(SOPHYAOBJP)piimage.o $(SOPHYAOBJP)piimgtools.o $(SOPHYAOBJP)pilineatt.o $(SOPHYAOBJP)pilistgen.o $(SOPHYAOBJP)pilistx.o $(SOPHYAOBJP)pimenubargen.o $(SOPHYAOBJP)pimenubarx.o $(SOPHYAOBJP)pimenugen.o $(SOPHYAOBJP)pimenux.o $(SOPHYAOBJP)pimsghandler.o $(SOPHYAOBJP)pioptmenugen.o $(SOPHYAOBJP)pioptmenux.o $(SOPHYAOBJP)piperiodx.o $(SOPHYAOBJP)pipixmapgen.o $(SOPHYAOBJP)pipixmapx.o $(SOPHYAOBJP)pipplist.o $(SOPHYAOBJP)pippmenubar.o $(SOPHYAOBJP)pippoptmenu.o $(SOPHYAOBJP)pippviewadapter.o $(SOPHYAOBJP)piscdrawwdg.o $(SOPHYAOBJP)pistdwdggen.o $(SOPHYAOBJP)pistdwdgx.o $(SOPHYAOBJP)pistzwin.o $(SOPHYAOBJP)pisurfdr.o $(SOPHYAOBJP)pitherm.o $(SOPHYAOBJP)pitxtdrw.o $(SOPHYAOBJP)piup.o $(SOPHYAOBJP)piup_def.o $(SOPHYAOBJP)piupdattachment.o $(SOPHYAOBJP)piwdggen.o $(SOPHYAOBJP)piwdgx.o $(SOPHYAOBJP)piwindowgen.o $(SOPHYAOBJP)piwindowx.o $(SOPHYAOBJP)pixtbase.o $(SOPHYAOBJP)piyfxdrw.o $(SOPHYAOBJP)psfile.o $(SOPHYAOBJP)xdispim.o
+	rm -f $(SOPHYALIBP)libPI.a
+ 
+$(SOPHYALIBP)libPI.a : $(SOPHYAOBJP)lut.o $(SOPHYAOBJP)parradapter.o $(SOPHYAOBJP)pi3ddrw.o $(SOPHYAOBJP)pi3dwdg.o $(SOPHYAOBJP)piapplgen.o $(SOPHYAOBJP)piapplx.o $(SOPHYAOBJP)piaxes.o $(SOPHYAOBJP)piaxestools.o $(SOPHYAOBJP)pibargraph.o $(SOPHYAOBJP)pibwdggen.o $(SOPHYAOBJP)pibwdgx.o $(SOPHYAOBJP)picmap.o $(SOPHYAOBJP)picmapgen.o $(SOPHYAOBJP)picmapview.o $(SOPHYAOBJP)picmapx.o $(SOPHYAOBJP)picons.o $(SOPHYAOBJP)picontainergen.o $(SOPHYAOBJP)picontainerx.o $(SOPHYAOBJP)pidrawer.o $(SOPHYAOBJP)pidrawwin.o $(SOPHYAOBJP)pidrwtools.o $(SOPHYAOBJP)pieldrw.o $(SOPHYAOBJP)pievthandler.o $(SOPHYAOBJP)pifilechogen.o $(SOPHYAOBJP)pifilechox.o $(SOPHYAOBJP)pifontgen.o $(SOPHYAOBJP)pifontx.o $(SOPHYAOBJP)pigraph3d.o $(SOPHYAOBJP)pigraphgen.o $(SOPHYAOBJP)pigraphps.o $(SOPHYAOBJP)pigraphuc.o $(SOPHYAOBJP)pigraphx.o $(SOPHYAOBJP)pigratt.o $(SOPHYAOBJP)pigrcoord.o $(SOPHYAOBJP)piimage.o $(SOPHYAOBJP)piimgtools.o $(SOPHYAOBJP)pilineatt.o $(SOPHYAOBJP)pilistgen.o $(SOPHYAOBJP)pilistx.o $(SOPHYAOBJP)pimenubargen.o $(SOPHYAOBJP)pimenubarx.o $(SOPHYAOBJP)pimenugen.o $(SOPHYAOBJP)pimenux.o $(SOPHYAOBJP)pimsghandler.o $(SOPHYAOBJP)pioptmenugen.o $(SOPHYAOBJP)pioptmenux.o $(SOPHYAOBJP)piperiodx.o $(SOPHYAOBJP)pipixmapgen.o $(SOPHYAOBJP)pipixmapx.o $(SOPHYAOBJP)piscdrawwdg.o $(SOPHYAOBJP)pistdwdggen.o $(SOPHYAOBJP)pistdwdgx.o $(SOPHYAOBJP)pistzwin.o $(SOPHYAOBJP)pisurfdr.o $(SOPHYAOBJP)pitherm.o $(SOPHYAOBJP)pitxtdrw.o $(SOPHYAOBJP)piwdggen.o $(SOPHYAOBJP)piwdgx.o $(SOPHYAOBJP)piwindowgen.o $(SOPHYAOBJP)piwindowx.o $(SOPHYAOBJP)pixtbase.o $(SOPHYAOBJP)piyfxdrw.o $(SOPHYAOBJP)psfile.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)lut.o: lut.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lut.cc
+ 
+$(SOPHYAOBJP)parradapter.o: parradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h parradapter.h \
+  $(SOPHYAINCP)machdefs.h lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  parradapter.cc
+ 
+$(SOPHYAOBJP)pi3ddrw.o: pi3ddrw.cc $(SOPHYAINCP)sopnamsp.h \
+  pi3ddrw.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi3ddrw.cc
+ 
+$(SOPHYAOBJP)pi3dwdg.o: pi3dwdg.cc $(SOPHYAINCP)sopnamsp.h \
+  pi3dwdg.h pisysdep.h $(SOPHYAINCP)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 pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.h piwindowx.h piwindowgen.h \
+  picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi3dwdg.cc
+ 
+$(SOPHYAOBJP)piapplgen.o: piapplgen.cc $(SOPHYAINCP)sopnamsp.h \
+  piapplgen.h pimsghandler.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapplgen.cc
+ 
+$(SOPHYAOBJP)piapplx.o: piapplx.cc $(SOPHYAINCP)sopnamsp.h \
+  piapplx.h piapplgen.h pimsghandler.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapplx.cc
+ 
+$(SOPHYAOBJP)piaxes.o: piaxes.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piaxes.cc
+ 
+$(SOPHYAOBJP)piaxestools.o: piaxestools.cc \
+  $(SOPHYAINCP)sopnamsp.h piaxes.h pigraphuc.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piaxestools.cc
+ 
+$(SOPHYAOBJP)pibargraph.o: pibargraph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pibargraph.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibargraph.cc
+ 
+$(SOPHYAOBJP)pibwdggen.o: pibwdggen.cc $(SOPHYAINCP)sopnamsp.h \
+  pibwdggen.h pisysdep.h $(SOPHYAINCP)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 pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.h piwindowx.h piwindowgen.h \
+  picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h pibwdgx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibwdggen.cc
+ 
+$(SOPHYAOBJP)pibwdgx.o: pibwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  pixtbaseP.h pibwdgx.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibwdgx.cc
+ 
+$(SOPHYAOBJP)picmap.o: picmap.cc $(SOPHYAINCP)sopnamsp.h \
+  picmap.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picmapx.h picmapgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmap.cc
+ 
+$(SOPHYAOBJP)picmapgen.o: picmapgen.cc $(SOPHYAINCP)sopnamsp.h \
+  picmapgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picmapx.h picmap.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapgen.cc
+ 
+$(SOPHYAOBJP)picmapview.o: picmapview.cc \
+  $(SOPHYAINCP)sopnamsp.h picmapview.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapview.cc
+ 
+$(SOPHYAOBJP)picmapx.o: picmapx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)machdefs.h \
+  pimsghandler.h picolist.h picmapx.h picmapgen.h pisysdep.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapx.cc
+ 
+$(SOPHYAOBJP)picons.o: picons.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picons.cc
+ 
+$(SOPHYAOBJP)picontainergen.o: picontainergen.cc \
+  $(SOPHYAINCP)sopnamsp.h picontainergen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picontainergen.cc
+ 
+$(SOPHYAOBJP)picontainerx.o: picontainerx.cc \
+  $(SOPHYAINCP)sopnamsp.h picontainerx.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picontainerx.cc
+ 
+$(SOPHYAOBJP)pidrawer.o: pidrawer.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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 pimenux.h pimenugen.h \
+  pioptmenux.h pioptmenugen.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrawer.cc
+ 
+$(SOPHYAOBJP)pidrawwin.o: pidrawwin.cc $(SOPHYAINCP)sopnamsp.h \
+  pidrawwin.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrawwin.cc
+ 
+$(SOPHYAOBJP)pidrwtools.o: pidrwtools.cc \
+  $(SOPHYAINCP)sopnamsp.h pidrwtools.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h pistdwdgx.h \
+  pistdwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrwtools.cc
+ 
+$(SOPHYAOBJP)pieldrw.o: pieldrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pieldrw.cc
+ 
+$(SOPHYAOBJP)pievthandler.o: pievthandler.cc \
+  $(SOPHYAINCP)sopnamsp.h pievthandler.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pievthandler.cc
+ 
+$(SOPHYAOBJP)pifilechogen.o: pifilechogen.cc \
+  $(SOPHYAINCP)sopnamsp.h pifilechogen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifilechogen.cc
+ 
+$(SOPHYAOBJP)pifilechox.o: pifilechox.cc \
+  $(SOPHYAINCP)sopnamsp.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifilechox.cc
+ 
+$(SOPHYAOBJP)pifontgen.o: pifontgen.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+  picmapgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifontgen.cc
+ 
+$(SOPHYAOBJP)pifontx.o: pifontx.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pifontx.h \
+  pifontgen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifontx.cc
+ 
+$(SOPHYAOBJP)pigraph3d.o: pigraph3d.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraph3d.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraph3d.cc
+ 
+$(SOPHYAOBJP)pigraphgen.o: pigraphgen.cc \
+  $(SOPHYAINCP)sopnamsp.h pigraphgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphgen.cc
+ 
+$(SOPHYAOBJP)pigraphps.o: pigraphps.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphps.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphps.cc
+ 
+$(SOPHYAOBJP)pigraphuc.o: pigraphuc.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphuc.cc
+ 
+$(SOPHYAOBJP)pigraphx.o: pigraphx.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphx.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphx.cc
+ 
+$(SOPHYAOBJP)pigratt.o: pigratt.cc $(SOPHYAINCP)sopnamsp.h \
+  pigratt.h pisysdep.h $(SOPHYAINCP)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 \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigratt.cc
+ 
+$(SOPHYAOBJP)pigrcoord.o: pigrcoord.cc $(SOPHYAINCP)sopnamsp.h \
+  pigrcoord.h pisysdep.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigrcoord.cc
+ 
+$(SOPHYAOBJP)piimage.o: piimage.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piimage.h \
+  parradapter.h lut.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piimage.cc
+ 
+$(SOPHYAOBJP)piimgtools.o: piimgtools.cc \
+  $(SOPHYAINCP)sopnamsp.h piimgtools.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piimgtools.cc
+ 
+$(SOPHYAOBJP)pilineatt.o: pilineatt.cc $(SOPHYAINCP)sopnamsp.h \
+  pilineatt.h pisysdep.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilineatt.cc
+ 
+$(SOPHYAOBJP)pilistgen.o: pilistgen.cc $(SOPHYAINCP)sopnamsp.h \
+  pilistgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilistgen.cc
+ 
+$(SOPHYAOBJP)pilistx.o: pilistx.cc $(SOPHYAINCP)sopnamsp.h \
+  pilistx.h pilistgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h piwdgx.h piwdggen.h \
+  pimsghandler.h picolist.h picontainerx.h picontainergen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilistx.cc
+ 
+$(SOPHYAOBJP)pimenubargen.o: pimenubargen.cc \
+  $(SOPHYAINCP)sopnamsp.h pimenubargen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenubargen.cc
+ 
+$(SOPHYAOBJP)pimenubarx.o: pimenubarx.cc \
+  $(SOPHYAINCP)sopnamsp.h pimenubarx.h \
+  pimenubargen.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenubarx.cc
+ 
+$(SOPHYAOBJP)pimenugen.o: pimenugen.cc $(SOPHYAINCP)sopnamsp.h \
+  pimenugen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenugen.cc
+ 
+$(SOPHYAOBJP)pimenux.o: pimenux.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pimenubarx.h \
+  pimenubargen.h pimenux.h pimenugen.h piwdgx.h piwdggen.h pimsghandler.h \
+  picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenux.cc
+ 
+$(SOPHYAOBJP)pimsghandler.o: pimsghandler.cc \
+  $(SOPHYAINCP)sopnamsp.h pimsghandler.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimsghandler.cc
+ 
+$(SOPHYAOBJP)pioptmenugen.o: pioptmenugen.cc \
+  $(SOPHYAINCP)sopnamsp.h pioptmenugen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pimenux.h \
+  pimenugen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pioptmenugen.cc
+ 
+$(SOPHYAOBJP)pioptmenux.o: pioptmenux.cc \
+  $(SOPHYAINCP)sopnamsp.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pioptmenux.cc
+ 
+$(SOPHYAOBJP)piperiodx.o: piperiodx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)machdefs.h \
+  pimsghandler.h picolist.h piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piperiodx.cc
+ 
+$(SOPHYAOBJP)pipixmapgen.o: pipixmapgen.cc \
+  $(SOPHYAINCP)sopnamsp.h pipixmapgen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipixmapgen.cc
+ 
+$(SOPHYAOBJP)pipixmapx.o: pipixmapx.cc $(SOPHYAINCP)sopnamsp.h \
+  pipixmapx.h pipixmapgen.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipixmapx.cc
+ 
+$(SOPHYAOBJP)piscdrawwdg.o: piscdrawwdg.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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 pimenux.h pimenugen.h \
+  pioptmenux.h pioptmenugen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h piaxestools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piscdrawwdg.cc
+ 
+$(SOPHYAOBJP)pistdwdggen.o: pistdwdggen.cc \
+  $(SOPHYAINCP)sopnamsp.h pistdwdggen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdwdggen.cc
+ 
+$(SOPHYAOBJP)pistdwdgx.o: pistdwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pistdwdgx.h \
+  pistdwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+  picontainerx.h picontainergen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdwdgx.cc
+ 
+$(SOPHYAOBJP)pistzwin.o: pistzwin.cc $(SOPHYAINCP)sopnamsp.h \
+  pistzwin.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwindowx.h piwindowgen.h picontainerx.h picontainergen.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)machdefs.h psfile.h pifontgen.h \
+  pigraphgen.h picmap.h picmapx.h picmapgen.h pifontx.h pigrcoord.h \
+  pilineatt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistzwin.cc
+ 
+$(SOPHYAOBJP)pisurfdr.o: pisurfdr.cc $(SOPHYAINCP)sopnamsp.h \
+  pisurfdr.h parradapter.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pisurfdr.cc
+ 
+$(SOPHYAOBJP)pitherm.o: pitherm.cc $(SOPHYAINCP)sopnamsp.h \
+  pitherm.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitherm.cc
+ 
+$(SOPHYAOBJP)pitxtdrw.o: pitxtdrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pitxtdrw.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitxtdrw.cc
+ 
+$(SOPHYAOBJP)piwdggen.o: piwdggen.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdggen.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwdggen.cc
+ 
+$(SOPHYAOBJP)piwdgx.o: piwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)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 \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwdgx.cc
+ 
+$(SOPHYAOBJP)piwindowgen.o: piwindowgen.cc \
+  $(SOPHYAINCP)sopnamsp.h piwindowgen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwindowgen.cc
+ 
+$(SOPHYAOBJP)piwindowx.o: piwindowx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwindowx.h piwindowgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h picontainerx.h \
+  picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwindowx.cc
+ 
+$(SOPHYAOBJP)pixtbase.o: pixtbase.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pixtbaseP.h pibwdgx.h \
+  pisysdep.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pixtbase.cc
+ 
+$(SOPHYAOBJP)piyfxdrw.o: piyfxdrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piyfxdrw.cc
+ 
+$(SOPHYAOBJP)psfile.o: psfile.cc $(SOPHYAINCP)sopnamsp.h \
+  psfile.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psfile.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PI/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Makefile.mgr	(revision 3445)
@@ -0,0 +1,333 @@
+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)pibargraph.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)pitxtdrw.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)pibargraph.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)pitxtdrw.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 pimenux.h pimenugen.h pioptmenux.h \
+ pioptmenugen.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)pibargraph.o: pibargraph.cc $(INC)machdefs.h \
+ pibargraph.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
+$(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 pimenux.h \
+ pimenugen.h pioptmenux.h pioptmenugen.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 pimenux.h pimenugen.h pioptmenux.h pioptmenugen.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 pimenux.h pimenugen.h \
+ pioptmenux.h pioptmenugen.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 ucckprot.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 \
+ $(INC)strutilxx.h
+$(OBJ)pigrcoord.o: pigrcoord.cc pigrcoord.h pisysdep.h \
+ $(INC)machdefs.h
+$(OBJ)piimage.o: piimage.cc pisysdep.h \
+ $(INC)machdefs.h piimage.h parradapter.h \
+ lut.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 pimenux.h pimenugen.h pioptmenux.h \
+ pioptmenugen.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)pitxtdrw.o: pitxtdrw.cc $(INC)machdefs.h \
+ pitxtdrw.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
+$(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 $(INC)pexceptions.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 $(INC)machdefs.h \
+ pixtbaseP.h pibwdgx.h pisysdep.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_Nov2007/SophyaPI/PI/Tests/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/Makefile	(revision 3445)
@@ -0,0 +1,560 @@
+include ../../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)midasitt $(SOPHYAEXEP)pilinetst $(SOPHYAEXEP)pist $(SOPHYAEXEP)pit0 $(SOPHYAEXEP)pit1 $(SOPHYAEXEP)pitcons $(SOPHYAEXEP)pitgr $(SOPHYAEXEP)xp0 $(SOPHYAEXEP)xp1 $(SOPHYAEXEP)xp2 $(SOPHYAEXEP)xp3
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)xp3.o $(SOPHYAOBJP)xp2.o $(SOPHYAOBJP)xp1.o $(SOPHYAOBJP)xp0.o $(SOPHYAOBJP)pitgr.o $(SOPHYAOBJP)pitcons.o $(SOPHYAOBJP)pit1.o $(SOPHYAOBJP)pit0.o $(SOPHYAOBJP)pist.o $(SOPHYAOBJP)pilinetst.o $(SOPHYAOBJP)midasitt.o
+ 
+midasitt: $(SOPHYAEXEP)midasitt
+	echo $@ " done"
+$(SOPHYAEXEP)midasitt: $(SOPHYAOBJP)midasitt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)midasitt.o $(SOPHYAALLSLBLIST)
+ 
+pilinetst: $(SOPHYAEXEP)pilinetst
+	echo $@ " done"
+$(SOPHYAEXEP)pilinetst: $(SOPHYAOBJP)pilinetst.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pilinetst.o $(SOPHYAALLSLBLIST)
+ 
+pist: $(SOPHYAEXEP)pist
+	echo $@ " done"
+$(SOPHYAEXEP)pist: $(SOPHYAOBJP)pist.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pist.o $(SOPHYAALLSLBLIST)
+ 
+pit0: $(SOPHYAEXEP)pit0
+	echo $@ " done"
+$(SOPHYAEXEP)pit0: $(SOPHYAOBJP)pit0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pit0.o $(SOPHYAALLSLBLIST)
+ 
+pit1: $(SOPHYAEXEP)pit1
+	echo $@ " done"
+$(SOPHYAEXEP)pit1: $(SOPHYAOBJP)pit1.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pit1.o $(SOPHYAALLSLBLIST)
+ 
+pitcons: $(SOPHYAEXEP)pitcons
+	echo $@ " done"
+$(SOPHYAEXEP)pitcons: $(SOPHYAOBJP)pitcons.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pitcons.o $(SOPHYAALLSLBLIST)
+ 
+pitgr: $(SOPHYAEXEP)pitgr
+	echo $@ " done"
+$(SOPHYAEXEP)pitgr: $(SOPHYAOBJP)pitgr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pitgr.o $(SOPHYAALLSLBLIST)
+ 
+xp0: $(SOPHYAEXEP)xp0
+	echo $@ " done"
+$(SOPHYAEXEP)xp0: $(SOPHYAOBJP)xp0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp0.o $(SOPHYAALLSLBLIST)
+ 
+xp1: $(SOPHYAEXEP)xp1
+	echo $@ " done"
+$(SOPHYAEXEP)xp1: $(SOPHYAOBJP)xp1.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp1.o $(SOPHYAALLSLBLIST)
+ 
+xp2: $(SOPHYAEXEP)xp2
+	echo $@ " done"
+$(SOPHYAEXEP)xp2: $(SOPHYAOBJP)xp2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp2.o $(SOPHYAALLSLBLIST)
+ 
+xp3: $(SOPHYAEXEP)xp3
+	echo $@ " done"
+$(SOPHYAEXEP)xp3: $(SOPHYAOBJP)xp3.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp3.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)midasitt.o: midasitt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)pidrawwin.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)piyfxdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  midasitt.cc
+ 
+$(SOPHYAOBJP)pilinetst.o: pilinetst.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilinetst.cc
+ 
+$(SOPHYAOBJP)pist.o: pist.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pist.cc
+ 
+$(SOPHYAOBJP)pit0.o: pit0.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pit0.cc
+ 
+$(SOPHYAOBJP)pit1.o: pit1.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)piyfxdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pit1.cc
+ 
+$(SOPHYAOBJP)pitcons.o: pitcons.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitcons.cc
+ 
+$(SOPHYAOBJP)pitgr.o: pitgr.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)pidrawwin.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)piaxestools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pi3dwdg.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitgr.cc
+ 
+$(SOPHYAOBJP)xp0.o: xp0.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp0.cc
+ 
+$(SOPHYAOBJP)xp1.o: xp1.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp1.cc
+ 
+$(SOPHYAOBJP)xp2.o: xp2.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp2.cc
+ 
+$(SOPHYAOBJP)xp3.o: xp3.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pi3dwdg.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp3.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PI/Tests/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/Makefile.mgr	(revision 3445)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := PITest
+MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYADEVREP)/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_Nov2007/SophyaPI/PI/Tests/midasitt.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/midasitt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/midasitt.cc	(revision 3445)
@@ -0,0 +1,524 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pilinetst.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pilinetst.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pilinetst.cc	(revision 3445)
@@ -0,0 +1,397 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pist.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pist.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pist.cc	(revision 3445)
@@ -0,0 +1,940 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pit0.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pit0.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pit0.cc	(revision 3445)
@@ -0,0 +1,310 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <iostream>
+
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pit1.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pit1.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pit1.cc	(revision 3445)
@@ -0,0 +1,572 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pitcons.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pitcons.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pitcons.cc	(revision 3445)
@@ -0,0 +1,297 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <X11/Intrinsic.h>
+#include <Xm/Xm.h>  // Pour *DBG*
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/Tests/pitgr.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pitgr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pitgr.cc	(revision 3445)
@@ -0,0 +1,431 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/pitst.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/pitst.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/pitst.cc	(revision 3445)
@@ -0,0 +1,437 @@
+#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 "sopnamsp.h"
+#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;
+  PrefCompSize(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_Nov2007/SophyaPI/PI/Tests/programs
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/programs	(revision 3445)
@@ -0,0 +1,11 @@
+midasitt midasitt.o
+pilinetst pilinetst.o
+pist pist.o
+pit0 pit0.o
+pit1 pit1.o
+pitcons pitcons.o
+pitgr pitgr.o
+xp0 xp0.o
+xp1 xp1.o
+xp2 xp2.o
+xp3 xp3.o
Index: /tags/V_Nov2007/SophyaPI/PI/Tests/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/smakefile	(revision 3445)
@@ -0,0 +1,560 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)midasitt $(SOPHYAEXEP)pilinetst $(SOPHYAEXEP)pist $(SOPHYAEXEP)pit0 $(SOPHYAEXEP)pit1 $(SOPHYAEXEP)pitcons $(SOPHYAEXEP)pitgr $(SOPHYAEXEP)xp0 $(SOPHYAEXEP)xp1 $(SOPHYAEXEP)xp2 $(SOPHYAEXEP)xp3
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)xp3.o $(SOPHYAOBJP)xp2.o $(SOPHYAOBJP)xp1.o $(SOPHYAOBJP)xp0.o $(SOPHYAOBJP)pitgr.o $(SOPHYAOBJP)pitcons.o $(SOPHYAOBJP)pit1.o $(SOPHYAOBJP)pit0.o $(SOPHYAOBJP)pist.o $(SOPHYAOBJP)pilinetst.o $(SOPHYAOBJP)midasitt.o
+ 
+midasitt: $(SOPHYAEXEP)midasitt
+	echo $@ " done"
+$(SOPHYAEXEP)midasitt: $(SOPHYAOBJP)midasitt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)midasitt.o $(SOPHYAALLSLBLIST)
+ 
+pilinetst: $(SOPHYAEXEP)pilinetst
+	echo $@ " done"
+$(SOPHYAEXEP)pilinetst: $(SOPHYAOBJP)pilinetst.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pilinetst.o $(SOPHYAALLSLBLIST)
+ 
+pist: $(SOPHYAEXEP)pist
+	echo $@ " done"
+$(SOPHYAEXEP)pist: $(SOPHYAOBJP)pist.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pist.o $(SOPHYAALLSLBLIST)
+ 
+pit0: $(SOPHYAEXEP)pit0
+	echo $@ " done"
+$(SOPHYAEXEP)pit0: $(SOPHYAOBJP)pit0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pit0.o $(SOPHYAALLSLBLIST)
+ 
+pit1: $(SOPHYAEXEP)pit1
+	echo $@ " done"
+$(SOPHYAEXEP)pit1: $(SOPHYAOBJP)pit1.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pit1.o $(SOPHYAALLSLBLIST)
+ 
+pitcons: $(SOPHYAEXEP)pitcons
+	echo $@ " done"
+$(SOPHYAEXEP)pitcons: $(SOPHYAOBJP)pitcons.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pitcons.o $(SOPHYAALLSLBLIST)
+ 
+pitgr: $(SOPHYAEXEP)pitgr
+	echo $@ " done"
+$(SOPHYAEXEP)pitgr: $(SOPHYAOBJP)pitgr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pitgr.o $(SOPHYAALLSLBLIST)
+ 
+xp0: $(SOPHYAEXEP)xp0
+	echo $@ " done"
+$(SOPHYAEXEP)xp0: $(SOPHYAOBJP)xp0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp0.o $(SOPHYAALLSLBLIST)
+ 
+xp1: $(SOPHYAEXEP)xp1
+	echo $@ " done"
+$(SOPHYAEXEP)xp1: $(SOPHYAOBJP)xp1.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp1.o $(SOPHYAALLSLBLIST)
+ 
+xp2: $(SOPHYAEXEP)xp2
+	echo $@ " done"
+$(SOPHYAEXEP)xp2: $(SOPHYAOBJP)xp2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp2.o $(SOPHYAALLSLBLIST)
+ 
+xp3: $(SOPHYAEXEP)xp3
+	echo $@ " done"
+$(SOPHYAEXEP)xp3: $(SOPHYAOBJP)xp3.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)xp3.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)midasitt.o: midasitt.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)pidrawwin.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)piyfxdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  midasitt.cc
+ 
+$(SOPHYAOBJP)pilinetst.o: pilinetst.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilinetst.cc
+ 
+$(SOPHYAOBJP)pist.o: pist.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pist.cc
+ 
+$(SOPHYAOBJP)pit0.o: pit0.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pit0.cc
+ 
+$(SOPHYAOBJP)pit1.o: pit1.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)piyfxdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pit1.cc
+ 
+$(SOPHYAOBJP)pitcons.o: pitcons.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitcons.cc
+ 
+$(SOPHYAOBJP)pitgr.o: pitgr.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)pidrawwin.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)piaxestools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pi3dwdg.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitgr.cc
+ 
+$(SOPHYAOBJP)xp0.o: xp0.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp0.cc
+ 
+$(SOPHYAOBJP)xp1.o: xp1.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp1.cc
+ 
+$(SOPHYAOBJP)xp2.o: xp2.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp2.cc
+ 
+$(SOPHYAOBJP)xp3.o: xp3.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)pisurfdr.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pi3dwdg.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  xp3.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PI/Tests/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/usedslibs	(revision 3445)
@@ -0,0 +1,3 @@
+PI
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaPI/PI/Tests/xp0.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/xp0.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/xp0.cc	(revision 3445)
@@ -0,0 +1,111 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+
+
+#include "sopnamsp.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)
+
+{
+puts("xp0: Debut PITApp::PITApp(int narg, char* 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");
+  exit(1);
+  }
+//  Creation de l'objet application et appel de Run()
+puts("xp0: Creation objet Application PITApp ");
+PITApp * app = new PITApp(narg, arg);
+puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Nov2007/SophyaPI/PI/Tests/xp1.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/xp1.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/xp1.cc	(revision 3445)
@@ -0,0 +1,194 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/xp2.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/xp2.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/xp2.cc	(revision 3445)
@@ -0,0 +1,257 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/Tests/xp3.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/Tests/xp3.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/Tests/xp3.cc	(revision 3445)
@@ -0,0 +1,300 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/exclude
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/exclude	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/exclude	(revision 3445)
@@ -0,0 +1,29 @@
+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_def.cc
+xdispim.c
+piup.cc
Index: /tags/V_Nov2007/SophyaPI/PI/exclude.peida
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/exclude.peida	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/exclude.peida	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/exclude_dpc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/exclude_dpc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/exclude_dpc	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/lut.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/lut.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/lut.cc	(revision 3445)
@@ -0,0 +1,121 @@
+// 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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/lut.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/lut.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/lut.h	(revision 3445)
@@ -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 
+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_Nov2007/SophyaPI/PI/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/objlist.list	(revision 3445)
@@ -0,0 +1,63 @@
+lut.o
+parradapter.o
+pi3ddrw.o
+pi3dwdg.o
+piapplgen.o
+piapplx.o
+piaxes.o
+piaxestools.o
+pibargraph.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
+pitxtdrw.o
+piwdggen.o
+piwdgx.o
+piwindowgen.o
+piwindowx.o
+pixtbase.o
+piyfxdrw.o
+psfile.o
Index: /tags/V_Nov2007/SophyaPI/PI/parradapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/parradapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/parradapter.cc	(revision 3445)
@@ -0,0 +1,559 @@
+//     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 "sopnamsp.h"
+#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"
+// 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 ne fait rien. Cette méthode est appelée par les drawers
+//	utilisant l'objet. 
+// int  OptionToString(vector<string> & opt) const
+//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
+//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
+//	Renvoie le nombre d'éléments ajoutés.
+//	L'implémentation par défaut ne fait rien.
+//--
+
+/* --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);
+}
+
+/* --Methode-- */
+int P1DArrayAdapter::DecodeOptionString(vector<string> & /* opt */, bool /*rmdecopt*/)
+{
+return 0;
+}
+/* --Methode-- */
+int P1DArrayAdapter::OptionToString(vector<string> & /*opt*/) const
+{
+return 0;
+}
+
+//++
+// 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
+// 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 ne fait rien. Cette méthode est appelée par les drawers
+//	utilisant l'objet, ou par PIImage .
+// int  OptionToString(vector<string> & opt) const
+//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
+//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
+//	Renvoie le nombre d'éléments ajoutés.
+//	L'implémentation par défaut ne fait rien.
+//--
+
+/* --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, bool htail, 
+					  double nbsig, double fracmax)
+// htail = true --> on vire le pic et on garde la queue de l'histo
+// htail = false --> on garde le pic le l'histo 
+{
+// TIMEF ; 
+int MINNBIN = 64;
+int MAXNBIN = 1024;
+
+int nbin = sX*sY/10;
+nbin = (nbin < MINNBIN) ? MINNBIN : ((nbin > MAXNBIN) ? MAXNBIN : nbin );
+int vitesse = sX*sY / 50000;
+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++; }
+if (sigr < 1) sigr = 1.;
+int sigl = 0;
+q = phis+binmax;
+while ( ((*q) > hmin) && (sigl < binmax) )  { sigl++; q--; }
+if (sigl < 1) sigl = 1.;
+
+if (nbsig <= 0.) nbsig = 1.;
+if (htail == false)  {  /*   On recherche le min/max autour du pic de l'histo  */
+  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; 
+  }
+
+//  On recherche le min/max en supprimant le pic de l'histo  (la queue, > pic)
+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);
+}
+
+/* --Methode-- */
+int P2DArrayAdapter::DecodeOptionString(vector<string> & /* opt */, bool /*rmdecopt*/)
+{
+return 0;
+}
+/* --Methode-- */
+int P2DArrayAdapter::OptionToString(vector<string> & /*opt*/) const
+{
+return 0;
+}
+
+
+//++
+// 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_Nov2007/SophyaPI/PI/parradapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/parradapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/parradapter.h	(revision 3445)
@@ -0,0 +1,144 @@
+// 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"
+
+#include <string> 
+#include <vector> 
+
+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);
+
+//   Methode de decodage des options - Implementation par defaut ne fait rien
+  virtual int DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   liste des options sous forme text - Implementation par defaut ne fait rien
+  virtual int OptionToString(vector<string> & opt) const;
+     
+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, bool htail, 
+				      double 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);
+
+//   Methode de decodage des options - Implementation par defaut ne fait rien
+  virtual int DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   liste des options sous forme text - Implementation par defaut ne fait rien
+  virtual int OptionToString(vector<string> & opt) const;
+
+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) ) 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) ) 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_Nov2007/SophyaPI/PI/pi.rsc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pi.rsc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pi.rsc	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pi3ddrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pi3ddrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pi3ddrw.cc	(revision 3445)
@@ -0,0 +1,447 @@
+// 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 "sopnamsp.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(bool asxy=false, asz=false)
+//	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, -
+//               double scx=1., double scy=1., double scz=1.)
+//	Définition de la boite 3D.
+// void ComputeScaleFactor(double xmin, double xmax, double ymin, double ymax,
+//                         double zmin, double zmax, bool asxy, bool asz,
+//                         double& scy, double& scz)
+//	Calcul des facteurs d'echelles scy, scz
+//	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.
+//
+// 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.);
+  SetAutoScale(false, false);
+}
+
+/* --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, double scx, double scy, double scz)
+{
+  x3Min = xmin;  x3Max = xmax;
+  y3Min = ymin;  y3Max = ymax;
+  z3Min = zmin;  z3Max = zmax;
+  mScx = scx;  mScy = scy;  mScz = scz;
+}
+
+/* --Methode-- */
+void PIDrawer3D::ComputeScaleFactor(double xmin, double xmax, double ymin, double ymax,
+				    double zmin, double zmax, bool asxy, bool asz,
+				    double& scy, double& scz)
+{
+  scy = scz = 1.;
+  if (!asxy && !asz) return;
+  double scm=1.;
+  if ((ymax-ymin) <= 1.e-19)  ymax = ymin + 1.e-19;
+  if (asxy)  { 
+    scy = (xmax-xmin)/(ymax-ymin);
+    scm = xmax-xmin;
+    }
+  else scm =  ((xmax-xmin) > (ymax-ymin)) ? (xmax-xmin)  : (ymax-ymin);
+  if ((zmax-zmin) <= 1.e-19)  zmax = zmin + 1.e-19;
+  if (asz) scz = scm/(zmax-zmin);
+  
+}
+
+/* --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()/mScx, XMax3()/mScx, YMin3()/mScy, YMax3()/mScy, 
+	     ZMin3()/mScz, ZMax3()/mScz);  
+}
+
+/* --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");
+
+}
+
+/* --Methode-- */
+int PIDrawer3D::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 == "rescale") || (opts == "autoscale") ) aScxy = aScz = true;
+    else if ( (opts == "norescale") || (opts == "noautoscale") ) aScxy = aScz = false;
+    else if ( (opts == "rescalexy") || (opts == "autoscalexy") )  aScxy = true;
+    else if ( (opts == "norescalexy") || (opts == "noautoscalexy") )  aScxy = false;
+    else if ( (opts == "rescalez") || (opts == "autoscalez") )  aScz = true;
+    else if ( (opts == "norescalez") || (opts == "noautoscalez") )  aScz = 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);  
+}
+
+/* --Methode-- */
+int PIDrawer3D::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+ if ( aScxy || aScz ) opt.push_back("autoscale");
+ else if (!aScxy && !aScz ) opt.push_back("noautoscale");
+ else {
+   if(aScxy) opt.push_back("autoscalexy"); else opt.push_back("noautoscalexy");
+   if(aScz) opt.push_back("autoscalez"); else opt.push_back("noautoscalez");
+ }
+ return 1;
+}
+
+/* --Methode-- */
+void PIDrawer3D::GetOptionsHelpInfo(string& info)
+{
+info += " ---- PIDrawer3D options help info : \n" ;
+info += "  X/Y,Z axis rescaling option (-> cubic 3D box)  \n";
+info += "  rescale=autoscale/ norescale=noautoscale : X/Y and Z axis \n";
+info += "  rescalexy=autoscalexy / norescalexy=noautoscalexy : X/Y  axis \n";
+info += "  rescalexy=autoscalexy / norescalexy=noautoscalexy : Z axis \n";
+info += " --- + Usual color/line/marker/... attribute decoding  \n";
+// On recupere ensuite la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+return;
+}
+
+/*  --------------------------------------------------------------  */
+/*  ------------------- 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 = PIDrawer3D::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 if (opts == "axesnone")   SetAxesFlags(kAxesNone);
+    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_Nov2007/SophyaPI/PI/pi3ddrw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pi3ddrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pi3ddrw.h	(revision 3445)
@@ -0,0 +1,128 @@
+// 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,
+				 double scx=1., double scy=1., double scz=1.);
+  inline  void		SetAutoScale(bool fgxy, bool fgz) 
+    { aScxy = fgxy;  aScz = fgz; }
+
+  inline  void		Copy3DBox(PIDrawer3D& dr3) {
+    Set3DBox(dr3.XMin3(), dr3.XMax3(), dr3.YMin3(), dr3.YMax3(), 
+	     dr3.ZMin3(), dr3.ZMax3(), dr3.GetScaleX(), dr3.GetScaleY(), dr3.GetScaleZ());  
+    SetAutoScale(dr3.isAutoScaleXY(), dr3.isAutoScaleZ());
+  }
+
+  static  void	        ComputeScaleFactor(double xmin, double xmax, double ymin, double ymax,
+					   double zmin, double zmax, bool asxy, bool asz,
+					   double& scy, double& scz);
+  
+  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);
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual int        OptionToString(vector<string> & opt) const;
+//   Texte d'aide des options disponibles
+  virtual void       GetOptionsHelpInfo(string& info);
+
+  // Cordonnees du cube 3D
+  inline double XMin3() const {return x3Min;}
+  inline double XMax3() const {return x3Max;}
+  inline double YMin3() const {return y3Min;}
+  inline double YMax3() const {return y3Max;}
+  inline double ZMin3() const {return z3Min;}
+  inline double ZMax3() const {return z3Max;}
+  // Facteur d'echelle: Cube3D = Coord.User(3D)*Scale
+  inline double GetScaleX() const {return mScx;}
+  inline double GetScaleY() const {return mScy;}
+  inline double GetScaleZ() const {return mScz;}
+  inline double ScaleX(double x) const {return x*mScx;}
+  inline double ScaleY(double y) const {return y*mScy;}
+  inline double ScaleZ(double z) const {return z*mScz;}
+  inline bool   isAutoScaleXY() const { return aScxy; }
+  inline bool   isAutoScaleZ()  const { return aScz; }
+
+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 
+  double mScx, mScy, mScz;  // Facteur d'echelle entre coord. utilise et cube 3D
+                            // x/y/z-Cube3D = x/y/z-User * mScx/y/z 
+  bool aScxy, aScz;    // Auto-scale X-Y, Z
+};
+
+
+// -----------------  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_Nov2007/SophyaPI/PI/pi3dwdg.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pi3dwdg.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pi3dwdg.cc	(revision 3445)
@@ -0,0 +1,661 @@
+// 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 "sopnamsp.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>D : Affichage du menu de manipulation des traceurs (drawers)
+//	* <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>U : Reinitialise la vue 3D (vue par défaut) et rafraichit le dessin.
+//	* <Alt>R : Rafraichit le dessin du widget.
+//	* <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, bool lock=false)
+//	Ajoute un Drawer3D. Voir *PIBaseWdg::AddDrawer()* pour les flags "ad,lock".
+//--
+
+/* --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;
+  // On cree l'objet PIGraphic3D pour la gestion des vues 3D
+  mGr3d = new PIGraphic3D(mWGrC, 0, 0, sx, sy);
+
+//  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);
+  mBDrw->SetLimits(0.,1.,0.,1.,kAxeDirLtoR,kAxeDirDownUp);
+  AddDrawer3D(mBDrw, false, true);
+  mBDrw->SetAxesFlags(kStdAxes);
+  Set3DViewBox(0., 1., 0., 1., 0., 1., false, false);
+  vfixed = false; // Il faut laisser le premier Drawer3D fixer les limites et la vue 3D
+  fixed3DBox = false;  
+
+  mPx = mPy = 0;
+
+  lPx = lPy = 0;
+  lCol = PI_Black;
+  cTeta = cPhi = 0.;  cUlen = 1.;
+
+// Menu pour la manipulation des drawers 
+  mDrwMen = NULL;
+
+  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);    
+
+  rOfg = false;
+  axfg = true;
+  skcfg = false;
+}
+
+/* --Methode-- */
+PIDraw3DWdg::~PIDraw3DWdg()
+{
+  delete mBDrw;
+  delete mGr3d;
+  if (mDrwMen) delete mDrwMen;
+}
+
+/* --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::Set3DViewBox(double xmin, double xmax, double ymin, double ymax,
+			       double zmin, double zmax, bool asxy, bool asz)
+{
+  double mscx, mscy, mscz;
+  PIDrawer3D::ComputeScaleFactor(xmin, xmax, ymin, ymax, zmin, zmax, 
+				 asxy, asz, mscy, mscz);
+  mscx = 1.;
+  xmin *= mscx;  xmax *= mscx;
+  ymin *= mscy;  ymax *= mscy;
+  zmin *= mscz;  zmax *= mscz;
+  mBDrw->Set3DBox(xmin, xmax, ymin, ymax, zmin, zmax, mscx, mscy, mscz);
+  mBDrw->SetAutoScale(asxy, asz);
+  fixed3DBox = true;
+
+  double D = xmax-xmin;
+  if (D < (ymax-ymin))  D = ymax-ymin;
+  if (D < (zmax-zmin))  D = zmax-zmin;
+  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);  
+    
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Update3DView()
+{
+  list<int>::iterator it = m3DrIl.begin();
+#if defined(CC_HAS_RTTI_SUPPORT)
+  while ( (it != m3DrIl.end()) && 
+	  (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)) == mBDrw) ) it++; 
+  if (it == m3DrIl.end())  return;
+  PIDrawer3D* dr3 = dynamic_cast<PIDrawer3D*>(GetDrawerId(*it));
+#else
+  while ( (it != m3DrIl.end()) && 
+	  ( (PIDrawer3D*)(GetDrawerId(*it)) == mBDrw) ) it++; 
+  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);
+  mBDrw->Copy3DBox(*dr3);
+  Refresh();
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Refresh()
+{
+  SetDrawers3DView();
+  PIBaseWdg::Refresh();
+}
+
+/* --Methode-- */
+int PIDraw3DWdg::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  if (opt.size() == 0)  return(0);  
+
+  vector<string> udopt;
+  unsigned int k = 0;
+  int ndec = opt.size();
+  bool fg3db = false;
+
+  double xmin = mBDrw->ScaleX( mBDrw->XMin3() );
+  double xmax = mBDrw->ScaleX( mBDrw->XMax3() );
+  double ymin = mBDrw->ScaleY( mBDrw->YMin3() );
+  double ymax = mBDrw->ScaleY( mBDrw->YMax3() );
+  double zmin = mBDrw->ScaleY( mBDrw->ZMin3() );
+  double zmax = mBDrw->ScaleY( mBDrw->ZMax3() );
+  bool asxy = mBDrw->isAutoScaleXY();
+  bool asz = mBDrw->isAutoScaleZ();
+
+  // Decodage des options par le PIElDrawer3D de base
+  int ndec1 = mBDrw->DecodeOptionString(opt, rmdecopt);
+
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    // Couleur d'arriere plan du widget
+    if (opts.substr(0,7) == "wbgcol=") {
+      vector<string> vsc;
+      vsc.push_back(opts.substr(7));
+      SetBackgroundColor(PIGraphicAtt(vsc).GetColor());
+      continue;
+    }
+    // Limites en x,y
+    if (opts.substr(0,10) == "xyzlimits=") {
+      sscanf(opts.substr(10).c_str(),"%lg,%lg,%lg,%lg,%lg,%lg",
+	     &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
+      fg3db = true;
+      continue;
+    }
+    if (opts.substr(0,9) == "lim3dbox=") {
+      sscanf(opts.substr(9).c_str(),"%lg,%lg,%lg,%lg,%lg,%lg",
+	     &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
+      fg3db = true;
+      continue;
+    }
+    if (opts == "autoscale3dbox") {
+      asxy = asz = true;
+      fg3db = true;
+      continue;
+    }
+    if (opts == "noautoscale3dbox") {
+      asxy = asz = false;
+      fg3db = true;
+      continue;
+    }
+    if (opts == "autoscalexy3dbox") {
+      asxy = true;
+      fg3db = true;
+      continue;
+    }
+    if (opts == "noautoscalexy3dbox") {
+      asxy = false;
+      fg3db = true;
+      continue;
+    }
+    if (opts == "autoscalez3dbox") {
+      asz = true;
+      fg3db = true;
+      continue;
+    }
+    if (opts == "noautoscalez3dbox") {
+      asz = false;
+      fg3db = true;
+      continue;
+    }
+    // Option non decode 
+    ndec--;
+    if (rmdecopt) udopt.push_back(opts);    
+  }
+
+  if (fg3db)  Set3DViewBox(xmin,xmax,ymin,ymax,zmin,zmax,asxy,asz);
+  
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+
+
+/* --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;
+
+  for(it = m3DrIl.begin(); it != m3DrIl.end(); it++) {
+#if defined(CC_HAS_RTTI_SUPPORT)
+    if (vo) 
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+    else   
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);  
+  (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Copy3DBox(*mBDrw);
+#else
+  if (vo)   
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else  
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);  
+  ((PIDrawer3D*)(GetDrawerId(*it)))->Copy3DBox(*mBDrw);
+#endif
+  }
+
+}
+
+/* --Methode-- */
+int PIDraw3DWdg::AddDrawer3D(PIDrawer3D* dr3, bool ad, bool lock)
+{
+if ((!vfixed) && (dr3 != mBDrw))  { 
+  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);
+  mBDrw->Copy3DBox(*dr3);
+  }
+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);
+  dr3->Copy3DBox(*mBDrw);
+  }
+int id = AddDrawer(dr3, false, false, ad, lock);
+if (dr3 != mBDrw) 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 == 'D' || key == 'd') { // Menu de manipulation des drawers
+    if (mDrwMen) delete mDrwMen;
+    mDrwMen = new PIDrwMgrMenu(this, true);
+    mDrwMen->Show();
+  }  
+
+  else if (key == 'A' || key == 'a')  {    // On affiche ou on enleve les axes
+    axfg = !axfg;
+    list<int>::iterator it;
+    if (!axfg) mBDrw->SetAxesFlags(kAxesNone);
+    else mBDrw->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')  Refresh();
+  else if (key == 'U' || key == 'u')  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);
+  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_Nov2007/SophyaPI/PI/pi3dwdg.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pi3dwdg.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pi3dwdg.h	(revision 3445)
@@ -0,0 +1,101 @@
+// 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 PIDrwMgrMenu;
+
+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.);
+  virtual 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);
+
+  // Definition/on impose la boite 3D
+  virtual void		Set3DViewBox(double xmin, double xmax, double ymin, double ymax,
+				     double zmin, double zmax, bool asxy, bool asz);
+
+  virtual void          Update3DView();   // Vue 3-D a partir de Drawer No 1
+
+  virtual void          Refresh();
+
+  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, bool lock=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
+  bool fixed3DBox;  // Set3DViewBox() 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
+
+
+// Menu pour la manipulation des drawers 
+  PIDrwMgrMenu* mDrwMen;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/piapplgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piapplgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piapplgen.cc	(revision 3445)
@@ -0,0 +1,196 @@
+//  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 "sopnamsp.h"
+#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.
+//
+// void  RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos=false, unsigned char va= PIVA_Def)
+//	Redirige le flot de sortie ("stdout" sous Unix) vers l'objet 
+//	PIConsole "cons", a travers le fichier "flnm". 
+//	Si "cons==NULL", redirection sur le flot original.
+//	Si "fgcpos==true", recopie sur le flot original, en plus de la redirection.
+//
+// void  RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos=false, unsigned char va= PIVA_Def)
+//	Redirige le flot des messages d'erreur ("stderr" sous Unix) 
+//	vers l'objet PIConsole "cons", a travers le fichier "flnm".  
+//	Si "cons==NULL", redirection sur le flot original.
+//	Si "fgcpos==true", recopie sur le flot original, en plus de la redirection.
+//--
+
+//++
+// 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_Nov2007/SophyaPI/PI/piapplgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piapplgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piapplgen.h	(revision 3445)
@@ -0,0 +1,57 @@
+#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_Red) = 0;
+
+        virtual void              RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos=false, 
+						    unsigned char va= PIVA_Def)  = 0;
+        virtual void              RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos=false, 
+						    unsigned char va= PIVA_Def)  = 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_Nov2007/SophyaPI/PI/piapplx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piapplx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piapplx.cc	(revision 3445)
@@ -0,0 +1,532 @@
+#include <stdio.h>
+#include <X11/cursorfont.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+#include <X11/StringDefs.h>
+#include <Xm/Xm.h>
+#include "sopnamsp.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 <sys/types.h>
+#include <sys/stat.h>
+
+#include <iostream>
+
+
+// #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 bool fgcopieos[2]={false, false};    // Si true, recopie sur descripteurs de depart, en plus de redirection
+static int  readfiledes[2]={-1, -1};   // descripteurs de fichiers ouvert en lecture , si redirection a travers fichier
+static XtIntervalId intervid[2];
+static unsigned long tm_interv = 40;   // intervalle timer = 40 ms
+
+//DBG static FILE * dbgfip = NULL;
+
+// call-back pour gestion de redirection stdout/stderr avec pipe 
+static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
+{
+char buff[512];
+int nr, tnr;
+
+int idx = *((int*)cld);
+if (idx != 1) idx = 0; 
+if (!consstream[idx]) return;
+tnr = 0;
+while ( (nr=read(*fd, buff, 511)) > 0 ) {
+  buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
+  tnr += nr;
+  }
+if (tnr > 0) consstream[idx]->Refresh();
+}
+
+// call-back pour gestion de redirection stdout/stderr avec pipe 
+static void redirectstream_timeout_callback(XtPointer cld, XtIntervalId * /*tid*/)
+{
+char buff[512];
+int nr, tnr;
+
+int idx = *((int*)cld);
+if (idx != 1) idx = 0; 
+if (!consstream[idx]) return;
+tnr = 0;
+while ( (nr=read(readfiledes[idx], buff, 511)) > 0 ) {
+  buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
+  tnr += nr;
+  if (fgcopieos[idx]) write(origfiledes[idx], buff, nr);   // recopie sur filedesc original
+  }
+if (tnr > 0) consstream[idx]->Refresh();
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+intervid[idx] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback, (XtPointer)(streamno+idx));
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
+{
+if ( origfiledes[0]<0 )  origfiledes[0] = fcntl(1, F_DUPFD, 0);     
+if ( cons == consstream[0]) { 
+  streamva[0] = va;
+  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);
+//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
+{
+if ( origfiledes[1]<0 )  origfiledes[1] = fcntl(2, F_DUPFD, 0);     
+if ( cons == consstream[1]) { 
+  streamva[1] = va;
+  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));
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
+{
+if (origfiledes[0] < 0)  { 
+  origfiledes[0] = dup(1); 
+  if (origfiledes[0] < 0) { perror("RedirectOutStream()/ERROR ofd[0]<0 "); return; }
+}
+if (readfiledes[0] > -1)  { close(readfiledes[0]); readfiledes[0] = -1;}
+if (!cons) { // requete d'annulation de redirection 
+  if (origfiledes[0] > -1) dup2(origfiledes[0], 1);
+  XtRemoveTimeOut(intervid[0]);
+  consstream[0] = NULL;  
+  return;
+  }
+
+int fidso =  open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
+if (fidso < 0) {
+  printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
+  return;
+}
+int rdfid =  open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
+if (rdfid < 0) {
+  printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
+  return;
+}
+readfiledes[0] = rdfid;
+dup2(fidso, 1);   // close(1=stdout), recopie fidso en fd=1
+close(fidso);    // on ferme le fidso (on l'a recopie en fd=1)
+consstream[0] = cons; streamva[0] = va;  fgcopieos[0] = fgcpos;
+
+#if (!defined(__GNUG__) && !defined(HPUX))
+setlinebuf(stdout);
+#endif
+ios::sync_with_stdio();
+
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+intervid[0] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback, 
+			      (XtPointer)(streamno+0));
+
+//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
+{
+if (origfiledes[1] < 0)  { 
+  origfiledes[1] = dup(2); 
+  if (origfiledes[1] < 0) { perror("RedirectOutStream()/ERROR ofd[1]<0 "); return; }
+}
+if (readfiledes[1] > -1)  { close(readfiledes[1]); readfiledes[1] = -1;}
+if (!cons) { // requete d'annulation de redirection 
+  if (origfiledes[1] > -1) dup2(origfiledes[1], 2);
+  XtRemoveTimeOut(intervid[1]);
+  consstream[1] = NULL;  
+  return;
+  }
+
+int fidso =  open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
+if (fidso < 0) {
+  printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
+  return;
+}
+int rdfid =  open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
+if (rdfid < 0) {
+  printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
+  return;
+}
+readfiledes[1] = rdfid;
+dup2(fidso, 2);   // close(2=stderr), recopie fidso en fd=2
+close(fidso);    // on ferme le fidso (on l'a recopie en fd=2)
+consstream[1] = cons; streamva[1] = va;  fgcopieos[1] = fgcpos;
+
+#if (!defined(__GNUG__) && !defined(HPUX))
+setlinebuf(stderr);
+#endif
+ios::sync_with_stdio();
+
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+intervid[1] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback, 
+			      (XtPointer)(streamno+1));
+}
+
Index: /tags/V_Nov2007/SophyaPI/PI/piapplx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piapplx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piapplx.h	(revision 3445)
@@ -0,0 +1,44 @@
+#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_Red);
+  virtual void              RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos=false, 
+					      unsigned char va= PIVA_Def);
+  virtual void              RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos=false, 
+					      unsigned char va= PIVA_Def);
+
+  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_Nov2007/SophyaPI/PI/piaxes.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piaxes.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piaxes.cc	(revision 3445)
@@ -0,0 +1,883 @@
+// Module PI : Peida Interactive     PIAxes
+// Methodes de trace des axes 
+//                    R. Ansari - 2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <iostream>
+#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()
+{
+  ConfigureTicks();
+  ConfigureAutoFontSize();
+  ConfigureAxesCenter();
+  setupDone = false;
+}
+
+/* --Methode-- */
+PIAxes::~PIAxes()
+{
+}
+
+//++
+// void  DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, \
+//                  unsigned int flags=kAxesDflt, bool afsz=true)
+//	Trace les axes en utilisant les limites de l'objet PIGraphicUC. 
+//	"flags" spécifie les attributs d'axes. Constantes prédéfinies: 
+//|	kCentAxes : Axes passant par le centre
+//|     kBoxAxes  : Axes entourant le tracé
+//|	kIntTicks, kExtTicks
+//|	kMajTicks, kMinTicks
+//|	kLabelsH, kLabelsV, kLabels
+//|	kAxesDflt = kStdAxes =
+//|	      kBoxAxes | kTicks | | kIntTicks | kLabels
+//|	kGridOn, kAxesNone
+//	Si "afsz == true", la taille de fonte est choisie automatiquement.
+//
+// void DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, \
+//        double xmin, double xmax, double ymin, double ymax, \
+//        unsigned int flags=kAxesDflt, bool afsz=true)
+//	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, (double)xmin, (double)xmax, 
+	     (double)ymin, (double)ymax, flags, afsz);
+}
+
+/* --Methode-- */
+void PIAxes::DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			double xmin, double xmax, double ymin, double ymax,
+			unsigned int flags, bool afsz)
+
+{
+  if ((flags&kTicks)&&!(flags&kIntTicks)&&!(flags&kExtTicks))
+    flags |= kIntTicks;  // Ticks internes par defaut
+  if ((flags&kTicks)&&!(flags&kMajTicks)&&!(flags&kMinTicks))
+    flags |= kMajTicks;  // Ticks majeures par defaut
+  
+  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 = (yMax-yMin)*fontSz;
+    g->SelFontSz(fsz);
+  }
+
+  if (flags & kCentAxes) {
+
+    // Les axes
+    double x0axes = (xMin+xMax)/2.,  y0axes = (yMin+yMax)/2.;
+    if(axesCenter) {x0axes = axesCentX0; y0axes = axesCentY0;}
+    if(x0axes<xMin || x0axes>xMax) x0axes = (xMin+xMax)/2.;
+    if(y0axes<yMin || y0axes>yMax) y0axes = (yMin+yMax)/2.;
+    
+    g->DrawLine(xMin, y0axes, xMax, y0axes);
+    g->DrawLine(x0axes, yMin, x0axes, yMax);
+    //    PIArrowMarker amk = g->GetArrowMarker();
+    //    if (amk == PI_NotDefArrowMarker) 
+    PIArrowMarker amk =  amk = PI_FTriangleArrowMarker;
+    g->SelArrowMarkerSz(xMajTickLen*2., amk);
+    //    g->SelArrowMarker(5, g->GetArrowMarker());
+    double xm2 = g->DeltaUCX(xMax, yMajTickLen*2.);
+    g->DrawArrowMarker(xMax, y0axes, xm2, y0axes, true);
+    double ym2 = g->DeltaUCY(yMax, xMajTickLen*2.);
+    g->DrawArrowMarker(x0axes, yMax, x0axes, ym2, true);
+    // La grille en pointilles
+
+    if (flags & kGridOn) DrawGrid(g);
+  
+    // Les ticks majeurs
+  
+    if ((flags & kTicks) && (flags & kMajTicks)) {
+        DrawHTicks(g, y0axes, xMajTickLen, xMajTickLen, xMajTicks);
+        DrawVTicks(g, x0axes, yMajTickLen, yMajTickLen, yMajTicks);
+    }
+    
+    // Les ticks mineurs
+  
+    if ((flags & kTicks) && (flags & kMinTicks)) {
+        DrawHTicks(g, y0axes, xMinTickLen, xMinTickLen, xMinTicks);
+        DrawVTicks(g, x0axes, yMinTickLen, yMinTickLen, yMinTicks);
+    }
+    
+    // Les labels
+    
+    if (flags & kLabelsH) {
+      double declab = 2*xMajTickLen;
+      if (!aYdir)
+        DrawHLabels(g, y0axes-declab, xMajTicks, PI_VerticalTop);
+      else 
+        DrawHLabels(g, y0axes+declab, xMajTicks, PI_VerticalTop);
+    }
+    if (flags & kLabelsV) {
+      double declab = 2.*yMajTickLen;
+      if (!aXdir)
+        DrawVLabels(g, x0axes-declab, yMajTicks, PI_HorizontalRight);
+      else 
+        DrawVLabels(g, x0axes+declab, 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
+    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 & kTicks) && (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 & kTicks) && (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 & kLabelsH) {
+      double declab = xMajTickLen;
+      if (flags & kExtTicks) declab *= 2.;
+      if (!aYdir) {
+        DrawHLabels(g, g->DeltaUCY(yMin, -declab), xMajTicks, PI_VerticalTop);
+      }
+      else {
+        DrawHLabels(g, g->DeltaUCY(yMax,  declab), xMajTicks, PI_VerticalTop);
+      }
+    }
+    if (flags & kLabelsV) {
+      double declab = yMajTickLen;
+      if (flags & kExtTicks) declab *= 2.;
+      if (!aXdir) {
+        DrawVLabels(g, g->DeltaUCX(xMin, -declab), yMajTicks, PI_HorizontalRight);
+      }
+      else {
+        DrawVLabels(g, g->DeltaUCX(xMax,  declab), 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);  
+    if(axesCenter) fy = axesCentY0;
+    else fy = 0.5*(yMin+yMax);
+    if(fy<yMin || fy>yMax) fy = (yMin+yMax)/2.;
+  }
+  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);
+    if(axesCenter) fx = axesCentX0;
+    else fx = 0.5*(xMin+xMax);
+    if(fx<xMin || fx>xMax) fx = (xMin+xMax)/2.;
+  }
+  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);
+  
+}
+
+//++
+// void ConfigureTicks(int ntickx=10, int nticky=12, \
+//		       double majtl=0.0125, double mintl=0.07)
+//	Configuration du nombre de ticks et taille des ticks.
+//	La taille des ticks est exprimée en fraction de la taille totale
+//	(X/Y max-min). Les paramètres ne sont pas changés si des valeurs
+//	négatives ou nulles sont spécifiées.
+// void ConfigureAutoFontSize(double fszf=0.0125)
+//	Configuration de la taille de fonte, en mode AutoFontSize.
+//	La taille est exprimée en fraction de la taille totale YMax-Min
+// void  ConfigureAxesCenter(bool fset,double x0,double y0)
+//	Force axe center to be at (x0,y0) or let it be in the middle
+//--
+
+/* --Methode-- */
+void PIAxes::ConfigureTicks(int ntickx, int nticky, 
+			    double majtl, double mintl)
+{
+  if (ntickx > 0) xNTicks = ntickx;
+  if (nticky > 0) yNTicks = nticky;
+  if (majtl > 1.e-19) fMajTickLen = majtl;
+  if (mintl > 1.e-19) fMinTickLen = mintl;
+}
+
+/* --Methode-- */
+void PIAxes::ConfigureAutoFontSize(double fszf)
+{
+  if (fszf > 1.e-19) fontSz = fszf;
+}
+
+/* --Methode-- */
+void PIAxes::ConfigureAxesCenter(bool fset,double x0,double y0)
+{
+ axesCenter = fset;
+ if(!axesCenter) return;
+ axesCentX0 = x0;
+ axesCentY0 = y0;
+}
+
+/* --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();
+
+  //   Reza - Mars 03 - Nb de ticks en parametres
+  int ntick_x = (aXlog) ? xNTicks : xNTicks;
+  if(aXlog) BestTicksLog(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+  else BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+
+  int ntick_y = (aYlog) ? yNTicks : yNTicks;
+  if(aYlog) BestTicksLog(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+  else BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+
+  //   Reza - Mars 03 - Taille des ticks en parametres
+  yMajTickLen = (xMax-xMin)*fMajTickLen;  // Au lieu de / 100  
+  yMinTickLen = (xMax-xMin)*fMinTickLen;  // Au lieu de / 200 ou 250
+  xMajTickLen = (yMax-yMin)*fMajTickLen;  // Au lieu de / 100
+  xMinTickLen = (yMax-yMin)*fMinTickLen;  // Au lieu de / 200 ou 250
+
+  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,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,0.5*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_Nov2007/SophyaPI/PI/piaxes.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piaxes.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piaxes.h	(revision 3445)
@@ -0,0 +1,108 @@
+// 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 {
+  kCentAxes    = 0x0001,
+  kBoxAxes     = 0x0002,
+  kTicks       = 0x0004,
+  kGridOn      = 0x0008,
+
+  kIntTicks    = 0x0010,
+  kExtTicks    = 0x0020,
+  kMajTicks    = 0x0040,
+  kMinTicks    = 0x0080,
+
+  kLabelsH     = 0x1000,
+  kLabelsV     = 0x2000,
+  kLabels      = kLabelsH | kLabelsV,
+
+// Axes trace par defaut
+  kAxesDflt    = kBoxAxes | kTicks | kMajTicks | kIntTicks | kLabels,       
+  kStdAxes     = kAxesDflt,       
+  kAxesNone    = 0         // Pas de trace d axe  
+};
+
+
+class PIAxes {
+public:
+
+                    PIAxes();
+  virtual           ~PIAxes();
+
+  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			       unsigned int flags=kAxesDflt, bool afsz=true);
+
+  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			       double xmin, double xmax, 
+			       double ymin, double ymax,
+			       unsigned int flags=kAxesDflt, bool afsz=true);
+
+
+  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); 
+
+  //  Taille des ticks d'axes (en fraction de taille d'axe)
+  void  ConfigureTicks(int ntickx=10, int nticky=12, 
+		       double majtl=0.016, double mintl=0.01);
+  void  ConfigureAutoFontSize(double fszf=0.04);
+  void  ConfigureAxesCenter(bool fset=false,double x0=0.,double y0=0.);
+
+  //  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;
+  
+  int xNTicks, yNTicks;             // Nb de ticks en X, Y
+  double fMajTickLen, fMinTickLen;  // Taille des ticks, en fraction de Max-Min
+  double fontSz;                    // Taille pour autofontsize, frac Max-Min
+  vector<double> xMajTicks;
+  vector<double> xMinTicks;
+  vector<double> yMajTicks;
+  vector<double> yMinTicks;
+  double xMajTickLen,  xMinTickLen;
+  double yMajTickLen,  yMinTickLen;
+  bool axesCenter; double axesCentX0,axesCentY0;
+
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/piaxestools.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piaxestools.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piaxestools.cc	(revision 3445)
@@ -0,0 +1,384 @@
+// 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>
+
+#include "sopnamsp.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() & kCentAxes) 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 |= kCentAxes;  flags &= ~kBoxAxes; }
+  else { flags &= ~kCentAxes;  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_Nov2007/SophyaPI/PI/piaxestools.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piaxestools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piaxestools.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pibargraph.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibargraph.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibargraph.cc	(revision 3445)
@@ -0,0 +1,235 @@
+// Module PI : Peida Interactive  PIBarGraph
+// Drawer Y=f(X)      R. Ansari  2004
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <iostream>
+#include "pibargraph.h"
+
+// --------------------------------------------------------------------------
+// ----------------------------------------------------------
+//  Classe de representation d'une serie de valeurs sous 
+//  forme de bar-graph  
+// ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+//++
+// Class	PIBarGraph
+// Lib		PI
+// include	pibargraph.h
+//
+//	Classe de representation d'une serie de valeur sous forme de bar-graph
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur
+// PIBarGraph::PIBarGraph()
+//--
+
+
+/* --Methode-- */
+PIBarGraph::PIBarGraph(bool horiz, bool fill)
+    : PIDrawer()
+{
+  idMin = 0.; idMax = 1.;
+  mMin = 0.; mMax = 1.;
+  //DEL  aColIdx = 0;
+  fgFill = fill;
+  fgHoriz = horiz;
+  fgValLabel = false;
+  packFrac = 0.5;
+  GetGraphicAtt().SetColAtt(PI_Black, PI_White);
+  GetGraphicAtt().SetFontAtt(PI_DefaultFont, PI_NormalSizeFont, PI_RomanFont);
+  GetGraphicAtt().SetLineAtt(PI_NormalLine);
+  SetName("BarGraph");
+} 
+
+/* --Methode-- */
+PIBarGraph::~PIBarGraph()
+{
+}
+
+/* --Methode-- */
+int PIBarGraph::AddBar(double id_, double val_, string const& lab_, PIColors col_)
+{
+  struct _bgdata bgd;
+  bgd.id = id_;
+  bgd.val = val_;
+  bgd.lab = lab_;
+  bgd.col = col_;
+  if (mBars.size() == 0) { mMin = mMax = val_; idMin = idMax = id_; }
+  else {
+    if (val_ < mMin)  mMin = val_;
+    if (val_ > mMax)  mMax = val_;
+    if (id_ < idMin)  idMin = id_;
+    if (id_ > idMax)  idMax = id_;
+  }
+  mBars.push_back(bgd);
+  return mBars.size();
+}
+
+/* --Methode-- */
+int PIBarGraph::AddBar(double val)
+{
+  string lab = "";
+  double id = mBars.size()+0.5;
+  return  AddBar(id, val, lab, PI_NotDefColor);
+}
+
+
+static inline void swap_ifhoriz(double& a, double& b) 
+{
+  double tmp = a;
+  a = b;  b = tmp;
+}
+
+/* --Methode-- */
+void PIBarGraph::UpdateLimits()
+{
+  if (mBars.size() < 1)  return;
+  double xmin, xmax, ymin, ymax;
+  xmin = idMin-packFrac*(idMax-idMin)/mBars.size(); 
+  xmax = idMax+packFrac*(idMax-idMin)/mBars.size();
+  if (mMin*mMax >= 0.) {
+    ymin = 0.; ymax = mMax*1.1;
+  }
+  else {
+    ymin = mMin*1.1;  ymax = mMax*1.1;
+  }
+  if (fgHoriz) {
+    swap_ifhoriz(xmin, ymin);
+    swap_ifhoriz(xmax, ymax);
+  }
+  PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+  PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+  SetLimits(xmin,xmax,ymin,ymax);
+  //  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);  Ne pas faire - Reza 05/04->11/99
+}
+
+static inline void swap_ifhoriz_g(PIGrCoord& a, PIGrCoord& b) 
+{
+  PIGrCoord tmp = a;
+  a = b;  b = tmp;
+}
+
+/* --Methode-- */
+void PIBarGraph::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  if (mBars.size() < 1) return;
+  PIGrCoord x,y,dx,dy;
+  double larg = packFrac*(idMax-idMin)/mBars.size();
+  for(unsigned int k=0; k<mBars.size(); k++) {
+    PIColors dcol = g->GetForeground();
+    x = mBars[k].id-0.5*larg; dx = larg;
+    y = 0.; dy = mBars[k].val;
+    if (mBars[k].col != PI_NotDefColor) g->SelForeground(mBars[k].col);
+    if (fgHoriz) {
+      swap_ifhoriz_g(x, y);
+      swap_ifhoriz_g(dx, dy);
+    }  
+    if (fgFill) g->DrawFBox(x,y,dx,dy);
+    else  g->DrawBox(x,y,dx,dy);
+    if ((mBars[k].lab.length() == 0 ) && !fgValLabel ) continue;
+    string lab = mBars[k].lab;
+    if (fgValLabel) {
+      char buff[32];
+      sprintf(buff, " %g ", mBars[k].val);
+      lab = buff;
+    }
+    x = mBars[k].id;
+    y = mBars[k].val;
+    double fy = y;
+    bool fgneg = false;
+    bool fgin = false;
+    if (fy > 0.) {
+      if (fy > mMax/2.)  { fgin = true;  fy *= 0.95; }
+      else fy *= 1.05;
+    }
+    else {
+      fgneg = true;
+      if (fy < mMin/2.)  { fgin = true;  fy *= 0.95; }
+      else fy *= 1.05;
+    }
+    y  = fy;
+    unsigned long pflg = PI_VerticalCenter|PI_HorizontalLeft;
+    if ( (fgin && !fgneg) || (!fgin && fgneg) ) pflg = PI_VerticalCenter|PI_HorizontalRight;
+    if (fgHoriz)  pflg |= PI_TextDirectionHorizontal;
+    else pflg |= PI_TextDirectionVerticalUp;
+    if (fgHoriz)  swap_ifhoriz_g(x, y);
+     if (fgin) g->DrawOpaqueString(x, y, lab.c_str(), pflg);
+    else g->DrawString(x, y, lab.c_str(), pflg);
+
+    if (mBars[k].col != PI_NotDefColor) g->SelForeground(dcol);
+  }
+}
+
+
+/* --Methode-- */
+int PIBarGraph::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=="horizontalbars") SetHorizontalBars(); 
+    else if (opts=="verticalbars") SetVerticalBars();
+    else if (opts=="fill")  SetFill(true);
+    else if (opts=="nofill")  SetFill(false);
+    else if (opts.substr(0,9)=="packfrac=") {
+      double frac = atof(opts.substr(9).c_str()); 
+      SetPacking(frac);
+    }
+    else if (opts=="barvaluelabel")  UseBarValueAsLabel(true);
+    else if (opts=="nobarvaluelabel")  UseBarValueAsLabel(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);  
+}
+
+/* --Methode-- */
+int PIBarGraph::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+ if (fgHoriz) opt.push_back("horizontalbars"); else opt.push_back("verticalbars");
+ if (fgFill) opt.push_back("fill");  else opt.push_back("nofill");
+ if (fgValLabel) opt.push_back("barvaluelabel");  else opt.push_back("nobarvaluelabel");
+ char buff[64];
+ sprintf(buff,"packfrac=%g", packFrac);
+ opt.push_back(buff);
+ return 1;
+}
+
+/* --Methode-- */
+void PIBarGraph::GetOptionsHelpInfo(string& info)
+{
+info += " ---- PIBarGraph options help info : \n" ;
+info += "  fill/nofill: set bar fill option \n";
+info += "  horizontalbars/verticalbars: set bar orientation \n";
+info += "  packfrac=value : set bar packing fraction (0..1) \n";
+info += "  barvaluelabel/nobarvaluelabel: Use/Don't use bar value as labels \n";
+info += " --- + Usual colr/line/font  attribute decoding ... \n";
+PIDrawer::GetOptionsHelpInfo(info);
+return;
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pibargraph.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibargraph.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibargraph.h	(revision 3445)
@@ -0,0 +1,59 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PIBarGraph
+// BarGraph drawer pairs(X_i,Y_i) -    R. Ansari  2004
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIBARGRAPH
+#define PIBARGRAPH
+
+#include "pisysdep.h"
+#include "pidrawer.h"
+#include <vector>
+
+// ----------------------------------------------------------
+// Classe de representation d'une serie de valeurs sous 
+// forme de bar-graph 
+ 
+class PIBarGraph : public PIDrawer {
+public:
+                     PIBarGraph(bool horiz=false, bool fill=true);
+  virtual            ~PIBarGraph();
+
+  int                AddBar(double id, double val, string const& lab, PIColors col);
+  int                AddBar(double val);
+
+  // --- Methodes inline pour changer les options de representation  
+  // Barres horizontales ou vertiacales (defaut=vertical)
+  inline  void       SetVerticalBars() { fgHoriz=false; }
+  inline  void       SetHorizontalBars() { fgHoriz=true; }  
+  // Barres pleines ou contour
+  inline  void       SetFill(bool fg) { fgFill=fg; } 
+  // Fraction de remplissage des bars
+  inline  void       SetPacking(double frac=0.5) { packFrac=frac; }
+  // Use Bar values as labels
+  inline  void	     UseBarValueAsLabel(bool fg=true) { fgValLabel = fg; }
+
+  // ------------------------------
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+
+  // Methode de decodage des options   
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);  
+  virtual int        OptionToString(vector<string> & opt) const;
+  virtual void	     GetOptionsHelpInfo(string& info);
+
+ // Renvoie une distance au point x,y
+ // virtual double     GetDistanceToPoint(double x, double y);
+
+protected:
+  struct _bgdata { double id,val; string lab; PIColors col; };
+  vector<struct _bgdata> mBars;
+  double mMin, mMax;
+  double idMin, idMax;
+  bool fgFill, fgHoriz;
+  bool fgValLabel;   // Use values as labels
+  double packFrac;
+ };
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/pibwdggen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibwdggen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibwdggen.cc	(revision 3445)
@@ -0,0 +1,801 @@
+// 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 "sopnamsp.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;
+if (PIDrwTools::GetCurrentBaseWdg() == this) 
+  PIDrwTools::SetCurrentBaseWdg(NULL);
+DeleteDrawers();
+}
+ 
+
+/* --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 elastic=true)
+//	Définition du rectangle d'attachement par défaut. "(x1,y1)" et "(x2,y2)" determinent
+//	les positions des deux coins opposés.
+//	si "elastic=true", les coordonnées sont supposées être des facteurs multiplicatifs 
+//	des dimensions de l'objet.
+// void  GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+//	Retourne le rectangle d'attachement par défaut. "(x1,y1)" et "(x2,y2)" determinent
+//	les positions des deux coins opposés."elastic=true": Pos/Taille spécifiées en fraction 
+//	de la taille du PIBaseWdg.
+// 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 elastic)
+{
+mDrX1 = x1;  mDrY1 = y1;
+mDrX2 = x2;  mDrY2 = y2;   mDrElastic = elastic;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+{
+x1 = mDrX1;  y1 = mDrY1;
+x2 = mDrX2;  y2 = mDrY2;   elastic = mDrElastic;
+}
+
+/* --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, bool lock=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.
+//	si "lock=true", le drawer ne peut être détaché suite à une requête interactive.
+//	La méthode retourne l'identificateur du drawer attaché.
+// int  AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false, bool lock=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.
+//	si "lock=true", le drawer ne peut être détaché suite à une requête interactive.
+//	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, bool lock)
+{
+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.lock = lock;
+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, bool lock)
+{
+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.lock = lock; 
+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 elastic=true)
+//	Modification du rectangle d'attachement du PIDrawer avec l'identificateur "id" , retourné
+//	par "AddDrawer()". Si "elatic=true", taille/pos spécifiée en fraction de la taille du PIBaseWdg.
+// void  RemoveDrawer(int id)
+//	Ote le drawer "id" de la liste des drawers du PIBaseWdg.
+// 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 elastic)
+{
+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 = elastic;
+    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;
+mActDrwId = -1;
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).ad)  delete (*it).drw;
+mDrwList.erase(mDrwList.begin(), mDrwList.end() );
+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
+// int  GetDrawerIdFromNum(int n)
+//	Retourne l'identificateur du drawer numero "n=0..NbDrawers()-1". 
+// bool IsDrawerLockedId(int id)
+//	Retourne le flag "lock" pour le PIDrawer avec l'identificateur "id".
+//	si "true", le drawer ne doit être détaché suite à une requête interactive.
+// bool IsDrawerAutoSizePos(int id)
+//	Retourne "true" si le  PIDrawer (Identificateur= "id") est positionné
+//	dans le rectangle par défaut.
+// void GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+//	Retourne le rectangle d'attachement du PIDrawer avec l'identificateur "id".
+//	"elastic=true": position et taille spécifiées en fraction de la taille du PIBaseWdg.
+//--
+
+/* --Methode-- */
+int PIBaseWdgGen::GetDrawerIdFromNum(int n)
+{
+if ( (n < 0) || (n >= mDrwList.size()) ) return(-1);
+return(mDrwList[n].id);
+}
+
+
+/* --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);
+}
+
+/* --Methode-- */
+bool PIBaseWdgGen::IsDrawerLockedId(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id)  return((*it).lock);
+return true;
+}
+
+/* --Methode-- */
+bool PIBaseWdgGen::IsDrawerAutoSizePos(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id)  return( (*it).autoszp );
+return false;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, 
+				     PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+{
+x1 = y1 = x2 = y2 = 0;
+elastic = false;
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id) { 
+    x1 = (*it).x1;  y1 = (*it).y1;
+    x2 = (*it).x2;  y2 = (*it).y2;
+    elastic = (*it).elastic;
+    break;
+  }
+return;
+}
+
+//++
+// 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).
+// int   FindNearestDrawerId(int x, int y)
+//	Retourne le numéro du traceur le plus proche au point "(x,y)" de l'objet PIBaseWdg. 
+//	-1 si pas de traceur.
+//--
+
+/* --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));
+}
+
+/* --Methode-- */
+int PIBaseWdgGen::FindNearestDrawerId(int xp, int yp)
+{
+  if (mDrwList.size() < 1)  return -1;
+  double xmin,ymin, xmax, ymax;
+  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;  
+  }
+  
+  int nid = -1;
+  double neardist = 9.e39;
+  bool fgido = false;
+  
+  vector<BWDrwId>::iterator it;
+  for(it = mDrwList.begin(); it != mDrwList.end(); it++) {
+    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);
+    }
+    double xu, yu;
+    (*it).drw->WdgCoord2DrwCoord(xp, yp, xu, yu, drx0, dry0, drdx, drdy);
+    double curd = (*it).drw->GetDistanceToPoint(xu, yu);
+    if (!fgido || (curd < neardist)) {
+      neardist = curd;  nid = (*it).id;  fgido = true;
+    }
+  }
+return nid;  
+}
+
+//++
+// 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();
+g->SaveGraphicAtt();
+
+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;
+  }
+g->RestoreGraphicAtt();
+return;
+}
+
+
+/* --Methode-- */
+PIGraphic* PIBaseWdgGen::WindowGraphic()
+{
+return(mWGrC);
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pibwdggen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibwdggen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibwdggen.h	(revision 3445)
@@ -0,0 +1,160 @@
+// 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 };
+
+// Forward declaration for PIDrawer
+class PIDrawer; 
+
+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       GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, 
+                                             PIGrCoord& x2, PIGrCoord& y2, bool& psz);
+  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, bool lock=false);
+  virtual int        AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, 
+			       bool ad=false, bool lock=false);
+  virtual void       MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, 
+                                      PIGrCoord x2, PIGrCoord y2, bool elastic=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 
+  inline  int        NbDrawers() { return mDrwList.size(); } 
+          int        GetDrawerIdFromNum(int n); 
+          PIDrawer*  GetDrawerId(int id);   
+          PIDrawer*  GetDrawer(int n); 
+          bool       IsDrawerLockedId(int id);
+          bool       IsDrawerAutoSizePos(int id);
+          void       GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, 
+				       PIGrCoord& x2, PIGrCoord& y2, bool& elastic);
+
+// Quel est le drawer actif
+          void       SetActiveDrawerId(int id);   
+          void       SetActiveDrawer(int n);   
+          int        GetActiveDrawerId();   
+          int        GetActiveDrawerNum();   
+          PIDrawer*  GetActiveDrawer();   
+
+// Recherche du plus proche Drawer
+  virtual int        FindNearestDrawerId(int x, int y);
+
+//  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);
+
+  virtual PIGraphic*  WindowGraphic();
+
+// -------------- Variables membres protegees -------------------
+protected:
+// ..... Structure de la liste de gestion des drawers .....
+  struct BWDrwId { 
+    int id;          // Drawer Identifier
+    PIGrCoord x1, y1, x2, y2;  // Drawer Position(/Size) in Widget
+    // autoszp/autolim=true, Size/Limits imposed by widget - 
+    // elastic=true: Pos/Size = fraction of wdget size
+    bool autoszp, autolim, elastic; 
+    bool clip, ad;  // clip=true : No graphic draw outside Drawer rectangle
+    // ad=true: Delete Drawer when delete of PIBaseWdg
+    bool lock;  // lock=true: cannot be detached/deleted
+    PIDrawer* drw;   // Pointer to drawer itself
+  };
+// ...........................................................
+
+  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_Nov2007/SophyaPI/PI/pibwdgx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibwdgx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibwdgx.cc	(revision 3445)
@@ -0,0 +1,254 @@
+// 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 "sopnamsp.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) , bwx_finishDone(false)
+
+{
+Arg  wargs[3];
+
+Init();
+mWGrC = NULL; // PIGraphic (Contexte graphique) associe a la fenetre
+
+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();
+// ----------------------------------------------------------------------------
+// Reza: Fev/Mai 2005 - On doit s'assurer que le bon FinishCreate() est appele
+// (table de fonction virtuelle mise a jour par les constructeurs successifs 
+// dans les classes heritieres
+// et on gere le PIGraphic (Contexte graphique) associe a la fenetre
+// Si pas cree par FinishCreate()
+if (finishDone) FinishCreate();
+else 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()
+// Doit pouvoir etre appele de multiple fois 
+if (bwx_finishDone) 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();
+bwx_finishDone = true;
+} 
+
+/* --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_Nov2007/SophyaPI/PI/pibwdgx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pibwdgx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pibwdgx.h	(revision 3445)
@@ -0,0 +1,61 @@
+// 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;
+// pour s'assurer que le bon FinishCreate() est appele - pb lie aux tables de fonctions
+// virtuelles des classes qui sont remplies au fur et a mesure des constructeurs
+  bool               bwx_finishDone; 
+};
+
+typedef PIBaseWdgX PIBaseWdg;
+
+#endif /* PIBWDGX_H_SEEN */
Index: /tags/V_Nov2007/SophyaPI/PI/picmap.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmap.cc	(revision 3445)
@@ -0,0 +1,1920 @@
+// Module PI : Peida Interactive     PIColorMap
+// Gestion de table de couleurs        96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "picmap.h"
+#include <iostream>
+
+//++
+// 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   30
+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, 256, 256, 256, 256, 256, 256, 256, 256  };
+
+// Tables de couleurs :
+// 5 Standard PI , 32  couleurs
+// 4 Standard PI , 128 couleurs
+// 7 Standard PI , 32 couleurs uniformes
+// 12 MIDAS , 256 couleurs
+// 1 Standard PI 64 couleurs differentes
+// 1 Standard PI 16 couleurs
+
+static   const char*  MapNoms[MXMAPIDS]  = {
+                      "Grey32","InvGrey32","ColRJ32","ColBR32","ColRV32", 
+                      "Grey128","InvGrey128","ColRJ128","ColBR128",
+		      "Red32CM","Green32CM","Blue32CM","Yellow32CM",
+ 		      "Orange32CM","Cyan32CM","Violet32CM",
+		      "MIDAS_Pastel","MIDAS_Heat","MIDAS_Rainbow3", 
+                      "MIDAS_BlueRed","MIDAS_BlueWhite","MIDAS_Stairs8",
+                      "MIDAS_Stairs9","MIDAS_StairCase","MIDAS_Color",
+                      "MIDAS_ManyCol","MIDAS_Idl14","MIDAS_Idl15",
+                      "MultiCol16","MultiCol64"};
+
+static   CMapId MapIds[MXMAPIDS] = { 
+                      CMAP_GREY32, CMAP_GREYINV32, CMAP_COLRJ32, CMAP_COLBR32, CMAP_COLRV32, 
+                      CMAP_GREY128, CMAP_GREYINV128, CMAP_COLRJ128, CMAP_COLBR128,  
+		      CMAP_RED32, CMAP_GREEN32, CMAP_BLUE32, CMAP_YELLOW32,
+		      CMAP_ORANGE32, CMAP_CYAN32, CMAP_VIOLET32, 
+                      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, CMAP_COL64 } ;
+
+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, 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_RED32      :  32 couleurs, nuances de rouge
+//|	CMAP_GREEN32    :  32 couleurs, nuances de vert
+//|	CMAP_BLUE32     :  32 couleurs, nuances de bleu
+//|	CMAP_YELLOW32   :  32 couleurs, nuances de jaune
+//|	CMAP_ORANGE32   :  32 couleurs, nuances d'orange
+//|	CMAP_CYAN32     :  32 couleurs, nuances de cyan
+//|	CMAP_VIOLET32   :  32 couleurs, nuances de violet
+//|	CMAP_COL16      :  16 Couleurs arcenciel
+//|	CMAP_COL64      :  64 Couleurs arcenciel 
+//|	CMAP_OTHER      :  Table non standard 
+//	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,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;
+
+    // Nuances de couleurs uniformes
+    case CMAP_RED32 :
+    case CMAP_GREEN32 :
+    case CMAP_BLUE32 :
+    case CMAP_YELLOW32 :
+    case CMAP_ORANGE32 :
+    case CMAP_CYAN32 :
+    case CMAP_VIOLET32 :
+      for(i=0; i<6; i++) {
+	int vcol = i*4000;
+	mycol.red = mycol.green = mycol.blue = 0;
+	if (mType == CMAP_RED32) mycol.red = vcol;
+	else if (mType == CMAP_GREEN32)  mycol.green = vcol;
+	else if (mType == CMAP_BLUE32)  mycol.blue = vcol;
+	else if (mType == CMAP_YELLOW32) mycol.green = mycol.red = vcol;
+	else if (mType == CMAP_ORANGE32) { mycol.red = vcol; mycol.green = vcol*0.65; }
+	else if (mType == CMAP_CYAN32) mycol.green = mycol.blue = vcol; 
+	else if (mType == CMAP_VIOLET32) 
+	  { mycol.red = 0.6*vcol; mycol.green = 0.2*vcol; mycol.blue = vcol; }
+        for(k=0; k<8; k++)     AllocColor(mycol, i*8+k);
+      }
+      for(i=6; i<16; i++) {
+	int vcol = 20000+(i-5)*2500;
+	mycol.red = mycol.green = mycol.blue = 0;
+	if (mType == CMAP_RED32) mycol.red = vcol;
+	else if (mType == CMAP_GREEN32)  mycol.green = vcol;
+	else if (mType == CMAP_BLUE32)  mycol.blue = vcol;
+	else if (mType == CMAP_YELLOW32) mycol.green = mycol.red = vcol;
+	else if (mType == CMAP_ORANGE32) { mycol.red = vcol; mycol.green = vcol*0.65; }
+	else if (mType == CMAP_CYAN32) mycol.green = mycol.blue = vcol; 
+	else if (mType == CMAP_VIOLET32) 
+	  { mycol.red = 0.6*vcol; mycol.green = 0.2*vcol; mycol.blue = vcol; }
+        for(k=0; k<8; k++)     AllocColor(mycol, i*8+k);
+      }
+      for(i=16; i<32; i++) {
+       	int vcol = 45000+(i-15)*1283.4;
+	mycol.red = mycol.green = mycol.blue = 0;
+	if (mType == CMAP_RED32) mycol.red = vcol;
+	else if (mType == CMAP_GREEN32)  mycol.green = vcol;
+	else if (mType == CMAP_BLUE32)  mycol.blue = vcol;
+	else if (mType == CMAP_YELLOW32) mycol.green = mycol.red = vcol;
+	else if (mType == CMAP_ORANGE32) { mycol.red = vcol; mycol.green = vcol*0.65; }
+	else if (mType == CMAP_CYAN32) mycol.green = mycol.blue = vcol; 
+	else if (mType == CMAP_VIOLET32) 
+	  { mycol.red = 0.6*vcol; mycol.green = 0.2*vcol; mycol.blue = vcol; }
+        for(k=0; k<8; k++)     AllocColor(mycol, i*8+k);
+      }
+      break;
+
+    case CMAP_COL64 : 
+      {
+	float fci_1[5] = { 0.60, 0.70, 0.80, 0.90, 1.0};
+	float fci_21[8] = { 1.0, 1.0, 1.0, 1.0, 0.8, 0.6, 0.4 };
+	float fci_22[8] = { 0.4, 0.6, 0.8, 1.0, 1.0, 1.0, 1.0 };
+	float fci_3[3] = { 0.4, 0.80, 1.0 };
+	i = 0;
+	int i1,i2,i3,ici;
+	// D'abord le noir (+1 comb)
+	mycol.red = mycol.green = mycol.blue = 0;
+	for(ici=0; ici<4; ici++) { 
+	  AllocColor(mycol, i); i++;
+	}
+	// les rouges (+5 comb)
+	mycol.green =  mycol.blue = 0;
+	for(i1=0; i1<5; i1++) {  
+	  mycol.red = fci_1[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite, rouge+vert (+7 comb)
+	mycol.blue = 0;
+	for(i1=0; i1<7; i1++) {
+	  mycol.red = fci_21[i1]*65530.;  
+	  mycol.green = fci_22[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite les verts (+5 comb)
+	mycol.red =  mycol.blue = 0;
+	for(i1=0; i1<5; i1++) {  
+	  mycol.green = fci_1[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite les verts+bleu (+7 comb)
+	mycol.red = 0;
+	for(i1=0; i1<7; i1++) {
+	  mycol.green = fci_21[i1]*65530.;  
+	  mycol.blue = fci_22[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite les bleus (+5 comb)
+	mycol.red =  mycol.green = 0;
+	for(i1=0; i1<5; i1++) {  
+	  mycol.blue = fci_1[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite les bleu+rouge (+7 comb)
+	mycol.green = 0;
+	for(i1=0; i1<7; i1++) {
+	  mycol.blue = fci_21[i1]*65530.;  
+	  mycol.red = fci_22[i1]*65530.;  
+	  for(ici=0; ici<4; ici++) { 
+	    AllocColor(mycol, i); i++;
+	  }
+	}
+	// Ensuite les bleu+rouge+vert (+27 comb)
+	for(i1=0; i1<3; i1++)   
+	  for(i2=0; i2<3; i2++)   
+	    for(i3=0; i3<3; i3++) {
+	      mycol.red = fci_3[i1]*65530.;  
+	      mycol.green = fci_3[i2]*65530.;  
+	      mycol.blue = fci_3[i3]*65530.;  
+	      for(ici=0; ici<4; ici++) { 
+		AllocColor(mycol, i); i++;
+	      }
+	    }   
+	//	cout << "PICMAP-Rainbow256 - NbColors allocated= " << i << endl;
+      }
+      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_Nov2007/SophyaPI/PI/picmap.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmap.h	(revision 3445)
@@ -0,0 +1,75 @@
+// 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
+
+ // Nuances de couleurs uniformes
+ CMAP_RED32       = 11,    // 32 couleurs - nuances de rouge
+ CMAP_GREEN32     = 12,    // 32 couleurs - nuances de vert
+ CMAP_BLUE32      = 13,    // 32 couleurs - nuances de bleu
+ CMAP_YELLOW32    = 14,    // 32 couleurs - nuances de jaune
+ CMAP_ORANGE32    = 15,    // 32 couleurs - nuances d' orange
+ CMAP_CYAN32      = 16,    // 32 couleurs - nuances de cyan
+ CMAP_VIOLET32    = 17,    // 32 couleurs - nuances de violet
+
+ // 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/64 couleurs 
+ CMAP_COL16       = 998,        // 16 Couleurs arcenciel
+ CMAP_COL64       = 999         // 64 Couleurs differentes
+ };
+
+
+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_Nov2007/SophyaPI/PI/picmapgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapgen.cc	(revision 3445)
@@ -0,0 +1,38 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/picmapgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/picmapview.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapview.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapview.cc	(revision 3445)
@@ -0,0 +1,183 @@
+// Module PI : Peida Interactive     PICMapView
+// Visualisation de table de couleur     R. Ansari  07/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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, const 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, const 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) || 
+       (cmap->Type() == CMAP_GREEN32) )  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_Nov2007/SophyaPI/PI/picmapview.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapview.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapview.h	(revision 3445)
@@ -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 = 5210};
+
+                  PICMapView(PIContainerGen *par, const 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_Nov2007/SophyaPI/PI/picmapx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapx.cc	(revision 3445)
@@ -0,0 +1,194 @@
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/picmapx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picmapx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picmapx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/picolist.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picolist.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picolist.h	(revision 3445)
@@ -0,0 +1,25 @@
+// 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_SkyBlue = 20, PI_RoyalBlue = 21,
+		 PI_ForestGreen = 22, 
+		 PI_OrangeRed = 23, PI_Brown = 24,
+		 PI_HighlightBlue = 25,
+                 PI_ColorAllBits0 = 30, PI_ColorAllBits1 = 31 };
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/picons.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picons.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picons.cc	(revision 3445)
@@ -0,0 +1,1019 @@
+#include "sopnamsp.h"
+#include "pisysdep.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.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 et envoi du message PIMsg_Cancel
+//	* Curseur gauche, droite : deplacement curseur
+//	* Cursur Haut,bas : rappel de commande
+//	* Backspace, del : effacement de caracteres
+//	* <Return> : Validation (Envoi du message PIMsg_OK)
+//--
+//++
+// 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;
+      Send( Msg(), PIMsg_Cancel, NULL);
+
+      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';      
+	int mxCC = mWSzC-strlen(mPrompt)-2;
+	if (mCCP >= mxCC) mCCP = mxCC; // On se met le plus loin possible sur la ligne        
+      }
+      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++; }
+    else mCPBuffer[k] =  '\0';
+    }
+  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_Nov2007/SophyaPI/PI/picons.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picons.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picons.h	(revision 3445)
@@ -0,0 +1,124 @@
+// 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:
+  enum {ClassId = 6100};
+
+                     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();
+
+  virtual long       kind() {return ClassId; }
+
+// 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_Nov2007/SophyaPI/PI/picontainergen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picontainergen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picontainergen.cc	(revision 3445)
@@ -0,0 +1,295 @@
+//  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 "sopnamsp.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".
+//	Peut controler la destruction des widgets fils (voir "SetAutoDelChilds()").
+//      Le conteneur créé n'est pas visible (actif) par défaut. Il faut 
+//	appeler "Show()".
+// 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.
+// bool Visible()
+//	Retourne "true" si l'objet est visible. 
+// 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()
+{
+Manage();
+stvis = true;
+if (finishDone) FinishCreate();
+}
+
+/* --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();    
+if (!stvis) return;
+for(int 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_Nov2007/SophyaPI/PI/picontainergen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picontainergen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picontainergen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/picontainerx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picontainerx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picontainerx.cc	(revision 3445)
@@ -0,0 +1,96 @@
+#include "sopnamsp.h"
+#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;
+// *************** Reza - Fev 2005 ***************
+// Probleme lie a la table des fonctions virtuelles qui ne contient
+// la bonne fonction que lorsque le bon constructeur a fini de s'executer  
+// Ici, le probleme est celui de la fonction FinishCreate()
+// Pour gerer le probleme de l'appel a FinishCreate() 
+// lorsque celui du parent est deja appele
+//--- les container sont cree dans l'etat inactif/invisible - FinishCreate() est 
+// donc desormais appele par PIContainerGen::Show() --- Mai 2005 ----
+//--- plus appele ici  if (finishDone)  FinishCreate(); ----
+}
+
+// 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;
+// *************** Reza - Fev 2005 ***************
+// Probleme lie a la table des fonctions virtuelles - voir ci-dessus
+//--- les container sont cree dans l'etat inactif/invisible - FinishCreate() est 
+// donc desormais appele par PIContainerGen::Show() --- Mai 2005 ----
+//--- plus appele ici  if (finishDone)  FinishCreate(); ----
+}
+
+/* --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_Nov2007/SophyaPI/PI/picontainerx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/picontainerx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/picontainerx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pidrawer.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrawer.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrawer.cc	(revision 3445)
@@ -0,0 +1,558 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <strings.h>
+#include <iostream>
+#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
+
+  lastHLStatus = 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();
+  // On supprime la fenetre PIDrwOptionStringWindow le cas echeant
+  PIDrwOptionStringWindow::RemoveDrwOptionStringWindow(this);
+}
+
+//++
+// 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(bool refwdg=false)
+//	"refwdg==false": Rafraîchit le dessin du PIDrawer sur tous les PIBaseWdg auxquel il est attaché.
+//	"refwdg==true": Appelle *Refresh()* 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(bool refwdg)
+{
+  list<DrwBWId>::iterator it;
+  if (refwdg) {
+    for(it = mBWdgList.begin(); it != mBWdgList.end(); it++)
+      (*it).wdg->Refresh();
+  }
+  else {
+    for(it = mBWdgList.begin(); it != mBWdgList.end(); it++)
+      (*it).wdg->CallDrawer((*it).id);
+  }
+
+}
+void
+PIDrawer::HighLight(bool fgh)
+{
+  if (lastHLStatus == fgh)  return; 
+  lastHLStatus = 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()*
+// int  OptionToString(vector<string> & opt) const
+//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
+//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
+//	Renvoie le nombre d'éléments ajoutés.
+//	L'implémentation par défaut effectue le décodage des attributs graphiques en 
+//	utilisant la méthode *PIGraphicAtt::AttToStrings()*
+// 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);
+}
+
+int
+PIDrawer::OptionToString(vector<string> & opt) const
+{
+  return mGrAtt.AttToStrings(opt);
+}
+
+void
+PIDrawer::GetOptionsHelpInfo(string& info)
+{
+  info += " ------- PIDrawer options help info ---------- \n";
+  info += ">>> color=ColorName - fgcolor=ColorName - bgcolor=ColorName \n";
+  info += "   ColorName: black white grey red blue green yellow \n";
+  info += "              magenta cyan turquoise navyblue orange \n";
+  info += "              siennared purple  limegreen gold violet \n";
+  info += "              violetred blueviolet darkviolet skyblue \n";
+  info += "              royalblue forestgreen orangered brown \n";
+  info += ">>> line=DashType,LineWidth  \n";
+  info += "   DashType: solid, dash, dotted, dashdotted   Width: 1,2,...\n";
+  info += ">>> font=FontName,FontAtt,FontSize  \n";
+  info += "   FontName: courier, helvetica, times, symbol   \n";
+  info += "   FontAtt: roman, bold, italic, bolditalic  \n";
+  info += "   FontSize: 6,8,10,12... (pts) - integer \n";
+  info += ">>> marker=MarkerType,MarkerSize (MarkerSize: integer 3,5,7... \n";
+  info += "   MarkerType: dot, plus, cross, circle, fcircle, box, fbox \n";
+  info += "               triangle, ftriangle, star, fstar \n";
+  info += ">>> arrow=ArrowType,ArrowSize (ArrowSize: integer 3,5,7... \n";
+  info += "   ArrowType: basic, triangle, ftriangle, \n";
+  info += "              arrowshaped, farrowshaped\n";
+  info += ">>> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32 \n";
+  info += "                grey128  invgrey128  colrj128  colbr128 \n";
+  info += "                red32cm  green32cm  blue32cm  yellow32cm \n";
+  info += "                orange32cm cyan32cm violet32cm \n";
+  info += "                midas_pastel midas_heat midas_rainbow3 midas_bluered\n";
+  info += "                midas_bluewhite midas_redwhite \n";
+  info += "                multicol16 multicol64\n";
+  info += ">   revcmap : This flag reverses ColorMap indexing \n";
+  info += "------- Obsolete- graphic att ---------- \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";
+  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 (!limitsFixed) UpdateLimits();
+  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
+    mGrUC->SelForeground(PI_HighlightBlue);
+    mGrUC->LockForegroundColor();
+    lastHLStatus = true;
+  }
+  else lastHLStatus = false;
+  
+  return(mGrUC);
+}
+
+void
+PIDrawer::WdgCoord2DrwCoord(int x, int y, double& xu, double& yu, 
+			    int x0, int y0, int dx, int dy)
+{
+  if (!limitsFixed) UpdateLimits();
+  PIGraphicUC guc(NULL, x0, y0, dx, dy);
+  guc.SetUCS(xMin, xMax, yMin, yMax, aXFlg, aYFlg);
+  if (aXlog || aYlog) guc.SetLogScale(aXlog, aYlog);
+  guc.GrC2UC(x,y,xu,yu);
+  return;
+}
+
+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, XMin(), XMax(), YMin(), YMax(),
+		  axesFlags, axesAFSz); 
+  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.
+// double  GetDistanceToPoint(double x, double y)
+//	Fournit une distance au point "x,y". Valeur entre 0 et 1 au bord xmin/max,ymin/max.  
+//	L'implémentation par défaut retourne la distance normalisée au point 
+//	((xmin+xmax)/2,(ymin+ymax)/2)
+//--
+
+
+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)
+{
+}
+
+double
+PIDrawer::GetDistanceToPoint(double x, double y)
+{
+  double xc = 0.5*(XMin()+XMax());
+  double yc = 0.5*(YMin()+YMax());
+  double delx = (x-xc)/(0.5*(XMax()-XMin()));
+  double dely = (y-yc)/(0.5*(YMax()-YMin()));  
+  return sqrt((delx*delx+dely*dely)/2.);
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pidrawer.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrawer.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrawer.h	(revision 3445)
@@ -0,0 +1,148 @@
+// 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); 
+// Renvoie une distance au point x,y 
+// 0: au(x) point(s) le(s) plus proche(s) ... 1  au bord xmin/xmax , ymin/ymax
+// La methode par defaut calcule la distance normalisee au point ((xmin+xmax)/2,(ymin+ymax)/2)
+  virtual double     GetDistanceToPoint(double x, double y);
+
+  virtual void       Refresh(bool refwdg=false);      // 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);
+//   Methode retournant un vecteur de string a partir des options 
+  virtual int        OptionToString(vector<string> & opt) const;
+
+//   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);
+//  Transformation coordonnees fenetre en coordonnees drawer
+  virtual  void      WdgCoord2DrwCoord(int x, int y, double& xu, double& yu, 
+				       int x0, int y0, int dx, int dy);
+
+//  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, dernier etat highlight ou non
+  bool mFgHighLight, lastHLStatus;
+// 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_Nov2007/SophyaPI/PI/pidrawwin.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrawwin.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrawwin.cc	(revision 3445)
@@ -0,0 +1,29 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pidrawwin.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrawwin.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrawwin.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pidrwtools.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrwtools.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrwtools.cc	(revision 3445)
@@ -0,0 +1,1504 @@
+// 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 "sopnamsp.h"
+#include "pidrwtools.h"
+#include <iostream>
+#include <list>
+#include <typeinfo>
+#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 = (3+6*0.85)*bsy+(8+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]->AppendItem("SkyBlue", 121);
+mOpt[0]->AppendItem("RoyalBlue", 122);
+mOpt[0]->AppendItem("ForestGreen", 123);
+mOpt[0]->AppendItem("OrangeRed", 124);
+mOpt[0]->AppendItem("Brown", 125);
+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(), "PIUniCol32");
+mCasc[2] = new PIMenu(mOpt[1]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3,nsct4;
+//  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]);
+nsct3 = 17;  // Les 7 tables de couleurs uniforme
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[1]);
+//  Apres les tables importees de MIDAS
+nsct4 = PIColorMap::NumberStandardColorMaps()-2; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct3; kcc<nsct4; kcc++) 
+  mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[2]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct4; 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 = bsx;
+int busp = (wszx-4*spx-3*butszx)/2;
+mButcf[0] = new PIButton(this, "GetAtt", 2500, butszx, bsy, cpx, cpy);
+cpx += butszx+busp;
+mButcf[1] = new PIButton(this, "SetAtt", 2600, butszx, bsy, cpx, cpy);
+cpx += butszx+busp;
+mButcf[2] = new PIButton(this, "Select", 2700, butszx, bsy, cpx, cpy);
+mButcf[2]->ActivatePress(true);
+
+butszx = 1.2*bsx;
+cpx = (wszx-2*butszx-4*spx)/2;
+cpy += bsy+spy;
+mButcf[4] = new PIButton(this, "OptionString", 2900, butszx, bsy, cpx, cpy);
+cpx += butszx+4*spx;
+mButcf[3] = new PIButton(this, "ShowControl", 2800, butszx, bsy, cpx, cpy);
+
+butszx = 1.6*bsx;
+cpx = (wszx-2*butszx-4*spx)/2;
+cpy += 2*spy+bsy;
+mButcf[5] = new PIButton(this, "Refresh", 3000, butszx, bsyo, cpx, cpy);
+cpx += butszx+4*spx;
+mButcf[6] = new PIButton(this, "Dismiss", 3777, butszx, bsyo, cpx, cpy);
+
+for(kb=0; kb<7; kb++) 
+  mButcf[kb]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+for(kb=0; kb<6; kb++) 
+  mButcf[kb]->SetUnSensitive();
+
+mButSens = 0;
+cwdrwt = this;
+
+}
+
+/* --Methode-- */
+PIDrwTools::~PIDrwTools()
+{
+if (cwdrwt == this)  cwdrwt = NULL;
+int i;
+for(i=0; i<7; 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<3; i++)  delete mCasc[i];
+delete mNlb;
+delete mDrName;
+}
+
+//  Declaration des differents attributs graphiques 
+#define MYNMXCOLORS 26
+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,
+		     PI_SkyBlue, PI_RoyalBlue,
+		     PI_ForestGreen,
+		     PI_OrangeRed, PI_Brown };
+
+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<5;kb++)  mButcf[kb]->SetUnSensitive();
+      if (butsensnew == 0) mButcf[5]->SetUnSensitive();
+      else mButcf[5]->SetSensitive();
+    }
+    else { 
+      for(kb=0; kb<2;kb++)  mButdr[kb]->SetSensitive();
+      for(kb=0; kb<3;kb++)  mButcf[kb]->SetSensitive();
+      mButcf[4]->SetSensitive();
+      mButcf[5]->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 2900 :
+      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) 
+        PIDrwOptionStringWindow::ShowDrwOptionStringWindow(mCurBW->GetDrawer(mNDr));
+      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;
+}
+
+
+//---------------------------------------------------------------
+//---------------- Classe PIDrwOptionStringWindow ---------------
+//---------------------------------------------------------------
+
+//++
+// Class	PIDrwOptionStringWindow
+// Lib		PI
+// include	pidrwtools.h
+//
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	Les attributs graphique des "Drawer" par l'appel à *DecodeOptionString()*.
+//--
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+// PIDrwTools
+//--
+
+//++
+// Titre	Méthodes statiques
+//--
+//++
+// void  ShowDrwOptionStringWindow(PIDrawer* drw)	
+//	Méthode statique permettant l'affichage de la fenêtre de changement des
+//	attributs graphiques à travers *PIDrawer::DecodeOptionString()*
+//	pour le drawer "drw".
+// void  RemoveDrwOptionStringWindow(
+//	Suppression de la fenêtre associé à "drw" (appelée par le destructeur
+//	des PIDrawer)
+//--
+
+static list<PIDrwOptionStringWindow* > drwoswlist;
+
+/* --Methode-- */
+void PIDrwOptionStringWindow::ShowDrwOptionStringWindow(PIDrawer* drw)
+{
+  if (drw == NULL) return;
+  list<PIDrwOptionStringWindow* >::iterator it;
+  for(it=drwoswlist.begin(); it!= drwoswlist.end(); it++) 
+    if ((*it)->GetDrawer() == drw) { 
+      (*it)->Show(); 
+      return; 
+    }
+  PIDrwOptionStringWindow* osw = 
+    new PIDrwOptionStringWindow(PIApplicationGetApp(), drw);
+  drwoswlist.push_back(osw);
+  osw->Show();
+}
+
+/* --Methode-- */
+void PIDrwOptionStringWindow::RemoveDrwOptionStringWindow(PIDrawer* drw)
+{
+  if (drw == NULL) return;
+  list<PIDrwOptionStringWindow* >::iterator it;
+  for(it=drwoswlist.begin(); it!= drwoswlist.end(); it++) 
+    if ((*it)->GetDrawer() == drw) { 
+      (*it)->Hide();
+      delete *it;
+      drwoswlist.erase(it); 
+      break;
+    }
+  return;
+}
+
+/* --Methode-- */
+PIDrwOptionStringWindow::PIDrwOptionStringWindow(PIApplication* par, PIDrawer* drw)
+  : PIWindow((PIMsgHandler *)par, "DrwOptionString", PIWK_normal, 400, 200, 100, 200) 
+  , mDrw(drw)
+{
+  int bsx, bsy;
+  int tsx, tsy;
+  int spx, spy;
+  PIApplicationPrefCompSize(bsx, bsy);
+  spx = bsx/8;   spy = bsy/6;
+  tsx = 7.5*bsx+2*spx;  tsy = 6*bsy+4*spy;
+  SetSize(tsx,tsy);
+  int cpx = spx;
+  int cpy = spy;
+  mTxt[0] = new PIText(this, "drwoshelp", true, true, bsx*7.5, 4*bsy, cpx, cpy);  
+  mTxt[0]->SetTextEditable(false);
+  mTxt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  mTxt[0]->SetText("");
+  cpy += 4*bsy+spy;
+  mTxt[1] = new PIText(this, "drwosset", bsx*7.5, bsy, cpx, cpy);  
+  mTxt[1]->SetTextEditable(true);
+  mTxt[1]->SetMsg(5555);
+  mTxt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  mTxt[1]->SetText("");
+  cpy += bsy+spy;
+  int lsx = tsx-4.8*bsx-6*spx;
+  mLab = new PILabel(this, "drwntyp", lsx, bsy, cpx, cpy);
+  mLab->SetBorderWidth(1);
+  mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  mLab->SetLabel("");
+  cpx += lsx+spx;
+  mBut[0] = new PIButton(this, "SetOption", 555, bsx*1.2, bsy, cpx, cpy);
+  mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpx += (1.2*bsx+spx);
+  mBut[1] = new PIButton(this, "GetOption", 666, bsx*1.2, bsy, cpx, cpy);
+  mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpx += (1.2*bsx+spx);
+  mBut[2] = new PIButton(this, "Refresh", 500, bsx*1.2, bsy, cpx, cpy);
+  mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpx += (1.2*bsx+spx);
+  mBut[3] = new PIButton(this, "Dimiss", 777, bsx*1.2, bsy, cpx, cpy);
+  mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+}
+
+/* --Methode-- */
+PIDrwOptionStringWindow::~PIDrwOptionStringWindow()
+{
+  delete mTxt[0];
+  delete mTxt[1];
+  delete mLab;
+  delete mBut[0];
+  delete mBut[1];
+  delete mBut[2];
+  delete mBut[3];
+}
+/* --Methode-- */
+void PIDrwOptionStringWindow::Show()
+{
+  if (mDrw) {
+    string hs;
+    mDrw->GetOptionsHelpInfo(hs);
+    mTxt[0]->SetText(hs);
+    mTxt[1]->SetText("");
+    hs = mDrw->Nom();
+    hs += " (T=";
+    hs += typeid(*mDrw).name();
+    hs += ")";
+    mLab->SetLabel(hs);
+  }
+  PIWindow::Show();
+}
+
+
+/* --Methode-- */
+void PIDrwOptionStringWindow::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+  PIMessage mod = ModMsg(msg);
+  msg = UserMsg(msg);
+  switch (msg) {
+  case 777:
+    Hide();
+    break;
+  case 555:
+  case 500:
+  case 5555:
+    if (mDrw) {
+      vector<string> vops;
+      string ops = mTxt[1]->GetText();
+      //cout << " DBG-A " << ops << endl; 
+      size_t len = ops.length();
+      if (len == 0) {
+	if (msg == 500)	mDrw->Refresh(true);
+	return;
+      }
+      size_t cp = ops.find_first_not_of(' ', 0);
+      if ((cp < 0) || (cp >= len) ) { 
+	if (msg == 500)	mDrw->Refresh(true);
+	return;
+      }
+      size_t tp = ops.find(' ', cp);
+      while ((tp > cp) && (tp < len)) {
+	vops.push_back(ops.substr(cp, tp-cp));
+	cp = tp+1; 
+	tp = ops.find(' ', cp);
+      }
+      if (cp < len) vops.push_back(ops.substr(cp));
+      //      cout << " DBG-B " << vops.size() << endl;
+      //for(int kk=0; kk< vops.size() ; kk++) 
+      //	cout << " DBG-C[" << kk << "] " << vops[kk] << endl; 
+      mDrw->DecodeOptionString(vops, false);
+      //      ops = "<< " + ops + " >> Decoded";
+      ops = "";
+      mTxt[1]->SetText(ops);
+      if (msg == 500)  mDrw->Refresh(true);
+      else mDrw->Refresh(false);
+    }
+    break;
+  case 666:
+    if (mDrw) {
+      vector<string> vops;
+      mDrw->OptionToString(vops);
+      string ops;
+      for(int kk=0; kk<vops.size(); kk++) {
+	ops += vops[kk]; ops += ' ';
+      }
+      mTxt[1]->SetText(ops);
+    }
+    break;
+  default :
+    break;
+      
+  }
+}
+
+//++
+// Class	PI
+// Lib		PIDrwMgrMenu
+// include	pidrwtools.h
+//
+//	Classe de menu (pop-up) permettant d'interagir avec les drawers
+//	attachés aux "PIBaseWdg".
+//--
+// Links	Parents
+// PIMenu
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+// PIBaseWdg
+//--
+
+//------------------------------------------------------------
+//------- Classe Event handler pour move/resize 
+class PIDrwPosSizeEvH : public PIEventHandler {
+public: 
+  PIDrwPosSizeEvH(PIBaseWdg* bwdg, bool fgxor=true);
+          void    CheckBeforeDelete();
+  virtual void    ProcessEvent(); 
+
+protected:
+  void ComputeResizeZone();
+  void ComputeMoveZone();
+  inline void ComputeDrawerZone() 
+    { x1 = _x1;  y1 = _y1; x2 = _x2-_x1;  y2 = _y2-_y1; }
+
+
+  PIBaseWdg* mBWdg;
+  bool _fgxor;
+  int _x1, _y1, _x2, _y2;
+  PIGrCoord x1, y1, x2, y2;
+  bool _elastic;
+  int _ipx, _ipy;
+  int _cpx, _cpy;
+  bool _defrect;  // true -> modification DefaultRectangle
+  bool _rsz; // true -> resize option
+  bool _okend;
+  bool _rmok;
+};
+
+/* --Methode-- */
+PIDrwPosSizeEvH::PIDrwPosSizeEvH(PIBaseWdg* bwdg, bool fgxor)
+{
+  mBWdg = bwdg;
+  _fgxor = fgxor;
+  _x1 = _y1 = _x2 = _y2 = -1;
+  _ipx = _ipy = -1;
+  _cpx = _cpy = -1;
+  _defrect = false;
+  _rsz = false;
+  _okend = false;
+  _rmok = false;
+  if (bwdg == NULL) return;
+  int aid = bwdg->GetActiveDrawerId();
+  if (aid < 0) return;
+  
+  _elastic = false;
+  if (mBWdg->IsDrawerAutoSizePos(aid)) {
+    mBWdg->GetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
+    _defrect = true; 
+  }
+  else { 
+    mBWdg->GetDrawerPosition(aid, x1, y1, x2, y2, _elastic);
+    _defrect = false; 
+  }
+    
+  if (_elastic) {
+    _x1 = (double)x1*(double)mBWdg->XSize();
+    _x2 = (double)x2*(double)mBWdg->XSize();
+    _y1 = (double)y1*(double)mBWdg->YSize();
+    _y2 = (double)y2*(double)mBWdg->YSize();
+  }
+  else {
+    _x1 = x1; _x2 = x2;
+    _y1 = y1; _y2 = y2;
+  }
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+  mBWdg->GetActiveDrawer()->HighLight(true);
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+  if (_fgxor) {
+    gr->SelForeground(PI_Magenta);
+    gr->SelGOMode(PI_GOXOR);
+  }
+  else {
+    gr->SelForeground(PI_HighlightBlue);
+    gr->SelGOMode(PI_GOCopy);
+  }
+  gr->SelLine(PI_ThinLine);
+  ComputeDrawerZone();
+  gr->DrawBox(x1,y1, x2, y2);
+  ComputeResizeZone();
+  gr->DrawFBox(x1,y1, x2, y2);
+  ComputeMoveZone();
+  gr->DrawBox(x1,y1, x2, y2);
+  gr->SelGOMode(gmod);
+  gr->SelLine(gline);
+  gr->SelForeground(gcol);
+
+//  cout << "DBG- Adding Event-Handler " << endl;
+  mBWdg->AddEventHandler(this, PIEvent_But1Press|PIEvent_Ptr1Move|PIEvent_But1Release);
+}
+/* --Methode-- */
+void PIDrwPosSizeEvH::CheckBeforeDelete()
+{
+  if (!_rmok) {
+    PIDrawer* adrw = mBWdg->GetActiveDrawer();
+    if (adrw) adrw->HighLight(true);
+    mBWdg->RemoveEventHandler(this);	
+  }
+  _rmok = true; 
+}
+
+/* --Methode-- */
+void PIDrwPosSizeEvH::ComputeResizeZone()
+{
+  int dx = (int)(0.05*(_x2-_x1));
+  int dy = (int)(0.05*(_y2-_y1));
+  int maxdx = (int)(0.20*(_x2-_x1));
+  int maxdy = (int)(0.20*(_y2-_y1));
+  if (dx < 20)  dx = 20;
+  if (dx > maxdx) dx = maxdx;
+  if (dy < 20)  dx = 20;
+  if (dy > maxdy) dy = maxdy;
+  int dxy = (dx < dy) ? dx : dy ;
+  x1 = _x2-dxy;  y1 = _y2-dxy;
+  x2 = y2 = dxy;
+}
+
+/* --Methode-- */
+void PIDrwPosSizeEvH::ComputeMoveZone()
+{
+  int dx = (int)(0.08*(_x2-_x1));
+  int dy = (int)(0.08*(_y2-_y1));
+  int maxdx = (int)(0.20*(_x2-_x1));
+  int maxdy = (int)(0.20*(_y2-_y1));
+  if (dx < 20)  dx = 20;
+  if (dx > maxdx) dx = maxdx;
+  if (dy < 20)  dx = 20;
+  if (dy > maxdy) dy = maxdy;
+  int dxy = (dx < dy) ? dx : dy ;
+  x1 = (_x1+_x2)*0.5-dxy;  
+  y1 = (_y1+_y2)*0.5-dxy;    
+  x2 = y2 = 2*dxy;
+}
+
+/* --Methode-- */
+void PIDrwPosSizeEvH::ProcessEvent()
+{
+  int delx, dely;
+  int ix1,iy1,ix2,iy2;
+  x1 = _x1; x2 = _x2;
+  y1 = _y1; y2 = _y2;
+  bool fgok = false;
+  int aid = -1;
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+
+  switch (EventType()) {
+    case PIEvent_But1Press :
+      // Zone de changement de taille 
+      ComputeResizeZone();
+      ix1 = x1;  iy1 = y1;
+      ix2 = _x2;  iy2 = _y2;
+      if ( (GetPosX() >= ix1) && (GetPosX() <= ix2) && 
+	   (GetPosY() >= iy1) && ((GetPosY() <= iy2) ) ) 
+	{ fgok = true; _rsz = true; }		 
+      ComputeMoveZone();
+      ix1 = x1;  iy1 = y1;
+      ix2 = (int)x2+ix1;  iy2 = (int)y2+iy1;
+      if ( (GetPosX() >= ix1) && (GetPosX() <= ix2) && 
+	   (GetPosY() >= iy1) && ((GetPosY() <= iy2) ) ) 
+	{ fgok = true; _rsz = false; }
+      if (!fgok) _okend = true;
+      else { 
+	_cpx = _ipx = GetPosX();
+	_cpy = _ipy = GetPosY();
+      }
+      break;
+
+    case  PIEvent_Ptr1Move :
+      if (_okend) return; 
+      if (_ipx < 0)  return;
+      delx = GetPosX()-_cpx;
+      dely = GetPosY()-_cpy;
+      _cpx = GetPosX(); 
+      _cpy = GetPosY(); 
+      
+      if (_fgxor) {
+        gr->SelForeground(PI_Magenta);
+        gr->SelGOMode(PI_GOXOR);
+      }
+      else {
+        gr->SelForeground(mBWdg->GetBackgroundColor());
+        gr->SelGOMode(PI_GOCopy);
+      }
+      gr->SelLine(PI_ThinLine);
+
+      ComputeDrawerZone();
+      gr->DrawBox(x1,y1, x2, y2);
+      ComputeResizeZone();
+      gr->DrawFBox(x1,y1, x2, y2);
+      ComputeMoveZone();
+      gr->DrawBox(x1,y1, x2, y2);
+
+      // Nouvelle position / taille 
+      _x2 += delx;
+      _y2 += dely;
+      if (!_rsz) { _x1 += delx;  _y1 += dely; }
+
+      if (!_fgxor) gr->SelForeground(PI_HighlightBlue);
+      ComputeDrawerZone();
+      gr->DrawBox(x1,y1, x2, y2);
+      ComputeResizeZone();
+      gr->DrawFBox(x1,y1, x2, y2);
+      ComputeMoveZone();
+      gr->DrawBox(x1,y1, x2, y2);      
+      gr->SelGOMode(gmod);
+      gr->SelLine(gline);
+      gr->SelForeground(gcol);
+
+      break;
+
+    case  PIEvent_But1Release :
+      if (_ipx < 0)  return;
+      if (_okend) {
+   // On efface de rectangle de resize/move
+        if (_fgxor) {
+          gr->SelForeground(PI_Magenta);
+          gr->SelGOMode(PI_GOXOR);
+        }       
+        else {
+          gr->SelForeground(mBWdg->GetBackgroundColor());
+          gr->SelGOMode(PI_GOCopy);
+        }
+        gr->SelLine(PI_ThinLine);
+	
+        ComputeDrawerZone();
+        gr->DrawBox(x1,y1, x2, y2);
+        ComputeResizeZone();
+        gr->DrawFBox(x1,y1, x2, y2);
+        ComputeMoveZone();
+        gr->DrawBox(x1,y1, x2, y2);
+	gr->SelGOMode(gmod);
+	gr->SelLine(gline);
+	gr->SelForeground(gcol);
+  // On enleve le handler 
+//	cout << " DBG- 	mBWdg->RemoveEventHandler(this); " << endl;
+        PIDrawer* adrw = mBWdg->GetActiveDrawer();
+        if (adrw) adrw->HighLight(false);
+	mBWdg->RemoveEventHandler(this);
+        _rmok = true;
+	return;
+      }
+
+      // Nouvelle position / taille 
+      delx = GetPosX()-_cpx;
+      dely = GetPosY()-_cpy;
+      _x2 += delx;
+      _y2 += dely;
+      if (!_rsz) { _x1 += delx;  _y1 += dely; }
+      if (_elastic) {
+	x1 = (double)_x1/(double)mBWdg->XSize();
+	x2 = (double)_x2/(double)mBWdg->XSize();
+	y1 = (double)_y1/(double)mBWdg->YSize();
+	y2 = (double)_y2/(double)mBWdg->YSize();
+      }
+      else {
+	x1 = _x1; x2 = _x2;
+	y1 = _y1; y2 = _y2;
+      }
+      if (_defrect) {
+	mBWdg->SetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
+//	cout << "DBG-SetDefaultDrawRectangle() x1,y1=" << _x1 << "," << _y1 
+//     << " x2,y2=" << _x2 << "," << _y2 << endl;
+      }
+      else {
+        aid = mBWdg->GetActiveDrawerId();
+        mBWdg->MoveResizeDrawer(aid, x1, y1, x2, y2, _elastic);
+//	cout << "DBG-MoveResizeDrawer() x1,y1=" << _x1 << "," << _y1 
+//	     << " x2,y2=" << _x2 << "," << _y2 << endl;
+      }	
+      mBWdg->Refresh();
+
+      if (_fgxor) {
+        gr->SelForeground(PI_Magenta);
+        gr->SelGOMode(PI_GOXOR);
+      }
+      else {
+        gr->SelForeground(PI_HighlightBlue);
+        gr->SelGOMode(PI_GOCopy);
+      }
+      ComputeDrawerZone();
+      gr->DrawBox(x1,y1, x2, y2);
+      ComputeResizeZone();
+      gr->DrawFBox(x1,y1, x2, y2);
+      ComputeMoveZone();
+      gr->DrawBox(x1,y1, x2, y2);      
+
+      gr->SelGOMode(gmod);
+      gr->SelLine(gline);
+      gr->SelForeground(gcol);
+
+      break; 
+
+    default :
+      break;
+  }
+  
+}
+
+//-----------------------------------------------------------------
+//------- Classe Event handler pour Mouse Select de l'active Drawer 
+class PIDrwSelectEvH : public PIEventHandler {
+public: 
+  PIDrwSelectEvH(PIBaseWdg* bwdg);
+          void    CheckBeforeDelete();
+  virtual void    ProcessEvent(); 
+
+protected:
+//  void ComputeResizeZone();
+  void ComputeOKZone();
+//  inline void ComputeDrawerZone() 
+//    { x1 = _x1;  y1 = _y1; x2 = _x2-_x1;  y2 = _y2-_y1; }
+
+
+  PIBaseWdg* mBWdg;
+  int _caid;
+  int _x1, _y1, _x2, _y2;
+  PIGrCoord x1, y1, x2, y2;
+  PIGrCoord xc, yc, rc;
+  bool _okend;
+  bool _rmok;
+};
+
+/* --Methode-- */
+PIDrwSelectEvH::PIDrwSelectEvH(PIBaseWdg* bwdg)
+{
+  mBWdg = bwdg;
+  _x1 = _y1 = _x2 = _y2 = -1;
+  x1 = y1 = x2 = y2 = xc = yc = rc = -1;
+  _okend = false;
+  _rmok = false;
+  if (bwdg == NULL) return;
+
+  int aid = bwdg->GetActiveDrawerId();
+  if (aid < 0) return;
+  
+  mBWdg->GetActiveDrawer()->HighLight(true);
+  _caid = aid;
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+  
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+
+  gr->SelForeground(PI_Magenta);
+  gr->SelGOMode(PI_GOXOR);
+  gr->SelLine(PI_ThinLine);
+
+  ComputeOKZone();
+  gr->DrawBox(x1,y1, x2, y2);
+  gr->DrawFCircle(xc,yc,rc);
+
+  gr->SelGOMode(gmod);
+  gr->SelLine(gline);
+  gr->SelForeground(gcol);
+
+//  cout << "DBG- Adding Event-Handler " << endl;
+  mBWdg->AddEventHandler(this, PIEvent_But1Press);
+}
+/* --Methode-- */
+void PIDrwSelectEvH::CheckBeforeDelete()
+{
+  if (!_rmok) {
+    PIDrawer* adrw = mBWdg->GetActiveDrawer();
+    if (adrw) adrw->HighLight(true);
+    mBWdg->RemoveEventHandler(this);	
+  }
+  _rmok = true; 
+}
+
+
+/* --Methode-- */
+void PIDrwSelectEvH::ComputeOKZone()
+{
+  bool _elastic = false;
+  int aid = mBWdg->GetActiveDrawerId();
+  if (mBWdg->IsDrawerAutoSizePos(aid)) {
+    mBWdg->GetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
+  }
+  else { 
+    mBWdg->GetDrawerPosition(aid, x1, y1, x2, y2, _elastic);
+  }
+    
+  if (_elastic) {
+    _x1 = (double)x1*(double)mBWdg->XSize();
+    _x2 = (double)x2*(double)mBWdg->XSize();
+    _y1 = (double)y1*(double)mBWdg->YSize();
+    _y2 = (double)y2*(double)mBWdg->YSize();
+  }
+  else {
+    _x1 = x1; _x2 = x2;
+    _y1 = y1; _y2 = y2;
+  }
+
+  int dx = (int)(0.06*(_x2-_x1));
+  int dy = (int)(0.06*(_y2-_y1));
+  if (dx < 20)  dx = 20;
+  if (dy < 20)  dx = 20;
+  int dxy = (dx < dy) ? dx : dy ;
+  if (dxy%2 != 0) dxy++;
+  _x1 = _x2-dxy;
+  _y1 = _y2-dxy;
+  x1 = _x1;  
+  y1 = _y1;    
+  x2 = y2 = dxy;
+  xc = _x1+dxy/2;
+  yc = _y1+dxy/2;
+  rc = dxy/2-2;
+}
+
+/* --Methode-- */
+void PIDrwSelectEvH::ProcessEvent()
+{
+
+  bool chgadrw = false;
+  int nid = -1;
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+
+
+  switch (EventType()) {
+    case PIEvent_But1Press :
+      // Zone OK=Fin
+      if ( (GetPosX() >= _x1) && (GetPosX() <= _x2) && 
+	   (GetPosY() >= _y1) && ((GetPosY() <= _y2) ) ) _okend = true;
+      else {
+        nid = mBWdg->FindNearestDrawerId(GetPosX(), GetPosY());
+        if (nid != _caid)  chgadrw = true;
+      }
+      break;
+
+    default :
+      break;
+  }
+  if ( _okend || chgadrw ) {
+    gr->SelForeground(PI_Magenta);
+    gr->SelGOMode(PI_GOXOR);
+    gr->SelLine(PI_ThinLine);
+
+    gr->DrawBox(x1,y1, x2, y2);
+    gr->DrawFCircle(xc,yc,rc);
+
+    gr->SelGOMode(gmod);
+    gr->SelLine(gline);
+    gr->SelForeground(gcol);
+
+    PIDrawer* adrw = mBWdg->GetActiveDrawer();
+    if (adrw) adrw->HighLight(false);
+    
+    if (_okend) {
+      mBWdg->RemoveEventHandler(this);
+      _rmok = true;
+      return;
+    }		 
+    else { 
+      mBWdg->SetActiveDrawerId(nid);
+      _caid = nid;
+      adrw = mBWdg->GetActiveDrawer();
+      if (adrw) adrw->HighLight(true);
+    
+      gr->SelForeground(PI_Magenta);
+      gr->SelGOMode(PI_GOXOR);
+      gr->SelLine(PI_ThinLine);
+
+      ComputeOKZone();
+
+      gr->DrawBox(x1,y1, x2, y2);
+      gr->DrawFCircle(xc,yc,rc);
+
+      gr->SelGOMode(gmod);
+      gr->SelLine(gline);
+      gr->SelForeground(gcol);
+    }
+  }  
+}
+
+
+
+//------------------------------------------------------------
+/* --Methode-- */
+PIDrwMgrMenu::PIDrwMgrMenu(PIBaseWdg* bwdg, bool fgxor) 
+  : PIMenu(bwdg, "PIDrwMgrMenu", k_PopupMenu)
+{
+  mBWdg = bwdg;
+  mListDrw = NULL;
+  mFgxor = fgxor;
+  mEvH = NULL;
+  mSEvH = NULL;
+
+  if (bwdg == NULL) return;
+
+  AppendItem("GraphicAttTools", 401);
+  AppendItem("OptionStringWin", 402);
+  AppendItem("ControlWin", 403);
+  AppendItem("Move/ReSize", 404);
+  AppendSeparator();
+  AppendItem("Detach", 405);
+  AppendItem("MouseSelect", 406);
+  AppendItem("Refresh", 407);
+  int aid = bwdg->GetActiveDrawerId();
+  if (aid < 0) {
+    for(int i=1; i<=6; i++)
+      SetSensitivityMsg(400+i, false);
+  }
+  else {
+    if ( !(bwdg->GetActiveDrawer()->HasSpecificControlWindow()) ) 
+      SetSensitivityMsg(403, false);
+    if ( bwdg->IsDrawerLockedId(aid)) 
+      SetSensitivityMsg(405, false);
+  }
+  if (bwdg->NbDrawers() > 0) {
+    AppendSeparator();
+    mListDrw = new PIMenu(this, "SelActiveDrw", k_PulldownMenu);
+    for(int k=0; k<bwdg->NbDrawers(); k++) {
+      char buff[16];
+      sprintf(buff, "%d- ", k);
+      string mit = buff;
+      mit += bwdg->GetDrawer(k)->Name();
+      mListDrw->AppendItem(mit.c_str(), 1000+k);
+      if (bwdg->GetDrawerIdFromNum(k) == aid)  
+	mListDrw->SetSensitivityMsg(1000+k, false);
+    }
+    AppendPDMenu(mListDrw);
+  }
+//SUP  PIDrawer*  actdr = mBWdg->GetActiveDrawer();
+//SUP  if (actdr)  actdr->HighLight(true);
+}
+
+/* --Methode-- */
+PIDrwMgrMenu::~PIDrwMgrMenu() 
+{
+  if (mListDrw) delete mListDrw;
+  if (mEvH) { 
+    mEvH->CheckBeforeDelete();
+    delete mEvH;
+  }
+  if (mSEvH) { 
+    mSEvH->CheckBeforeDelete();
+    delete mSEvH;
+  }
+}
+
+/* --Methode-- */
+void PIDrwMgrMenu::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{  
+  if (mBWdg == NULL) return;
+  int aid = mBWdg->GetActiveDrawerId();
+  PIDrawer* actdrw = mBWdg->GetActiveDrawer();
+  PIMessage mod = ModMsg(msg);
+  msg = UserMsg(msg);
+  switch (msg) {
+    case 401 :
+      if (aid >= 0)  PIDrwTools::ShowPIDrwTools(mBWdg);
+      break;
+    case 402 :
+      if (actdrw != NULL) { 
+	PIDrwOptionStringWindow::ShowDrwOptionStringWindow(actdrw);
+	actdrw->HighLight(false);
+      }
+      break;
+    case 403 :
+      if (actdrw != NULL) { 
+	actdrw->ShowControlWindow(mBWdg);
+      }
+      break;
+    case 404 :
+      if (mEvH) { 
+	mEvH->CheckBeforeDelete();	
+	delete mEvH;
+      }
+      mEvH = new PIDrwPosSizeEvH(mBWdg, mFgxor);
+      break;
+    case 405 :
+      if (aid >= 0) { 
+	mBWdg->RemoveDrawer(aid);
+	mBWdg->Refresh();
+      }
+      break;
+    case 406 :
+      if (mSEvH) { 
+	mSEvH->CheckBeforeDelete();	
+	delete mSEvH;
+      }
+      mSEvH = new PIDrwSelectEvH(mBWdg);
+      break;
+    case 407 :
+      mBWdg->Refresh();
+      break;
+    default :
+      if (actdrw != NULL) actdrw->HighLight(false);
+      if (msg >= 1000)
+	mBWdg->SetActiveDrawer(msg-1000);
+      break;
+  }
+
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pidrwtools.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pidrwtools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pidrwtools.h	(revision 3445)
@@ -0,0 +1,102 @@
+// 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 PIMENU_H
+#include PIOPTMENU_H
+#include PIWIN_H
+#include PIAPP_H
+#include "pibwdggen.h"
+
+// ------ fenetres de dialogue pour modifs options/attributs des Drawers ----------
+// --------------------------------------------------------------------------------
+
+class PIDrawer;  // Declaration des objets drawer
+
+// fenetre de gestion interactive des attributs graphique
+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[7];
+  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;
+};
+
+// Classe pour le changement interactive des attributs par appel 
+// a DecodeOptionString 
+
+class PIDrwOptionStringWindow : public PIWindow 
+{
+public:
+  static void ShowDrwOptionStringWindow(PIDrawer* drw);
+  static void RemoveDrwOptionStringWindow(PIDrawer* drw);
+
+  PIDrwOptionStringWindow(PIApplication* par, PIDrawer* drw);
+  ~PIDrwOptionStringWindow();
+  virtual void  Show();
+  inline PIDrawer* GetDrawer() { return mDrw; }
+
+protected:
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+private:
+  PIText* mTxt[2]; 
+  PILabel* mLab;
+  PIButton* mBut[4];
+  PIDrawer* mDrw;
+};
+
+//-------------------------------------------------------------------------------------------
+// Classe de menu specifique de manipulation interactive des drawers attaches a un PIBaseWdg
+//-------------------------------------------------------------------------------------------
+class PIDrwPosSizeEvH;  // Event Handler pour le deplacement/resize des drawers 
+class PIDrwSelectEvH;   // Event Handler pour la selection interactive des drawers 
+
+class PIDrwMgrMenu : public PIMenu {
+public:
+                  PIDrwMgrMenu(PIBaseWdg* bwdg, bool fgxor=true);
+  virtual         ~PIDrwMgrMenu();
+  virtual void    Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+protected:
+  PIMenu*  mListDrw;
+  PIBaseWdg* mBWdg;
+  bool mFgxor;
+  PIDrwPosSizeEvH* mEvH;
+  PIDrwSelectEvH* mSEvH;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/pieldrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pieldrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pieldrw.cc	(revision 3445)
@@ -0,0 +1,735 @@
+// Module PI : Peida Interactive     PIElDrawer
+//	      E. Aubourg , R.Ansari     96-02
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <strings.h>
+#include <iostream>
+
+#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_Oval :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawOval(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->DrawOval((*it).ex, (*it).ey, (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_FOval :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawFOval(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->DrawFOval((*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(kAxesDflt);
+    else if (opts == "boxaxesgrid")
+      SetAxesFlags(kAxesDflt | kGridOn);
+    else if (opts == "fineaxes") 
+      SetAxesFlags(kAxesDflt | kMinTicks | kMajTicks);
+    else if (opts == "fineaxesgrid")
+      SetAxesFlags(kAxesDflt | kMinTicks | kMajTicks | kGridOn);
+    else if (opts == "centeredaxes")
+      SetAxesFlags(kCentAxes | kTicks | kMajTicks | kLabels);
+    else if (opts == "finecenteredaxes")
+      SetAxesFlags(kCentAxes | kTicks | kMajTicks | kMinTicks | kLabels);
+    else if (opts == "centeredaxesgrid")
+      SetAxesFlags(kCentAxes | kTicks | kMajTicks | kLabels | kGridOn);
+    else if (opts == "finecenteredaxesgrid")
+      SetAxesFlags(kCentAxes | kTicks | 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 == "hlabels")
+      SetAxesFlags(GetAxesFlags() | kLabelsH);
+    else if (opts == "nohlabels")
+      SetAxesFlags(GetAxesFlags() & ~kLabelsH);
+    else if (opts == "vlabels")
+      SetAxesFlags(GetAxesFlags() | kLabelsV);
+    else if (opts == "novlabels")
+      SetAxesFlags(GetAxesFlags() & ~kLabelsV);
+    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() & ~kIntTicks |  kExtTicks);
+    else if (opts == "intticks")
+      SetAxesFlags(GetAxesFlags() & ~kExtTicks |  kIntTicks);
+    else if (opts == "extintticks")
+      SetAxesFlags(GetAxesFlags() | kIntTicks |  kExtTicks);
+    else if (opts == "grid")
+      SetAxesFlags(GetAxesFlags() | kGridOn);
+    else if (opts == "nogrid")
+      SetAxesFlags(GetAxesFlags() & ~kGridOn);
+    else if (opts.substr(0,11) == "axescenter=") {
+      if(opts == "axescenter=") {
+        axeDr.ConfigureAxesCenter();
+      } else {
+        double x0=0., y0=0.;
+        sscanf(opts.substr(11).c_str(),"%lf,%lf",&x0,&y0);
+        axeDr.ConfigureAxesCenter(true,x0,y0);
+      }
+    }
+
+    else if (opts.substr(0,13) == "autofontsize=") {
+      double fszf = atof(opts.substr(13).c_str());
+      ConfigureAxeAutoFontSize(fszf);
+      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 if (opts.substr(0,8) == "nbticks=") {
+      int xnticks=0;
+      int ynticks=0;
+      sscanf(opts.substr(8).c_str(),"%d,%d", &xnticks, &ynticks);
+      ConfigureAxeTicks(xnticks, ynticks, 0., 0.);
+    }
+    else if (opts.substr(0,9) == "tickslen=") {
+      double fmajtl = 0.;
+      double fmintl = 0.;
+      sscanf(opts.substr(9).c_str(),"%lg,%lg", &fmajtl, &fmintl);
+      ConfigureAxeTicks(0, 0, fmajtl, fmintl);
+    }
+    else {
+      ndec--;
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }  
+
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+/* --Methode-- */
+void PIElDrawer::GetOptionsHelpInfo(string& info)
+{
+  info += " ---- PIElDrawer options help info : \n" ;
+  info += " >> Axe and grid configuration flags: \n";
+  info += "   axesnone  stdaxes defaxes \n";
+  info += "   boxaxes boxaxesgrid fineaxes fineaxesgrid \n";
+  info += "   centeredaxes finecenteredaxes centeredaxesgrid \n";
+  info += "   finecenteredaxesgrid  grid/nogrid \n";
+  info += " >> Centered axes position: axescenter=xc,yc \n";
+  info += " >> Axe ticks/labels (h=horizontal/x, v=vertical/y): \n"; 
+  info += "   labels/nolabels  hlabels/nohlabels vlabels/novlabels \n";
+  info += "   ticks/noticks minorticks/nominorticks \n";
+  info += "   extticks/intticks/extintticks nbticks=X_NbTicks,Y_NbTicks \n";
+  info += "   tickslen=MajorTickLenFrac,MinorTickLenFraC \n";
+  info += " >> Axe label font size: \n";
+  info += "    autofontsize=FontSizeFrac fixedfontsize \n";
+  info += " >> Up/Down title: title tit notitle notit \n";
+  info += "    ... Color/Font/line attributes : \n";
+// On recupere ensuite la chaine info de la classe de base
+  PIDrawer::GetOptionsHelpInfo(info);
+  return;  
+}
+
+/* --Methode-- */
+void  PIElDrawer::DrawAxes(PIGraphicUC* g)
+{
+  if (axesFlags == kAxesNone) return;
+  //  g->NoClip();
+  axeDr.DrawXYAxes(g, mGrAtt, XMin(), XMax(), YMin(), YMax(), 
+		   axesFlags, axesAFSz); 
+  if (showAxesLabels) { 
+    axeDr.DrawXCaption(g, labelAtt, axesFlags, xLabel);
+    axeDr.DrawYCaption(g, labelAtt, axesFlags, yLabel);
+  }
+  //  g->Clip();
+}
+
+/* --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);
+  if ( titleT.length() > 0) {
+    fh = 0.04*(YMax()-YMin());
+    if (g->isAxeYDirUpDown()) fy = g->DeltaUCY(YMin(), -fh);
+    else fy = g->DeltaUCY(YMax(), fh);
+    g->DrawString(fx, fy, titleT.c_str(), PI_HorizontalCenter | PI_VerticalBottom);
+    //      printf(" PIElDrawer::Draw()/DBG (%g , %g) %s  - %g \n", fx, fy, titleT.c_str(), fh);
+  }
+  if ( titleB.length() > 0) {
+    fh = 0.075*(YMax()-YMin());
+    if (g->isAxeYDirUpDown()) fy =  g->DeltaUCY(YMax(), fh);
+    else fy = g->DeltaUCY(YMin(), -fh);
+    g->DrawString(fx, fy, titleB.c_str(), PI_HorizontalCenter | PI_VerticalTop);
+    //      printf(" PIElDrawer::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);
+
+}
+
+/* --Methode-- */
+double  PIElDrawer::GetDistanceToPoint(double x, double y) 
+{
+  double dist,disty,distx,d1,d2;
+  bool fgokx, fgoky;
+  d1 = fabs(x-XMin());
+  d2 = fabs(x-XMax());
+  if ((y<YMax()) && (y>YMin()))  { 
+    distx = (d1 < d2) ? d1 : d2;
+    distx /= 0.5*(XMax()-XMin());
+    fgokx = true;
+  }
+  else fgokx = false;
+  d1 = fabs(y-YMin());
+  d2 = fabs(y-YMax());
+  if ((x<XMax()) && (x>XMin()))  { 
+    disty = (d1 < d2) ? d1 : d2;
+    disty /= 0.5*(YMax()-YMin());
+    fgoky = true;
+  }
+  else fgoky = false;
+  if (!fgokx  && !fgoky)  return PIDrawer::GetDistanceToPoint(x,y);
+  else {
+    if (fgokx && fgoky) dist = (distx<disty) ? distx : disty;
+    else if (fgokx) dist = distx;
+    else dist = disty;
+  }
+  return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pieldrw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pieldrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pieldrw.h	(revision 3445)
@@ -0,0 +1,284 @@
+// 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_Oval = 7, PIDEL_FOval = 8,
+         PIDEL_Arc = 9,  PIDEL_FArc = 10,
+         PIDEL_Arc3P = 11,  PIDEL_FArc3P = 12,
+         PIDEL_Poly = 13, PIDEL_FPoly = 14,
+	 PIDEL_Mark = 15, PIDEL_Arrow = 16,
+         PIDEL_CText = 17  } ; 
+
+		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' ovales
+  inline int    ElAddOval(double x, double y, double dx, double dy, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Oval, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddOval(double x, double y, double dx, double dy, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Oval, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+
+  inline int    ElAddFOval(double x, double y, double dx, double dy, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_FOval, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddFOval(double x, double y, double dx, double dy, 
+			   PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_FOval, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+
+  // ---- 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);
+//   Texte d'aide des options disponibles
+  virtual void	     GetOptionsHelpInfo(string& info);
+
+  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); 
+
+// Renvoie une distance au point x,y 
+// 0: au(x) point(s) le(s) plus proche(s) ... 1  au bord xmin/xmax , ymin/ymax
+// La methode par defaut calcule la distance normalisee au point ((xmin+xmax)/2,(ymin+ymax)/2)
+  virtual double     GetDistanceToPoint(double x, double y);
+
+  inline void        ConfigureAxeTicks(int ntickx=0, int nticky=0, 
+				       double majtl=0., double mintl=0.)
+     { axeDr.ConfigureTicks(ntickx, nticky, majtl, mintl); }
+  inline void        ConfigureAxeAutoFontSize(double fszf=0.)
+     { axeDr.ConfigureAutoFontSize(fszf); }
+
+  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()
+  PIAxes axeDr;                // Trace d'axes
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/pierrdisp.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pierrdisp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pierrdisp.cc	(revision 3445)
@@ -0,0 +1,106 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pierrdisp.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pierrdisp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pierrdisp.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pievthandler.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pievthandler.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pievthandler.cc	(revision 3445)
@@ -0,0 +1,142 @@
+// 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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pievthandler.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pievthandler.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pievthandler.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pifilechogen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifilechogen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifilechogen.cc	(revision 3445)
@@ -0,0 +1,74 @@
+// Module PI : Peida Interactive     PIFileChooser
+// Selecteur de fichier                    96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pifilechogen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifilechogen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifilechogen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pifilechox.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifilechox.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifilechox.cc	(revision 3445)
@@ -0,0 +1,174 @@
+#include<stdio.h>
+#include<string.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pifilechox.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifilechox.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifilechox.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pifontgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifontgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifontgen.cc	(revision 3445)
@@ -0,0 +1,97 @@
+// Module PI : Peida Interactive     PIFontGen 
+// LAL (Orsay) / IN2P3-CNRS          R. Ansari  99
+
+// Classe generique de gestion de fonte - (Ne peut etre instancie)
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pifontgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifontgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifontgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pifontx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifontx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifontx.cc	(revision 3445)
@@ -0,0 +1,405 @@
+// 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 "sopnamsp.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_Nov2007/SophyaPI/PI/pifontx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pifontx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pifontx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigfname.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigfname.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigfname.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraph3d.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraph3d.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraph3d.cc	(revision 3445)
@@ -0,0 +1,492 @@
+// 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 "sopnamsp.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_Nov2007/SophyaPI/PI/pigraph3d.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraph3d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraph3d.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraphgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphgen.cc	(revision 3445)
@@ -0,0 +1,859 @@
+// 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 "sopnamsp.h"
+#include "pigraphgen.h"
+#include <math.h>
+#include <iostream>
+#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.
+//--
+
+inline void compstring_swapcoord( unsigned long txtdir, PIGrCoord& x, PIGrCoord& y)
+{
+  if (txtdir != PI_TextDirectionHorizontal) {
+    PIGrCoord tmp = x;
+    x = y; y = tmp;
+  }
+  return;
+}
+
+inline void compstring_chksgn_dyud( unsigned long txtdir, int & dyu, int & dyd)
+{
+  if (txtdir == PI_TextDirectionVerticalDown) {
+    dyu = -dyu;
+    dyd = -dyd;
+  }
+}
+inline void compstring_chksgn_dx( unsigned long txtdir, int & dx)
+{
+  if (txtdir == PI_TextDirectionVerticalUp)  dx = -dx;
+}
+
+/* --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,xss,yss; 
+  int posh = pos & PI_HorizontalPosition;
+  int posv = pos & PI_VerticalPosition;
+  unsigned long txtdir = pos&PI_TextDirection;
+
+  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;
+
+  // Pour gerer les traces de texte verticaux 
+  compstring_swapcoord(txtdir, x, y);
+  compstring_chksgn_dyud( txtdir, dyu, dyd);
+  compstring_chksgn_dx( txtdir, deltaposx); 
+  compstring_chksgn_dx( txtdir, sw_s); 
+  compstring_chksgn_dx( txtdir, sw_sup); 
+  compstring_chksgn_dx( txtdir, sw_sdn); 
+
+  if ((pos == 0) || ((posh == PI_HorizontalLeft) && (posv == PI_VerticalBaseLine))) {
+    xs = (int)x+sw_s;
+    ys = y;
+    compstring_swapcoord(txtdir, xs, ys);    
+    if (s != NULL)  DrawString(xs, ys, s, txtdir | PI_HorizontalRight);
+    xs = (int)x+sw_s+deltaposx;
+    ys = (int)y+dyu;
+    SelFont(fnt_ss);
+    compstring_swapcoord(txtdir, xs, ys);    
+    if (s_up != NULL) DrawString(xs, ys, s_up, txtdir | PI_HorizontalLeft);
+    xs = (int)x+sw_s+deltaposx;
+    ys = (int)y+dyd;
+    compstring_swapcoord(txtdir, xs, ys);    
+    if (s_dn != NULL) DrawString(xs, ys, s_dn, txtdir | PI_HorizontalLeft);
+  }
+  else {
+    if (posh == PI_HorizontalRight) {
+      int sw_ss_max = ( sw_sup > sw_sdn ) ? sw_sup : sw_sdn;
+      xss = xs = (int)x-sw_ss_max-deltaposx;
+      ys = y;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s != NULL)  DrawString(xs, ys, s, txtdir | PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)xss+deltaposx;
+      ys = (int)y+dyu;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_up != NULL) DrawString(xs, ys, s_up, txtdir | PI_HorizontalLeft);
+      xs = (int)xss+deltaposx;
+      ys = (int)y+dyd;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, txtdir | PI_HorizontalLeft);      
+    }
+    else if (posh == PI_HorizontalCenter) {
+      int sw_tot = sw_sup+sw_sdn+sw_s+deltaposx;
+      xss = xs = (int)x-sw_tot/2+sw_s; 
+      ys = y;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s != NULL)  DrawString(xs, ys, s, txtdir | PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)xss+deltaposx;
+      ys = (int)y+dyu;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_up != NULL) DrawString(xs, ys, s_up, txtdir | PI_HorizontalLeft);
+      xs = (int)xss+deltaposx;
+      ys = (int)y+dyd;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, txtdir | PI_HorizontalLeft);            
+    }
+    else {
+      xs = (int)x+sw_s;
+      ys = y;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s != NULL)  DrawString(xs, ys, s, txtdir | PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)x+sw_s+deltaposx;
+      ys = (int)y+dyu;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_up != NULL) DrawString(xs, ys, s_up, txtdir | PI_HorizontalLeft);
+      xs = (int)x+sw_s+deltaposx;
+      ys = (int)y+dyd;
+      compstring_swapcoord(txtdir, xs, ys);    
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, txtdir | 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)*0.75;
+    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)*0.75;
+    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()
+{
+  // Doit-on sauver et utiliser l'etat de lock ? Reza - Mai 2003
+  sFCol = GetForeground();
+  sBCol = GetBackground();
+  sGOm = GetGOMode();
+  sFont = GetFont();   
+  sLAtt = GetLineAtt();
+  sMrk = GetMarker();   
+  sMrkSz = GetMarkerSize();
+  sArrowMrk = GetArrowMarker();
+  sArrowMrkSz = GetArrowMarkerSize();
+  return;
+}
+
+/* --Methode-- */
+void PIGraphicGen::RestoreGraphicAtt()
+{
+  UnLockForegroundColor(); // Doit-on sauver et utiliser l'etat de lock ?
+  SelForeground(sFCol);
+  SelBackground(sBCol);
+  SelGOMode(sGOm);
+  SelFont(sFont);
+  SelLine(sLAtt);
+  SelMarker(sMrkSz, sMrk);
+  SelArrowMarker(sArrowMrkSz, sArrowMrk);
+  return;
+}
+
+
+
Index: /tags/V_Nov2007/SophyaPI/PI/pigraphgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraphics.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphics.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphics.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraphps.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphps.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphps.cc	(revision 3445)
@@ -0,0 +1,524 @@
+// Module PI : Peida Interactive     PIGraphicPS
+// Trace graphiques en PostScript    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pigraphps.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphps.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphps.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraphuc.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphuc.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphuc.cc	(revision 3445)
@@ -0,0 +1,991 @@
+// Module PI : Peida Interactive     PIGraphicUC 
+// Trace graphiques User-Coordinates    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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;
+  if (myLockFCol)  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_Nov2007/SophyaPI/PI/pigraphuc.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphuc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphuc.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigraphx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphx.cc	(revision 3445)
@@ -0,0 +1,909 @@
+// 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 "sopnamsp.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  128 
+
+/* --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;
+if ( XAllocNamedColor (mdsp, cmap, "SkyBlue", &mycol, &exact) )
+  colpix[PI_SkyBlue] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "RoyalBlue", &mycol, &exact) )
+  colpix[PI_RoyalBlue] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "ForestGreen", &mycol, &exact) )
+  colpix[PI_ForestGreen] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "OrangeRed", &mycol, &exact) )
+  colpix[PI_OrangeRed] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "brown", &mycol, &exact) )
+  colpix[PI_Brown] = mycol.pixel;
+
+mycol.red = 39000;
+mycol.blue = 65535;
+mycol.green = 49000;
+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_Nov2007/SophyaPI/PI/pigraphx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigraphx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigraphx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pigratt.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigratt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigratt.cc	(revision 3445)
@@ -0,0 +1,913 @@
+// Module PI : Peida Interactive     PIGraphicAtt 
+// PIGraphicAtt - Implementation     R. Ansari  2002
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "pigratt.h"
+#include <ctype.h>
+#include "strutilxx.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.
+// int  AttToStrings(vector<string> & att) const
+//	Renvoie dans "att" les attributs sous forme de string Décodeable 
+//	par *DecodeAttStrings()* . Retourne le nombre d'éléments ajoutés.
+// 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;
+
+#define GRA_NCOLMX 25
+static PIColors GrAcolTab[GRA_NCOLMX] = 
+  { 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, PI_SkyBlue, PI_RoyalBlue , PI_ForestGreen, 
+    PI_OrangeRed, PI_Brown };
+
+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;
+  gic = PI_SkyBlue;
+  GrAcol["skyblue"] = gic;
+  gic = PI_RoyalBlue;
+  GrAcol["royalblue"] = gic;
+  gic = PI_ForestGreen;
+  GrAcol["forestgreen"] = gic;
+  gic = PI_OrangeRed;
+  GrAcol["orangered"] = gic;
+  gic = PI_Brown;
+  GrAcol["brown"] = 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++ ) {
+    bool fgdec = false;
+    string gratt = att[k];
+    // Valeurs par defaut 
+    if (gratt == "default") { 
+      SetDefaultAtt();  
+      fgdec = true;
+    }
+    // Decodage couleur avant-plan/arriere-plan avec fgcolor=colname ou bgcolor=colname
+    else if ( (gratt.substr(0, 8) == "fgcolor=") || (gratt.substr(0, 8) == "bgcolor=") ||  
+	 (gratt.substr(0, 6) == "color=") ) {
+      string scol;
+      bool sfgc = true;
+      if (gratt[0] != 'c')  {
+	if (gratt[0] == 'b') sfgc = false;
+	scol = gratt.substr(8);
+      }
+      else scol = gratt.substr(6);
+
+      GrAttColors& GrAcol = *GrAcolors;
+      GrAttColors::const_iterator itc = GrAcol.find(scol);
+      PIColors cdcol = PI_NotDefColor;
+      fgdec = false;
+      if (itc != GrAcol.end())  { 
+	cdcol = (*itc).second;  fgdec = true;  
+      }
+      if (sfgc) mFCol = cdcol;
+      else mBCol = cdcol;
+      fgdec = true;
+    }
+    // Decodage de fonte sous forme de font=FontName,FontAtt,FontSizePt
+    else if (gratt.substr(0, 5) == "font=") {
+      PIFontName dfn = PI_DefaultFont;
+      int dfsz = 10;
+      PIFontAtt dfa = PI_RomanFont;
+      vector<string> fna;
+      FillVStringFrString(gratt.substr(5), fna, ',');
+      if (fna.size() > 0) {
+	if (fna[0] == "courier") dfn = PI_CourierFont;
+	else if (fna[0] == "helvetica") dfn = PI_HelveticaFont;
+	else if (fna[0] == "times") dfn = PI_TimesFont;
+	else if (fna[0] == "symbol") dfn = PI_SymbolFont;
+      }
+      if (fna.size() > 1) {
+	if (fna[1] == "roman") dfa = PI_RomanFont;
+	else if (fna[1] == "bold") dfa = PI_BoldFont;
+	else if (fna[1] == "italic") dfa = PI_ItalicFont;
+	else if (fna[1] == "bolditalic") dfa = PI_BoldItalicFont;
+      }
+      if (fna.size() > 2) dfsz = atoi(fna[2].c_str());
+      //      cout << "DBG-GRATT: " << fna[0] << " " << fna[1] << " " << dfsz << endl;
+      mFnt.SetFont(dfn);
+      mFnt.SetFontAtt(dfa);
+      mFnt.SetFontSzPt(dfsz);
+      if (fna.size() > 0) mNotDefFnt = true;
+      else  mNotDefFnt = false;
+      fgdec = true;
+    }
+    // Decodage d'attribut de ligne sous forme de line=dashtype,width
+    else if (gratt.substr(0, 5) == "line=") {
+      PILineDash dld = PI_LineSolid;
+      int dlw = 1;
+      vector<string> lna;
+      FillVStringFrString(gratt.substr(5), lna, ',');
+      if (lna.size() > 0) {
+	if (lna[0] == "solid") dld = PI_LineSolid;
+	else if (lna[0] == "dashed") dld = PI_LineDashed;
+	else if (lna[0] == "dotted") dld = PI_LineDotted;
+	else if (lna[0] == "dashdotted") dld = PI_LineDashDotted;
+      }
+      if (lna.size() > 1) dlw = atoi(lna[1].c_str());
+      mLAtt.SetLineWidth(dlw);
+      mLAtt.SetLineDash(dld);
+      fgdec = true;
+    }
+    // decodage de marker sous forme de marker=type,size
+    else if (gratt.substr(0, 7) == "marker=") {
+      PIMarker dmrk = PI_NotDefMarker;
+      int dmsz = 1;
+      vector<string> mka;
+      FillVStringFrString(gratt.substr(7), mka, ',');
+      if (mka.size() > 0) {
+	if (mka[0] == "dot") dmrk = PI_DotMarker;
+	else if (mka[0] == "plus") dmrk = PI_PlusMarker;
+  	else if (mka[0] == "cross") dmrk = PI_CrossMarker;
+      	else if (mka[0] == "circle") dmrk = PI_CircleMarker;
+      	else if (mka[0] == "fcircle") dmrk = PI_FCircleMarker;
+      	else if (mka[0] == "box") dmrk = PI_BoxMarker;
+      	else if (mka[0] == "fbox") dmrk = PI_FBoxMarker;
+      	else if (mka[0] == "triangle") dmrk = PI_TriangleMarker;
+      	else if (mka[0] == "ftriangle") dmrk = PI_FTriangleMarker;
+      	else if (mka[0] == "star") dmrk = PI_StarMarker;
+      	else if (mka[0] == "fstar") dmrk = PI_FStarMarker;
+      }
+      if (mka.size() > 1) dmsz = atoi(mka[1].c_str());
+      mMrk = dmrk;  
+      mMSz = dmsz;
+      fgdec = true;
+    }
+    // decodage de arrowmarker sour forme de arrow=type,size
+    else if (gratt.substr(0, 6) == "arrow=") {
+      PIArrowMarker darr = PI_NotDefArrowMarker;
+      int dasz = 3;
+      vector<string> mka;
+      FillVStringFrString(gratt.substr(6), mka, ',');
+      if (mka.size() > 0) {
+	if (mka[0] == "basic") darr = PI_BasicArrowMarker;
+      	else if (mka[0] == "triangle") darr = PI_TriangleArrowMarker;
+      	else if (mka[0] == "ftriangle") darr = PI_FTriangleArrowMarker;
+      	else if (mka[0] == "arrowshaped") darr = PI_ArrowShapedArrowMarker;
+      	else if (mka[0] == "farrowshaped") darr = PI_FArrowShapedArrowMarker;
+      }
+      if (mka.size() > 1) dasz = atoi(mka[1].c_str());
+      mArrowMrk = darr;
+      mArrowMrkSz = dasz;
+      fgdec = true;
+    }
+    
+    // Inversion d'indexage de ColorMap
+    else if (gratt == "revcmap")  { 
+      mRevCmap = true;  fgdec = true;
+    }
+    if (fgdec) continue;
+
+    // Si c'est un colormap
+    fgdec = false;
+    GrAttColMaps& GrAcmp = *GrAcmaps;
+    GrAttColMaps::const_iterator itcm = GrAcmp.find(gratt);
+    if (itcm != GrAcmp.end())  { 
+      mCmapid = (*itcm).second;  
+      fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+
+    // Le decodage ancienne maniere (avant Mai 2003)
+    // Si c'est une couleur
+    GrAttColors& GrAcol = *GrAcolors;
+    GrAttColors::const_iterator itc = GrAcol.find(gratt);
+    fgdec = false;
+    if (itc != GrAcol.end())  { 
+      mFCol = (*itc).second;  fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    // Si c'est un attribut de lignes
+    fgdec = false;
+    GrAttLines& GrAlin = *GrAlines;
+    GrAttLines::const_iterator itl = GrAlin.find(gratt);
+    if (itl != GrAlin.end())  { 
+      mLAtt = (*itl).second;  fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    // Si c'est un nom de fontes
+    fgdec = false;
+    GrAttFontNames& GrAfontnm = *GrAfontNames;
+    GrAttFontNames::const_iterator itfn = GrAfontnm.find(gratt);
+    if (itfn != GrAfontnm.end()) { 
+      mFnt.SetFont((*itfn).second);  
+      mNotDefFnt = true;  fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    // Si c'est un attribut de fontes
+    fgdec = false;
+    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;  fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    // Si c'est un attribut de markers
+    fgdec = false;
+    GrAttMarkers& GrAmrk = *GrAmarkers;
+    GrAttMarkers::const_iterator itm = GrAmrk.find(gratt);
+    if (itm != GrAmrk.end()) {
+      mMrk = (*itm).second.mrk;  
+      mMSz = (*itm).second.msz;  
+      fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    // Si c'est un attribut de ArrowMarker (fleche)
+    fgdec = false;
+    GrAttArrowMarkers& GrAarrmrk = *GrAarrowMarkers;
+    GrAttArrowMarkers::const_iterator itam = GrAarrmrk.find(gratt);
+    if (itam != GrAarrmrk.end()) {
+      mArrowMrk = (*itam).second.amrk;  
+      mArrowMrkSz = (*itam).second.amsz;  
+      fgdec = true;  continue; 
+    }
+    if (fgdec) continue;
+    
+    ndec--;
+    if (rmdecatt)  udatt.push_back(gratt);
+  }
+  if (rmdecatt)  att = udatt;
+  return(ndec);
+}
+
+int PIGraphicAtt::AttToStrings(vector<string> & att) const
+{
+  // On ne vide pas (ne met pas a zero) att, mais on ajoute derriere.
+  //  att.push_back("??GraphicAtt??");
+  char sbuff[32];
+  string astr;
+  int naj = 0;
+  // ------ Attribut de couleur
+  for (GrAttColors::const_iterator it = GrAcolors->begin(); 
+       it != GrAcolors->end(); it++) 
+    if ( (*it).second == mFCol ) {
+      att.push_back((*it).first); 
+      naj++;
+      break;
+    }
+  // ------ Attribut de ligne
+  astr = "line=";
+  if (mLAtt.GetLineDash() == PI_LineSolid) astr += "solid,";
+  else if (mLAtt.GetLineDash() == PI_LineDashed) astr += "dashed,";
+  else if (mLAtt.GetLineDash() == PI_LineDotted) astr += "dotted";
+  else if (mLAtt.GetLineDash() == PI_LineDashDotted) astr += "dashdotted";
+  else astr += "solid,";
+  sprintf(sbuff,"%d",mLAtt.GetLineWidth());
+  astr += sbuff;
+  att.push_back(astr); 
+  naj++;
+  // ------ Attribut de fonte
+  astr = "font=";
+  if (mFnt.GetFontName() == PI_CourierFont) astr += "courier,";
+  else if (mFnt.GetFontName() == PI_HelveticaFont) astr += "helvetica,";
+  else if (mFnt.GetFontName() == PI_TimesFont) astr += "times,";
+  else if (mFnt.GetFontName() == PI_SymbolFont) astr += "symbol,";
+  else astr += "courier,";
+  if (mFnt.GetFontAtt() == PI_RomanFont) astr += "roman,";
+  else if (mFnt.GetFontAtt() == PI_BoldFont) astr += "bold,";
+  else if (mFnt.GetFontAtt() == PI_ItalicFont) astr += "italic,";
+  else if (mFnt.GetFontAtt() == PI_BoldItalicFont) astr += "bolditalic,";
+  else astr += "roman,";
+  sprintf(sbuff,"%d",mFnt.GetFontSize());
+  astr += sbuff;
+  att.push_back(astr); 
+  naj++;
+  // ------ Attribut de table de couleur
+  for (GrAttColMaps::const_iterator it = GrAcmaps->begin(); 
+       it != GrAcmaps->end(); it++) 
+    if ( (*it).second == mCmapid ) {
+      att.push_back((*it).first); 
+      naj++;
+      break;
+    }
+  // Inversion d'indexage de ColorMap
+  //  else if (gratt == "revcmap")  { 
+  if (mRevCmap) {
+    att.push_back("revcmap");
+    naj++;
+  }
+
+  // ------ Attribut de marqueur
+  const char* mrkn[11] = {"dot", "plus", "cross", 
+			  "circle", "fcircle", 
+			  "boxmarker", "fbox", 
+			  "triangle", "ftriangle", 
+			  "star", "fstar"};
+  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};
+  if (mMrk != PI_NotDefMarker) {
+    astr = "marker=";
+    for(int kk=0; kk<11; kk++) 
+      if (mrk[kk] == mMrk)  { 
+	astr += mrkn[kk];
+	break;
+      }
+    sprintf(sbuff,",%d",mMSz);
+    astr += sbuff;
+    att.push_back(astr); 
+    naj++;
+  }
+  if (mArrowMrk != PI_NotDefArrowMarker) {
+    astr = "arrow=";
+    if (mArrowMrk == PI_BasicArrowMarker)  astr += "basic";
+    else if (mArrowMrk == PI_TriangleArrowMarker)  astr += "triangle";
+    else if (mArrowMrk == PI_FTriangleArrowMarker)  astr += "ftriangle";
+    else if (mArrowMrk == PI_ArrowShapedArrowMarker)  astr += "arrowshaped";
+    else if (mArrowMrk == PI_FArrowShapedArrowMarker)  astr += "farrowshaped";
+    else astr += "basic";
+    sprintf(sbuff,",%d",mArrowMrkSz);
+    astr += sbuff;
+    att.push_back(astr); 
+    naj++;
+  }
+  return naj;
+}
+
+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
+//--
+
+
+//++
+// Titre	Utilitaires pour choix de couleur 
+//--
+//++
+// 
+// PIColors ColNameToColor(string const & colname)
+//	Renvoie la couleur specifiee par le nom colname (methode static)
+// PIColors ColIndexToColor(string const & colname)
+//	Renvoie la couleur specifiee par le numero colidx
+//	et le flag d'inversion de la table de couleur
+//--
+
+PIColors PIGraphicAtt::ColNameToColor(string const & colname)
+{
+  if (!gratt_init_done) InitGrAttStrings();
+  GrAttColors& GrAcol = *GrAcolors;
+  GrAttColors::const_iterator itc = GrAcol.find(colname);
+  PIColors cdcol = PI_NotDefColor;
+  if (itc != GrAcol.end())  cdcol = (*itc).second;  
+  return cdcol;
+}
+
+PIColors PIGraphicAtt::ColIndexToColor(int colidx)
+{
+  if (!gratt_init_done) InitGrAttStrings();
+  if ((colidx < 0) || (colidx >= GRA_NCOLMX))  return PI_NotDefColor;
+  return GrAcolTab[colidx];
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pigratt.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigratt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigratt.h	(revision 3445)
@@ -0,0 +1,99 @@
+// 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);
+  virtual int    AttToStrings(vector<string> & att) const;
+  // 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); }
+
+  static PIColors    ColNameToColor(string const & colname);
+  static PIColors    ColIndexToColor(int colidx);
+
+protected:
+  static 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_Nov2007/SophyaPI/PI/pigrcoord.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigrcoord.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigrcoord.cc	(revision 3445)
@@ -0,0 +1,89 @@
+// 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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pigrcoord.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pigrcoord.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pigrcoord.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piimage.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piimage.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piimage.cc	(revision 3445)
@@ -0,0 +1,1719 @@
+// 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 "sopnamsp.h"
+#include "pisysdep.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <string.h>
+#include <ctype.h>
+#include <math.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>D : Affichage du menu de manipulation des traceurs (drawers)
+//	* <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 le 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);
+ mdrw->SetAxesFlags(kAxesNone);
+gvdrw = new PIElDrawer();
+AddDrawer(mdrw, true, false, false, false);
+
+SetLut(AutoLut_No, -9.e19, 9.e19, kLutType_Lin, 0, false);
+SetColMapId(CMAP_COLRJ32);
+// pour le copier-coller
+cpbuffer = NULL;
+cpbuflen = 0;
+
+// Menu pour la manipulation des drawers 
+mDrwMen = NULL;
+
+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 (mDrwMen) delete mDrwMen;
+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());
+// Reza, Aout 2007 : SetLut par defaut passe a AutoLut MeanSigma a 2 sigmas
+// a l'occasion des corrections et nouveaux types de calculs d'autolut
+  CenterPave();
+  double min=1., max=-1.;
+  SetLut(AutoLut_MeanSigma, min, max, kLutType_Lin, 2., 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 contient Refresh fait apres Show (21/08/2007)
+  // pour regler le pb de la fenetre de CutXY blanche + clic -> coredump
+  cutwin->Show();
+  UpdateCuts();
+  }
+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(AutoLutType alt, double min, double max, int typlut=kLutType_Lin, \
+//        double nsa=1., 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(AutoLutType alt, double min, double max, int typlut, double nsa, bool refr)
+{
+t_al = alt; 
+if (alt != AutoLut_No) { 
+  min_al = min; max_al = max; ns_al = nsa;
+}
+if (lut) delete(lut);
+int nbnul, nbsat;
+double moy, sig, fracmax;
+double dmx, smin, smax;
+bool fgtail;
+
+switch (alt)
+{
+ case AutoLut_No :
+   if (min >= max)  img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+   break;
+ case AutoLut_MinMax :
+   min = 1.; max = -1.;  
+   img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+   if (max <= min) max = min+0.1*fabs(min);
+   if ((nsa <= 0.)||(nsa > 1.))  nsa = 1.;
+   dmx = (nsa-1.)*(max-min);
+   min = min+dmx;  max = max-dmx;
+   break; 
+ case AutoLut_MeanSigma :
+   img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+   smin = min, smax = max;
+   min = moy - nsa*sig;   max = moy + nsa*sig;
+   if (min < smin) min = smin;
+   if (max > smax) max = smax;
+   break;
+ case AutoLut_HistoPeak :
+ case AutoLut_HistoTail :
+   fracmax = 1.-0.05*nsa;
+   if (min >= max)  img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+   fgtail = (alt == AutoLut_HistoTail) ? true : false;
+   img->ComputeLut_PicHisto(min, max, fgtail, nsa, fracmax);
+   break;
+} 
+
+if (max <= min) max = min + 0.1*fabs(min);
+lut = new LUT(min, max, NbCol(), typlut);
+
+ComputeGloVPixmap();
+if (refr) Apply();
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::SetLut(LUT *clut, bool refr)
+{
+t_al = AutoLut_No;
+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();  
+  int optsz1 = ndec;
+  bool fgcmapid=false, revcmapid=false; CMapId cmapid=CMAP_COLRJ32;
+  bool invx = false;
+  bool invy = false;
+  bool exchxy = false;
+  bool confaxes = false;
+
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    // Couleur d'arriere plan du widget
+    if (opts.substr(0,7) == "wbgcol=") {
+      vector<string> vsc;
+      vsc.push_back(opts.substr(7));
+      SetBackgroundColor(PIGraphicAtt(vsc).GetColor());
+      continue;
+    }
+    // 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;
+    }
+    // Configuration axes 
+    if (opts == "invx") {
+      invx = true;
+      confaxes = true;
+      continue;
+    }
+    if (opts == "invy") {
+      invy = true;
+      confaxes = true;
+      continue;
+    }
+    if (opts == "exchxy") {
+      exchxy = true;
+      confaxes = true;
+      continue;
+    }
+    // Changementr de lut - avec specification type de lut [et min/max] 
+    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(AutoLut_No, min, max, typlut, 0, false);
+      continue;
+    }
+    // Auto lut avec specification type auto-lut [et nb-sigmas] (Aout2007)
+    if (opts.substr(0,8) == "autolut=") {
+      double min = min_al;
+      double max = max_al;
+      int ctlut = Lut()->Type();
+      double pnsal = ns_al; 
+      size_t q = opts.find(',');
+      if (q < opts.length()-1) {
+	string suop = opts.substr(q+1);
+	size_t q2 = suop.find(','); 
+	if (q2 < suop.length()-1) 
+	  sscanf(suop.c_str(),"%lg,%lg,%lg",&pnsal,&min, &max);
+	else pnsal = atof( suop.c_str() );
+      }
+      AutoLutType palt = AutoLut_No;     
+      if (opts.substr(8,6) == "minmax")  palt = AutoLut_MinMax;
+      else if (opts.substr(8,7) == "meansig")  palt = AutoLut_MeanSigma;
+      else if (opts.substr(8,7) == "hispeak")  palt = AutoLut_HistoPeak;
+      else if (opts.substr(8,9) == "hispeak")  palt = AutoLut_HistoPeak;
+      else if (opts.substr(8,6) == "hispic")   palt = AutoLut_HistoPeak;
+      else if (opts.substr(8,7) == "histail")  palt = AutoLut_HistoTail;
+      if ( palt != AutoLut_No )  SetLut(palt, min_al, max_al, ctlut, pnsal, false);
+      continue;
+    }
+    ndec--;
+    udopt.push_back(opts);
+  }
+  // Set color map if requested
+  if(fgcmapid || revcmapid) SetColMapId(cmapid,revcmapid,false);
+  // Configure axes if requested 
+  if (confaxes) ChangeAxesConfiguration(invx, invy, exchxy, false);
+
+  // Is there any more options to decode ?
+  if (udopt.size() > 0) 
+    ndec += mdrw->DecodeOptionString(udopt, rmdecopt);
+
+
+  if (rmdecopt)  opt = udopt;
+
+  // Decodage des options par le array-adapter
+  int ndec2 = 0;
+  if ( ( optsz1-ndec > 0) && (img) ) {
+    ndec2 = img->DecodeOptionString(opt, rmdecopt);
+    // On recalcule la LUT si on est en auto-lut, le contenu de l'image peut avoir change (Aout2007)
+    if ((ndec2 > 0) && (t_al != AutoLut_No))  
+      SetLut(t_al, min_al, max_al, Lut()->Type(), ns_al, false);
+  }
+  return(ndec+ndec2);
+}
+
+
+/* --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 == 'D' || key == 'd') {  // Menu de manipulation des drawers
+    if (mDrwMen) delete mDrwMen;
+    mDrwMen = new PIDrwMgrMenu(this, true);
+    mDrwMen->Show();
+  }  
+  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) {   
+// --- cmv+rz 21/08/2007 : Correction plantage lors agrandissement fenetre , 
+  if (xwsz >= img->XSize()) offx = 0; 
+  if (ywsz >= img->YSize()) offy = 0; 
+// Fin correction cmv+rz 21/08/2007 -----
+  if (xwsz > (img->XSize()-offx)) xwsz = (img->XSize()-offx);
+  if (ywsz > (img->YSize()-offy)) ywsz = (img->YSize()-offy);
+  }
+xpav = offx+xwsz/2; 
+ypav = offy+ywsz/2; // --- cmv+rz 21/08/2007 : c'etait offx au lieu de offy
+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.);
+}
+//++
+// Class	PIImageNavigator
+// Lib		PI
+// include	piimage.h
+//
+//   	Classe regroupant un PIImage, un widget Zoom, un widget 
+//	de vue globale et un widget afficheur de colormap dans 
+//	un conteneur (PIContainer).
+//++
+// Links	Parents
+// PIContainer
+//--
+//++
+// Links	Voir aussi
+// PIImage
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+//  PIImageNavigator(PIContainerGen *par, const char *nom, int sx=0, int sy=0, int px=0, int py=0)
+//	Constructeur
+//  
+//--
+/* --Methode-- */
+PIImageNavigator::PIImageNavigator(PIContainer *par, const char *nom, 
+				  int sx, int sy, int px, int py)
+  : PIContainer(par, nom, sx, sy, px, py)
+{
+  int csx, csy;
+  int cpx, cpy,bss;
+  string name = nom;
+  name += "::";
+  string nomw = name;
+  nomw += "Navigator";
+  bss = 5; // 5 pixels
+  csx = 0.2*sx;  csy = 0.2*sy;
+  cpx = bss; cpy = bss;
+  gimv = new PIPixmap(this, nomw.c_str(), csx, csy, cpx, cpy);
+  gimv->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic, PIBK_elastic); 
+  nomw = name;
+  nomw += "Zoom";
+  cpx += (bss+csx);
+  zoom = new PIPixmap(this, nomw.c_str(), csx, csy, cpx, cpy);
+  zoom->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic, PIBK_elastic); 
+  nomw = name;
+  nomw += "ColorMap";
+  cpx = bss; cpy += (bss+csy);
+  csx = sx-2*bss;  csy = 0.2*sy*0.2;
+  cmapv = new PICMapView(this, nomw.c_str(), csx, csy, cpx, cpy);
+  cmapv->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic, PIBK_elastic); 
+  nomw = name;
+  nomw += "Image";
+  cpx = bss; cpy += (bss+csy);
+  csx = sx-2*bss;  csy = sy-bss-cpy;
+  piimg = new PIImage(this, nomw.c_str(), csx, csy, cpx, cpy);
+  piimg->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic, PIBK_elastic); 
+
+  piimg->SetZoomWin(zoom, false);
+  piimg->SetGloVWin(gimv, false);
+  piimg->SetCMapWin(cmapv, false);
+}
+
+/* --Methode-- */
+PIImageNavigator::~PIImageNavigator()
+{
+  if (piimg) delete piimg;
+  if (zoom)  delete zoom;
+  if (gimv)  delete gimv;
+  if (cmapv) delete cmapv;
+}
+
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// inline PIImage*    ImageWdg() 
+//	Acces a l'objet PIImage associe. 
+//--
Index: /tags/V_Nov2007/SophyaPI/PI/piimage.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piimage.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piimage.h	(revision 3445)
@@ -0,0 +1,230 @@
+// 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 PIDrwMgrMenu;
+
+enum AutoLutType { AutoLut_No=0, AutoLut_MinMax=1, AutoLut_MeanSigma=2, 
+		   AutoLut_HistoPeak=3, AutoLut_HistoTail=4}; 
+
+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(AutoLutType alt, double min, double max, int typlut=kLutType_Lin,
+              double nsa=1., 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;
+  AutoLutType t_al;   // Si AutoLut et le type lors du dernier appel a SetLut()
+  double min_al, max_al, ns_al; // Parametres nsa, min et max lors  du dernier appel a SetLut()
+  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;
+
+// Menu pour la manipulation des drawers 
+  PIDrwMgrMenu* mDrwMen;
+};
+
+// Classe regroupant un PIImage, Widget Zoom et Widget Naviguator
+class PIImageNavigator : public PIContainer
+{
+public:
+  enum {ClassId = 5155};
+
+                     PIImageNavigator(PIContainer *par, const char *nom, 
+                                     int sx=500, int sy=500, int px=0, int py=0);
+  virtual            ~PIImageNavigator();
+  virtual long       kind() {return ClassId; }
+
+  inline PIImage*    ImageWdg() { return piimg; }
+
+protected:
+  PIImage* piimg;
+  PIPixmap* zoom;
+  PIPixmap* gimv;
+  PICMapView* cmapv;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/piimgtools.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piimgtools.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piimgtools.cc	(revision 3445)
@@ -0,0 +1,511 @@
+// 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 "sopnamsp.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("MeanMax", 1206);
+mOpt[1]->AppendItem("MeanMax90%", 1205);
+mOpt[1]->AppendItem("MeanMax70%", 1204);
+mOpt[1]->AppendItem("MeanSig 3", 1203);
+mOpt[1]->AppendItem("MeanSig 2", 1202);
+mOpt[1]->AppendItem("MeanSig 1", 1201);
+mOpt[1]->AppendItem("NoAuto", 1200);
+mOpt[1]->AppendItem("HistoTail+1s", 1207);
+mOpt[1]->AppendItem("HistoTail+2s", 1208);
+mOpt[1]->AppendItem("HistoPeak+1s", 1209);
+mOpt[1]->AppendItem("HistoPeak+2s", 1210);
+mOpt[1]->SetValue(1200);
+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(), "PIUniCol32");
+mCasc[2] = new PIMenu(mOptzc[0]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3,nsct4;
+//  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]);
+nsct3 = 16;  // Les 7 tables de couleurs uniforme
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOptzc[0]->AppendPDMenu(mCasc[1]);
+//  Apres les tables importees de MIDAS
+nsct4 = PIColorMap::NumberStandardColorMaps()-2; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct3; kcc<nsct4; kcc++) 
+  mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOptzc[0]->AppendPDMenu(mCasc[2]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct4; 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} ; 
+AutoLutType alts[11] = { AutoLut_No, 
+			 AutoLut_MeanSigma, AutoLut_MeanSigma, AutoLut_MeanSigma,
+			 AutoLut_MinMax, AutoLut_MinMax, AutoLut_MinMax, 
+			 AutoLut_HistoTail, AutoLut_HistoTail, 
+			 AutoLut_HistoPeak, AutoLut_HistoPeak } ; 
+double nsas[11] = {0., 1., 2., 3., 0.70, 0.9, 1., 2., 1., 2.};
+ 
+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;
+    if ((lauto < 0) || (lauto > 10))  lauto = 10;
+    typ = mOpt[0]->GetValue() - 1100;
+    if ( (typ < 0) || (typ > 3) )  typ = 0;
+    (PIImage::CurrentPIImage())->SetLut(alts[lauto], min, max, typlut[typ], nsas[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_Nov2007/SophyaPI/PI/piimgtools.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piimgtools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piimgtools.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pilineatt.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilineatt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilineatt.cc	(revision 3445)
@@ -0,0 +1,158 @@
+// 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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pilineatt.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilineatt.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilineatt.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pilistgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilistgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilistgen.cc	(revision 3445)
@@ -0,0 +1,83 @@
+// Module PI : Peida Interactive     PIList
+// Liste                                     96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pilistgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilistgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilistgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pilistx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilistx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilistx.cc	(revision 3445)
@@ -0,0 +1,423 @@
+#include<stdio.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pilistx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pilistx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pilistx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimak
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimak	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimak	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimenubargen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenubargen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenubargen.cc	(revision 3445)
@@ -0,0 +1,55 @@
+// Module PI : Peida Interactive     PIMenubar
+// Barre de menu                        96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pimenubargen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenubargen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenubargen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimenubarx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenubarx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenubarx.cc	(revision 3445)
@@ -0,0 +1,113 @@
+#include<stdio.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pimenubarx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenubarx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenubarx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimenugen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenugen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenugen.cc	(revision 3445)
@@ -0,0 +1,124 @@
+// Module PI : Peida Interactive     PIMenu
+// Menu                                     96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pimenugen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenugen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenugen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimenux.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenux.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenux.cc	(revision 3445)
@@ -0,0 +1,502 @@
+#include<stdio.h>
+#include<iostream>
+
+#include "sopnamsp.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.subwindow = None;
+evt.root = rw;
+evt.x_root = xr;
+evt.y_root = yr; 
+evt.x = px;
+evt.y = py;
+evt.serial = PIXGetLastEventSerial(); 
+// evt.time = PIXGetLastEventTime();
+PIXGetLastEventInfo(evt.state, evt.time);
+evt.button = 1;
+// evt.state = 0;
+evt.send_event = False;
+evt.same_screen = True;
+//cout << " XmMenuPosition-DBG xr,yr= " << xr << "," << yr 
+//     << " x,y=" << px << "," << py << endl;
+XmMenuPosition(XtWdg(), &evt);
+// SetPos(xr, yr);
+Manage();
+return;    
+}
+
+
+
+
Index: /tags/V_Nov2007/SophyaPI/PI/pimenux.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimenux.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimenux.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pimsghandler.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimsghandler.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimsghandler.cc	(revision 3445)
@@ -0,0 +1,102 @@
+//  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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pimsghandler.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pimsghandler.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pimsghandler.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pioptmenugen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pioptmenugen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pioptmenugen.cc	(revision 3445)
@@ -0,0 +1,67 @@
+// Module PI : Peida Interactive     PIOptMenu
+// Menu a option                                96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pioptmenugen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pioptmenugen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pioptmenugen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pioptmenux.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pioptmenux.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pioptmenux.cc	(revision 3445)
@@ -0,0 +1,181 @@
+#include<stdio.h>
+
+#include <Xm/Xm.h>
+#include <Xm/PushB.h>
+
+#include "sopnamsp.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();
+if (finishDone) FinishCreate();
+}
+
+
+/* --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_Nov2007/SophyaPI/PI/pioptmenux.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pioptmenux.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pioptmenux.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piperiodx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piperiodx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piperiodx.cc	(revision 3445)
@@ -0,0 +1,82 @@
+// Module PI : Peida Interactive     PIPeriodX
+// Classe d'objets periodiques - X11 - R. Ansari 96-98
+// LAL (Orsay) / IN2P3-CNRS    DAPNIA/CEA (Saclay)      
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/piperiodx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piperiodx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piperiodx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pipixmapgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipixmapgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipixmapgen.cc	(revision 3445)
@@ -0,0 +1,156 @@
+// 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 "sopnamsp.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_Nov2007/SophyaPI/PI/pipixmapgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipixmapgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipixmapgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pipixmapx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipixmapx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipixmapx.cc	(revision 3445)
@@ -0,0 +1,175 @@
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pipixmapx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipixmapx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipixmapx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pipplist.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipplist.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipplist.cc	(revision 3445)
@@ -0,0 +1,199 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pipplist.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pipplist.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pipplist.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pippmenubar.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippmenubar.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippmenubar.cc	(revision 3445)
@@ -0,0 +1,45 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pippmenubar.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippmenubar.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippmenubar.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pippoptmenu.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippoptmenu.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippoptmenu.cc	(revision 3445)
@@ -0,0 +1,68 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pippoptmenu.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippoptmenu.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippoptmenu.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pippviewadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippviewadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippviewadapter.cc	(revision 3445)
@@ -0,0 +1,129 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pippviewadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pippviewadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pippviewadapter.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piscdrawwdg.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piscdrawwdg.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piscdrawwdg.cc	(revision 3445)
@@ -0,0 +1,685 @@
+// Module PI : Peida Interactive     PIScDrawWdg
+// Gestionnaire Drawer-2D  E.Aubourg, R. Ansari  96-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <math.h>
+#include <iostream>
+
+#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>D : Affichage du menu de manipulation des traceurs (drawers)
+//	* <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, bool lock=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(kAxesDflt);
+  FreeLimits();
+  xEndDrag = yEndDrag = xBegDrag = yBegDrag = 0;
+  AddDrawer(mBDrw, true, false, false, true);
+
+//  Pour afficher les coordonnees courante (click-bouton-1)  
+  mTrlb = mTxw = NULL;
+  mTrW = NULL;
+  SetTextWin(NULL);
+
+//  Affichage eventuelle d'infos-texte
+  mInfoW = NULL;
+  mInfoTxt = NULL;
+
+// Menu pour la manipulation des drawers 
+  mDrwMen = 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
+  if (mDrwMen) delete mDrwMen;
+}
+
+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 == 'T' || key == 't') { // fenetre des options texte
+    PIDrawer* actdrw = GetActiveDrawer();
+    if (actdrw != NULL) PIDrwOptionStringWindow::ShowDrwOptionStringWindow(actdrw);
+  }
+  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 == 'D' || key == 'd') {  // Menu de manipulation des drawers
+    if (mDrwMen) delete mDrwMen;
+    mDrwMen = new PIDrwMgrMenu(this, true);
+    mDrwMen->Show();
+  }  
+  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.08, 0.08, 0.92, 0.92, 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];
+    // Couleur d'arriere plan du widget
+    if (opts.substr(0,7) == "wbgcol=") {
+      vector<string> vsc;
+      vsc.push_back(opts.substr(7));
+      SetBackgroundColor(PIGraphicAtt(vsc).GetColor());
+      continue;
+    }
+    // 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 (stdaxes boxaxesgrid ...) sont decodes par PIElDrawer
+
+    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, bool lock)
+{
+  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, lock));
+}
+
+
+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)
+{
+  PIKeyModifier kmod;
+  unsigned long tm;
+  GetLastEventInfo(kmod, tm);
+  // cmv+rz 21/08/2007 : pour eviter le plantage suite pb d'evenement eXpose non delivre par 
+  // le serveur X (x.org) sous Linux - 
+  if (mBDrw->GetGraphicUC() == NULL)  Refresh();
+  // ----- Fin modif du 21/08/2007   
+  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)
+{
+  // cmv+rz 21/08/2007 : On rafraichit la fenetre si d'evenement eXpose non delivre  
+  if (mBDrw->GetGraphicUC() == NULL)  Refresh();
+  // ----- Fin modif du 21/08/2007   
+  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)
+{
+  // cmv+rz 21/08/2007 : On rafraichit la fenetre si d'evenement eXpose non delivre  
+  if (mBDrw->GetGraphicUC() == NULL)  Refresh();
+  // ----- Fin modif du 21/08/2007   
+  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_Nov2007/SophyaPI/PI/piscdrawwdg.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piscdrawwdg.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piscdrawwdg.h	(revision 3445)
@@ -0,0 +1,134 @@
+// 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 PIDrwMgrMenu;
+
+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=kAxesDflt);
+
+  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, bool lock=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;
+
+// Menu pour la manipulation des drawers 
+  PIDrwMgrMenu* mDrwMen;
+
+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_Nov2007/SophyaPI/PI/pistdwdggen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistdwdggen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistdwdggen.cc	(revision 3445)
@@ -0,0 +1,288 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pistdwdggen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistdwdggen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistdwdggen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pistdwdgx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistdwdgx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistdwdgx.cc	(revision 3445)
@@ -0,0 +1,707 @@
+#include<stdlib.h>
+#include<string.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/pistdwdgx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistdwdgx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistdwdgx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pistzwin.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistzwin.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistzwin.cc	(revision 3445)
@@ -0,0 +1,374 @@
+// 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 "sopnamsp.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_Nov2007/SophyaPI/PI/pistzwin.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pistzwin.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pistzwin.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pisurfdr.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pisurfdr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pisurfdr.cc	(revision 3445)
@@ -0,0 +1,317 @@
+// 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 "sopnamsp.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);
+
+  aScxy = asxy;
+  aScz = asz;
+
+  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;
+//  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;
+  ComputeScaleFactor(mXmin, mXmax, mYmin, mYmax, mZmin, mZmax, 
+		     aScxy, aScz, mScy, mScz);
+  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), mScx, mScy, mScz);
+
+//  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 = ScaleX(mXmax-mXmin)/xsz; 
+  dy = ScaleY(mYmax-mYmin)/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 = ScaleX(x); x += dx/2.;
+      y = ScaleY(y); y += dy/2.;
+      ijzp[k].zh = mArr->Value(i,j);
+      z = ScaleZ(ijzp[k].zh);
+      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 = ScaleZ(z/4.);        
+//      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 = ScaleX(x); 
+     y = ScaleY(y); 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 = ScaleZ(z/4.);
+//     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 = ScaleX(x); x += dx;
+     y = ScaleY(y); 
+     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 = ScaleZ(z/4.);
+//     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 = ScaleX(x); x += dx;
+  y = ScaleY(y); y += dy;
+  z = mArr->Value(i-1,j-1) + mArr->Value(i1,j-1) + mArr->Value(i1,j1) +  mArr->Value(i-1,j1);
+  z = ScaleZ(z/4.);
+//  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
+    bool revcm = false;
+    PIColorMap* cmap = new PIColorMap(GetGraphicAtt().GetColMapId(revcm));
+    cmap->ReverseColorIndex(revcm);
+    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;
+}
+
+/* --Methode-- */
+int PISurfaceDrawer::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  int optsz1 = opt.size();
+  if(optsz1<1) return(0); 
+  int ndec1 = PIDrawer3D::DecodeOptionString(opt, rmdecopt);
+  if(optsz1-ndec1<1) return(ndec1);  // si tout a ete decode
+  // Decodage des options par le array-adapter
+  int ndec2 = 0;
+  if ( ( optsz1-ndec1 > 0) && (mArr) ) {
+    ndec2 = mArr->DecodeOptionString(opt, rmdecopt);
+  }
+  return(ndec1+ndec2);
+}
+
+/* --Methode-- */
+int PISurfaceDrawer::OptionToString(vector<string> & opt) const
+{
+  PIDrawer3D::OptionToString(opt);
+  if (mArr) mArr->OptionToString(opt);
+  return 1;
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pisurfdr.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pisurfdr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pisurfdr.h	(revision 3445)
@@ -0,0 +1,38 @@
+// 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); 
+
+/* --- Juin 2004 : decodage des options mis ds PIDrawer3D 
+       Jan 2007 : reactive pour decoder les options du P2DArrayAdapter* mArr  ---  */
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual int        OptionToString(vector<string> & opt) const;
+//   Texte d'aide des options disponibles
+//-- Celui de PIDrawer3D (Juin04/Jan07)  virtual void       GetOptionsHelpInfo(string& info);
+
+protected :
+  P2DArrayAdapter* mArr;
+  bool mAda;
+  double mXmin, mXmax;
+  double mYmin, mYmax;
+  double mZmin, mZmax;
+  LUT* mLut;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/pisysdep.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pisysdep.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pisysdep.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pitherm.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pitherm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pitherm.cc	(revision 3445)
@@ -0,0 +1,207 @@
+// Module PI : Peida Interactive   PIThermometer
+// Thermometre                   R. Ansari  05/00
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/pitherm.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pitherm.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pitherm.h	(revision 3445)
@@ -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 = 5220};
+
+                  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_Nov2007/SophyaPI/PI/pitxtdrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pitxtdrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pitxtdrw.cc	(revision 3445)
@@ -0,0 +1,166 @@
+// Module PI : Peida Interactive  PIBarGraph
+// Drawer Y=f(X)      R. Ansari  2004
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <iostream>
+#include "pitxtdrw.h"
+
+// --------------------------------------------------------------------------
+// ----------------------------------------------------------
+//  Classe de representation d'une serie de lignes de texte
+//  eventuellement avec marker ( et bout de ligne <- pas fait) 
+// ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+//++
+// Class	PITextDrawer
+// Lib		PI
+// include	pitxtdrw.h
+//
+//	Classe de representation d'une serie de lignes eventuellement
+//	avec un marker 
+//
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur
+// PITextDrawer::PITextDrawer()
+//--
+
+
+/* --Methode-- */
+PITextDrawer::PITextDrawer(bool fgframe)
+    : PIDrawer()
+{
+  fgFrame = fgframe;
+  GetGraphicAtt().SetColAtt(PI_Black, PI_White);
+  GetGraphicAtt().SetFontAtt(PI_DefaultFont, PI_NormalSizeFont, PI_RomanFont);
+  GetGraphicAtt().SetLineAtt(PI_NormalLine);
+  SetName("TextDrw");
+} 
+
+/* --Methode-- */
+PITextDrawer::~PITextDrawer()
+{
+}
+
+/* --Methode-- */
+int PITextDrawer::AddLine(string const& line_, PIGraphicAtt const& att_)
+{
+  struct _ldata ld;
+  ld.line = line_;
+  ld.att = att_;
+  mLines.push_back(ld);
+  return mLines.size();
+}
+
+/* --Methode-- */
+int PITextDrawer::AddLine(string const& line)
+{
+  PIGraphicAtt gatt;
+  return AddLine(line, gatt);
+}
+
+/* --Methode-- */
+void PITextDrawer::UpdateLimits()
+{
+  double xmin, xmax, ymin, ymax;
+  xmin = ymin = 0.; xmax = ymax = 1.;
+
+  PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+  PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+  SetLimits(xmin,xmax,ymin,ymax);
+  //  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);  Ne pas faire - Reza 05/04->11/99
+}
+
+
+/* --Methode-- */
+void PITextDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  if ((mLines.size() < 1) && !fgFrame) return;
+  PIGraphicAtt siatt = GetGraphicAtt();
+  PIGraphicAtt catt;
+
+  PIGrCoord x,y,ym,dx,dy,fa,fd;
+  x = 0.05;   y = 0.95;
+  for(unsigned int k=0; k<mLines.size(); k++) { 
+    catt = siatt;
+    catt.UpdateFrom(mLines[k].att);
+    SetGraphicAtt(catt);
+    SelGraAtt(g);
+    if (mLines[k].att.GetMarker() != PI_NotDefMarker) {
+      ym = (double)y-(double)(g->GetFontHeight(fa, fd))*0.5;
+      g->DrawMarker(x, ym);
+      double dxu, dyu;
+      double dxpix = g->GetMarkerSize();
+      g->DGrC2UC(dxpix, 0, dxu, dyu);
+      x = (double)x+dxu+0.02;
+    }
+    // Trace des lignes de texte
+    g->DrawString(x,y,mLines[k].line.c_str(),PI_VerticalTop);
+    y = (double)y-(double)(g->GetFontHeight(fa, fd))*1.1;
+  }
+  SetGraphicAtt(siatt);
+  if (fgFrame) {   // Trace de cadre
+    SelGraAtt(g);
+    x = y = 0.;
+    dx = dy = 1.;
+    g->DrawBox(x,y,dx, dy);
+  }
+}
+
+
+/* --Methode-- */
+int PITextDrawer::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=="frame") SetFrameFlag(true);
+    else if (opts=="noframe") SetFrameFlag(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);  
+}
+
+/* --Methode-- */
+int PITextDrawer::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+ if(fgFrame) opt.push_back("frame"); else opt.push_back("noframe");
+ return 1;
+}
+
+/* --Methode-- */
+void PITextDrawer::GetOptionsHelpInfo(string& info)
+{
+info += " ---- PITextDrawer options help info : \n" ;
+info += "  frame,noframe: enable/disable frame drawing\n";
+info += " --- + Usual line font color attribute decoding)  \n";
+PIDrawer::GetOptionsHelpInfo(info);
+return;
+}
Index: /tags/V_Nov2007/SophyaPI/PI/pitxtdrw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pitxtdrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pitxtdrw.h	(revision 3445)
@@ -0,0 +1,41 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PITextDrawer
+// Multi Line Text Drawer            R. Ansari  2004
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PITEXTDRAWER
+#define PITEXTDRAWER
+
+#include "pisysdep.h"
+#include "pidrawer.h"
+#include <vector>
+#include <string>
+
+// ----------------------------------------------------------
+// Classe de representation de lignes de texte 
+// (+marker et ligne) 
+ 
+class PITextDrawer : public PIDrawer {
+public:
+                     PITextDrawer(bool fgframe=false);
+  virtual            ~PITextDrawer();
+
+  int                AddLine(string const& line, PIGraphicAtt const& att);
+  int                AddLine(string const& line);
+  inline void        SetFrameFlag(bool fgf) {fgFrame = fgf; }
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);  
+  virtual int        OptionToString(vector<string> & opt) const;
+  virtual void	     GetOptionsHelpInfo(string& info);
+    
+protected:
+  struct _ldata { string line; PIGraphicAtt att; };
+  vector<struct _ldata> mLines;
+  bool fgFrame;
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/piup.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piup.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piup.cc	(revision 3445)
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/piup.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piup.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piup.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piup_def.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piup_def.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piup_def.cc	(revision 3445)
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sopnamsp.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_Nov2007/SophyaPI/PI/piupdattachment.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piupdattachment.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piupdattachment.cc	(revision 3445)
@@ -0,0 +1,105 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/piupdattachment.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piupdattachment.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piupdattachment.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piusmak
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piusmak	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piusmak	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piversion.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piversion.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piversion.h	(revision 3445)
@@ -0,0 +1,6 @@
+#ifndef PIVERSION_H_SEEN
+#define PIVERSION_H_SEEN
+
+#define PI_VERSIONNUMBER  4.10
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/piwdggen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwdggen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwdggen.cc	(revision 3445)
@@ -0,0 +1,432 @@
+//  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 "sopnamsp.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  OptionToString(vector<string> & opt) const
+//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
+//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
+//	Renvoie le nombre d'éléments ajoutés.
+//--
+
+int PIWdgGen::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  return(0);
+}
+int PIWdgGen::OptionToString(vector<string> & opt) const
+{
+  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_Nov2007/SophyaPI/PI/piwdggen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwdggen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwdggen.h	(revision 3445)
@@ -0,0 +1,155 @@
+// 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);
+//   Remplissage de chaine decodable par DecodeOptionString() a partir des options
+  virtual int            OptionToString(vector<string> & opt) const;
+
+//  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_Nov2007/SophyaPI/PI/piwdgx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwdgx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwdgx.cc	(revision 3445)
@@ -0,0 +1,1224 @@
+#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 "sopnamsp.h"
+#include "piwdgx.h"
+#include "picontainerx.h"
+#include "pievthandler.h"
+#include "pigraphx.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "perrors.h"
+#else
+#include "pexceptions.h"
+#endif
+
+
+// #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
+if (nom) printf("Debug_PIWdgX::CreateXtWdg(%s) Getting in \n", nom);
+else printf("Debug_PIWdgX::CreateXtWdg(NULL) 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()
+// Doit pouvoir etre appele plusieurs fois
+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);
+*/
+/*  Modifs Reza Avril 2007, remplacement par XtMakeGeometryRequest 
+XtResizeWidget(sdw, sx, sy, BorderWidth());
+*/
+XtWidgetGeometry wgeom;
+wgeom.request_mode = CWWidth|CWHeight;
+wgeom.width = sx;
+wgeom.height = sy;
+XtMakeGeometryRequest(sdw, &wgeom, NULL);
+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);
+*/
+/*  Modifs Reza Avril 2007, remplacement par XtMakeGeometryRequest 
+XtMoveWidget(sdw, px, py);
+*/
+XtWidgetGeometry wgeom;
+wgeom.request_mode = CWX|CWY;
+wgeom.x = px;
+wgeom.y = py;
+XtMakeGeometryRequest(sdw, &wgeom, NULL);
+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), 
+                          sessionShellWidgetClass, NULL, 0);
+// Reza, Avril 2007 : applicationShell remplace par sessionShell  
+//                    doc Lesstif dit que applicationShell est obsolete
+//                        applicationShellWidgetClass, NULL, 0);
+
+if (top == NULL) {
+  fprintf(stderr, "PIWdgX::InitXt()/ Error XtVaAppInitialize()\n");
+#ifdef SANS_EVOLPLANCK
+  throw notFoundErr;
+#else
+  throw NotFoundExc("PIWdgX::InitXt()/ Error XtVaAppInitialize()");
+#endif
+  }
+dpy = XtDisplay(top);
+if (dpy == NULL)  {
+  fprintf(stderr, "PIWdgX::InitXt()/ Error XtVaAppInitialize()/DisplayConnection\n");
+#ifdef SANS_EVOLPLANCK
+  throw notFoundErr;
+#else
+  throw NotFoundExc("PIWdgX::InitXt()/ Error XtVaAppInitialize()/DisplayConnection");
+#endif
+  }
+
+/*  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);
+if (mDHlist.size() == 1)
+  XtInsertEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this, XtListTail);
+}
+
+/* --Methode-- */
+void PIWdgX::RemoveDrawHandler(PIEventHandler* drwh)
+{
+PIWdgGen::RemoveDrawHandler(drwh);
+if (mDHlist.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);
+//cout << "DBG-PIWdgX::RemoveEventHandler( " << hex << evh << dec << ") mEHlist.size()="
+//      << mEHlist.size() << endl;
+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)
+{
+//cout << "DBG-PIWdgX:CallEventHandlers() - mEHlist.size()=" << mEHlist.size() << endl;
+PIEventHandler* eh;
+list<EvHand>::iterator it;
+// On fait d'abord une copie pour eviter les problemes
+// lies a l'ajout ou la supression d'event-handler par un ProcessEvent()
+list<EvHand> cEHlist;
+for(it= mEHlist.begin(); it != mEHlist.end(); it++) { 
+  if (!((*it).mask & evt))  continue; 
+  cEHlist.push_back(*it);
+}
+// Et on refait la boucle sur la liste copiee ...
+for(it= cEHlist.begin(); it != cEHlist.end(); it++) { 
+  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_Nov2007/SophyaPI/PI/piwdgx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwdgx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwdgx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piwindowgen.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwindowgen.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwindowgen.cc	(revision 3445)
@@ -0,0 +1,111 @@
+//  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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PI/piwindowgen.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwindowgen.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwindowgen.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piwindowx.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwindowx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwindowx.cc	(revision 3445)
@@ -0,0 +1,168 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include "sopnamsp.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()));
+  // cmv+rz 09/08/2007 Ajout XFlush() + usleep 
+  // pour regler le probleme de  perte d'evenement expose a la creation
+  XFlush(mdsp);   usleep(5000);
+return;
+}
+
+/* --Methode-- */
+void PIWindowX::Hide()
+{
+PIWindowGen::Hide();
+// UnManage();  $CHECK$ Ca ne doit plus etre necessaire Reza 9/7/97
+pwm->UnManage();
+}
+
+
Index: /tags/V_Nov2007/SophyaPI/PI/piwindowx.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piwindowx.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piwindowx.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pixtbase.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pixtbase.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pixtbase.cc	(revision 3445)
@@ -0,0 +1,363 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#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; }
+
+/* Gestion de variable d'environnement pour choix Mod1Mask ou Mod2Mask */
+static bool fgenv_kb_modmasks = false;
+static int  sel_kb_modmasks = 3;  // Nov 2007: On passe le defaut a 3, au lieu de 1
+
+/* Nouvelle-Fonction */
+static void init_class_pixtbase()
+{
+// Pour le choix Mod1Mask OU Mod2mask OU ( Mod1Mask | Mod2mask )
+// Il faut en particulier Mod2Mask sur serveur X11/MacOSX (touche pomme)
+//                      Reza / Septembre 2003
+// Var. Env  PIXKBMODMASK   =2 -> Mod2Mask
+//                          =3 -> Mod1Mask | Mod2Mask
+//                          =0 -> Pas de ModMask
+//                          =autre -> Mod1Mask (defaut) 
+if ( !fgenv_kb_modmasks ) {
+  char *envmodmask = getenv("PIXKBMODMASK");
+  if (envmodmask) {
+    if (envmodmask[0] == '0')  sel_kb_modmasks = 0;
+    else if (envmodmask[0] == '1')  sel_kb_modmasks = 1;
+    else if (envmodmask[0] == '2')  sel_kb_modmasks = 2;
+    else if (envmodmask[0] == '3')  sel_kb_modmasks = 3;
+    else sel_kb_modmasks = 1;
+  }
+}
+#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);
+    // Choix Mod1Mask Et/Ou Mod2Mask par variable sel_kb_modmasks
+    //                      Reza / Septembre 2003
+    if ((sel_kb_modmasks == 1) && (evt->xkey.state & Mod1Mask) )
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    if ((sel_kb_modmasks == 2) && (evt->xkey.state & Mod2Mask) )
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    if ((sel_kb_modmasks == 3) && 
+	((evt->xkey.state & Mod1Mask) || (evt->xkey.state & Mod2Mask)) )
+      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)  (((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_Nov2007/SophyaPI/PI/pixtbase.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pixtbase.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pixtbase.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/pixtbaseP.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/pixtbaseP.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/pixtbaseP.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/piyfxdrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piyfxdrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piyfxdrw.cc	(revision 3445)
@@ -0,0 +1,277 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <iostream>
+#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";
+  NptDraw = 0;
+} 
+
+/* --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);
+  // NE PAS FAIRE - Reza Mai 2005  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+}
+
+
+/* --Methode-- */
+void PIYfXDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  double xp,yp;
+  int i;
+
+  if (axesFlags != kAxesNone) DrawAxes(g);
+
+  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;
+  NptDraw=0;
+
+//  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);
+      NptDraw++;
+    }
+  }
+
+  if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)    return;
+
+// Trace des lignes 
+  NptDraw=0;
+  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);
+    NptDraw++;
+  }
+
+}
+
+
+/* --Methode-- */
+double PIYfXDrawer::GetDistanceToPoint(double x, double y)
+{
+ if(mSz<=0)  return 1.e+9;
+
+ const int nessai = 100;
+ long inc = (NptDraw>nessai) ? (long)(NptDraw/nessai)+1 : 1;
+
+ double dist = -1.e+18;
+ long n = 0;
+ for(long i=0; i<mSz; i++) {
+   double xp,yp;
+   if(mAy) {xp=mAx->Value(i); yp=mAy->Value(i);}
+     else  {xp=mAx->X(i);     yp=mAx->Value(i);}
+   if(xp<XMin() || xp>XMax()) continue;
+   if(yp<YMin() || yp>YMax()) continue;
+   if(n%inc==0) {
+     xp = (xp-x)/(XMax()-XMin())/0.5;
+     yp = (yp-y)/(YMax()-YMin())/0.5;
+     xp = xp*xp+yp*yp;
+     if(dist<0. || xp<dist) dist = xp;
+   }
+   n++;
+ }
+ dist=sqrt(fabs(dist));
+ //cout<<"PIYfXDrawer: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
+ //    <<" mSz="<<mSz<<" inc="<<inc<<endl;
+ //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<" NptDraw="<<NptDraw<<endl;
+
+ return dist;
+}
+
+
+
+
+
+//================================================================
+// 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;
+  }
+}
+
+
+/* --Methode-- */
+double PIFuncDrawer::GetDistanceToPoint(double x, double y)
+{
+ if(mFunc==NULL) return 1.e+9;
+
+ double xStep = (XMax()-XMin())/50;
+ double dist = -1.e+18;
+ for(double xx=XMin()+xStep; xx<XMax(); xx+=xStep) {
+   double xp = (xx-x)/(XMax()-XMin())/0.5;
+   double yp = (mFunc(xp)-y)/(YMax()-YMin())/0.5;
+   xp = xp*xp+yp*yp;
+   if(dist<0. || xp<dist) dist = xp;
+ }
+ dist=sqrt(fabs(dist));
+ //cout<<"PIFuncDrawer: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()<<endl;
+ //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<endl;
+
+ return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PI/piyfxdrw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/piyfxdrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/piyfxdrw.h	(revision 3445)
@@ -0,0 +1,57 @@
+// 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();
+  
+ // Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+
+protected:
+  P1DArrayAdapter* mAx;
+  P1DArrayAdapter* mAy;
+  int mSz;
+  bool mAdDO;
+  long NptDraw; // nombre de points effectivement dessines dans la fenetre
+};
+
+// ----------------------------------------------------------
+// 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);
+
+ // Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+
+protected:
+  FUNC               mFunc;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PI/psfile.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/psfile.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/psfile.cc	(revision 3445)
@@ -0,0 +1,1445 @@
+/*
+ *   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 "sopnamsp.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_SkyBlue, PI_RoyalBlue, PI_ForestGreen, \
+  PI_OrangeRed, PI_Brown, PI_HighlightBlue, \
+  \
+  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  {1.000 1.000 1.000 setrgbcolor} bind def %% PI_White\n\
+/C%-2d  {0.824 0.824 0.824 setrgbcolor} bind def %% PI_Grey\n\
+/C%-2d  {1.000 0.0   0.0   setrgbcolor} bind def %% PI_Red\n\
+/C%-2d  {0.0   0.0   1.000 setrgbcolor} bind def %% PI_Blue\n\
+/C%-2d  {0.0   1.000 0.0   setrgbcolor} bind def %% PI_Green\n\
+/C%-2d  {1.000 1.000 0.0   setrgbcolor} bind def %% PI_Yellow\n\
+/C%-2d  {1.000 0.0   1.000 setrgbcolor} bind def %% PI_Magenta\n\
+/C%-2d  {}                              bind def %% PI_NotDefColor\n\
+/C%-2d  {0.0   1.000 1.000 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  {1.000 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  {1.000 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\
+/C%-2d  {0.530 0.805 0.920 setrgbcolor} bind def %% PI_SkyBlue\n\
+/C%-2d  {0.255 0.410 0.880 setrgbcolor} bind def %% PI_RoyalBlue\n\
+/C%-2d  {0.135 0.545 0.135 setrgbcolor} bind def %% PI_ForestGreen\n\
+/C%-2d  {1.000 0.270 0.000 setrgbcolor} bind def %% PI_OrangeRed\n\
+/C%-2d  {0.647 0.165 0.165 setrgbcolor} bind def %% PI_Brown\n\
+/C%-2d  {0.600 0.750 1.000 setrgbcolor} bind def %% PI_HighlightBlue\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 newpath\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 newpath\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 ; 
+}
+
+
+/* fonction pour rajouter \ devant ( ) et \ pour string postscript */
+static char * EscapePSString(const char *s)
+{
+  int nce = 0;
+  int ls = strlen(s);
+  int i,j,k;
+  for(int k=0; k<ls; k++) 
+    if ( (s[k] == '(') || (s[k] == ')') || (s[k] == '\\') ) nce++;
+  if (nce == 0) return NULL;
+  char * es = new char[ls+nce+1];
+  j = 0;
+  for(int k=0; k<ls; k++) {
+    if ( (s[k] == '(') || (s[k] == ')') || (s[k] == '\\') ) {
+      es[j] = '\\';  j++; 
+    }
+    es[j] = s[k];  j++;
+  }
+  es[j] = '\0';
+  return es;
+}
+
+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
+    }
+    /* Les () et \ doivent avoir le caractere escape \ dans les chaines postscript */
+    char * es = EscapePSString(s);
+    const char * epss = s;
+    if (es != NULL) epss = es;
+    if (pos == 0) 
+      fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) S gr\n", x, y, epss) ; 
+    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, epss) ;
+	else 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) hlshstr gr\n", 
+		  x, y, angle, epss) ;
+      }
+      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, epss, sshp) ;
+	  else fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cshstr gr\n", 
+		       x, y, angle, epss, 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, epss, sshp, ssvp) ; 
+	else 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cv%cshstr gr\n", 
+		  x, y, angle, epss, sshp, ssvp) ; 
+      }
+    }
+
+    if (es) delete[] es;  /* chaine modifiee avec des \( \) ou \\ */    
+    return;
+}
+
+
+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_Nov2007/SophyaPI/PI/psfile.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/psfile.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/psfile.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libPI.so
Index: /tags/V_Nov2007/SophyaPI/PI/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/smakefile	(revision 3445)
@@ -0,0 +1,506 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPI.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)lut.o $(SOPHYAOBJP)parradapter.o $(SOPHYAOBJP)pi3ddrw.o $(SOPHYAOBJP)pi3dwdg.o $(SOPHYAOBJP)piapplgen.o $(SOPHYAOBJP)piapplx.o $(SOPHYAOBJP)piaxes.o $(SOPHYAOBJP)piaxestools.o $(SOPHYAOBJP)pibargraph.o $(SOPHYAOBJP)pibwdggen.o $(SOPHYAOBJP)pibwdgx.o $(SOPHYAOBJP)picmap.o $(SOPHYAOBJP)picmapgen.o $(SOPHYAOBJP)picmapview.o $(SOPHYAOBJP)picmapx.o $(SOPHYAOBJP)picons.o $(SOPHYAOBJP)picontainergen.o $(SOPHYAOBJP)picontainerx.o $(SOPHYAOBJP)pidrawer.o $(SOPHYAOBJP)pidrawwin.o $(SOPHYAOBJP)pidrwtools.o $(SOPHYAOBJP)pieldrw.o $(SOPHYAOBJP)pierrdisp.o $(SOPHYAOBJP)pievthandler.o $(SOPHYAOBJP)pifilechogen.o $(SOPHYAOBJP)pifilechox.o $(SOPHYAOBJP)pifontgen.o $(SOPHYAOBJP)pifontx.o $(SOPHYAOBJP)pigraph3d.o $(SOPHYAOBJP)pigraphgen.o $(SOPHYAOBJP)pigraphps.o $(SOPHYAOBJP)pigraphuc.o $(SOPHYAOBJP)pigraphx.o $(SOPHYAOBJP)pigratt.o $(SOPHYAOBJP)pigrcoord.o $(SOPHYAOBJP)piimage.o $(SOPHYAOBJP)piimgtools.o $(SOPHYAOBJP)pilineatt.o $(SOPHYAOBJP)pilistgen.o $(SOPHYAOBJP)pilistx.o $(SOPHYAOBJP)pimenubargen.o $(SOPHYAOBJP)pimenubarx.o $(SOPHYAOBJP)pimenugen.o $(SOPHYAOBJP)pimenux.o $(SOPHYAOBJP)pimsghandler.o $(SOPHYAOBJP)pioptmenugen.o $(SOPHYAOBJP)pioptmenux.o $(SOPHYAOBJP)piperiodx.o $(SOPHYAOBJP)pipixmapgen.o $(SOPHYAOBJP)pipixmapx.o $(SOPHYAOBJP)pipplist.o $(SOPHYAOBJP)pippmenubar.o $(SOPHYAOBJP)pippoptmenu.o $(SOPHYAOBJP)pippviewadapter.o $(SOPHYAOBJP)piscdrawwdg.o $(SOPHYAOBJP)pistdwdggen.o $(SOPHYAOBJP)pistdwdgx.o $(SOPHYAOBJP)pistzwin.o $(SOPHYAOBJP)pisurfdr.o $(SOPHYAOBJP)pitherm.o $(SOPHYAOBJP)pitxtdrw.o $(SOPHYAOBJP)piup.o $(SOPHYAOBJP)piup_def.o $(SOPHYAOBJP)piupdattachment.o $(SOPHYAOBJP)piwdggen.o $(SOPHYAOBJP)piwdgx.o $(SOPHYAOBJP)piwindowgen.o $(SOPHYAOBJP)piwindowx.o $(SOPHYAOBJP)pixtbase.o $(SOPHYAOBJP)piyfxdrw.o $(SOPHYAOBJP)psfile.o $(SOPHYAOBJP)xdispim.o
+	rm -f $(SOPHYALIBP)libPI.a
+ 
+$(SOPHYALIBP)libPI.a : $(SOPHYAOBJP)lut.o $(SOPHYAOBJP)parradapter.o $(SOPHYAOBJP)pi3ddrw.o $(SOPHYAOBJP)pi3dwdg.o $(SOPHYAOBJP)piapplgen.o $(SOPHYAOBJP)piapplx.o $(SOPHYAOBJP)piaxes.o $(SOPHYAOBJP)piaxestools.o $(SOPHYAOBJP)pibargraph.o $(SOPHYAOBJP)pibwdggen.o $(SOPHYAOBJP)pibwdgx.o $(SOPHYAOBJP)picmap.o $(SOPHYAOBJP)picmapgen.o $(SOPHYAOBJP)picmapview.o $(SOPHYAOBJP)picmapx.o $(SOPHYAOBJP)picons.o $(SOPHYAOBJP)picontainergen.o $(SOPHYAOBJP)picontainerx.o $(SOPHYAOBJP)pidrawer.o $(SOPHYAOBJP)pidrawwin.o $(SOPHYAOBJP)pidrwtools.o $(SOPHYAOBJP)pieldrw.o $(SOPHYAOBJP)pievthandler.o $(SOPHYAOBJP)pifilechogen.o $(SOPHYAOBJP)pifilechox.o $(SOPHYAOBJP)pifontgen.o $(SOPHYAOBJP)pifontx.o $(SOPHYAOBJP)pigraph3d.o $(SOPHYAOBJP)pigraphgen.o $(SOPHYAOBJP)pigraphps.o $(SOPHYAOBJP)pigraphuc.o $(SOPHYAOBJP)pigraphx.o $(SOPHYAOBJP)pigratt.o $(SOPHYAOBJP)pigrcoord.o $(SOPHYAOBJP)piimage.o $(SOPHYAOBJP)piimgtools.o $(SOPHYAOBJP)pilineatt.o $(SOPHYAOBJP)pilistgen.o $(SOPHYAOBJP)pilistx.o $(SOPHYAOBJP)pimenubargen.o $(SOPHYAOBJP)pimenubarx.o $(SOPHYAOBJP)pimenugen.o $(SOPHYAOBJP)pimenux.o $(SOPHYAOBJP)pimsghandler.o $(SOPHYAOBJP)pioptmenugen.o $(SOPHYAOBJP)pioptmenux.o $(SOPHYAOBJP)piperiodx.o $(SOPHYAOBJP)pipixmapgen.o $(SOPHYAOBJP)pipixmapx.o $(SOPHYAOBJP)piscdrawwdg.o $(SOPHYAOBJP)pistdwdggen.o $(SOPHYAOBJP)pistdwdgx.o $(SOPHYAOBJP)pistzwin.o $(SOPHYAOBJP)pisurfdr.o $(SOPHYAOBJP)pitherm.o $(SOPHYAOBJP)pitxtdrw.o $(SOPHYAOBJP)piwdggen.o $(SOPHYAOBJP)piwdgx.o $(SOPHYAOBJP)piwindowgen.o $(SOPHYAOBJP)piwindowx.o $(SOPHYAOBJP)pixtbase.o $(SOPHYAOBJP)piyfxdrw.o $(SOPHYAOBJP)psfile.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)lut.o: lut.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lut.cc
+ 
+$(SOPHYAOBJP)parradapter.o: parradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h parradapter.h \
+  $(SOPHYAINCP)machdefs.h lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  parradapter.cc
+ 
+$(SOPHYAOBJP)pi3ddrw.o: pi3ddrw.cc $(SOPHYAINCP)sopnamsp.h \
+  pi3ddrw.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi3ddrw.cc
+ 
+$(SOPHYAOBJP)pi3dwdg.o: pi3dwdg.cc $(SOPHYAINCP)sopnamsp.h \
+  pi3dwdg.h pisysdep.h $(SOPHYAINCP)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 pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.h piwindowx.h piwindowgen.h \
+  picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi3dwdg.cc
+ 
+$(SOPHYAOBJP)piapplgen.o: piapplgen.cc $(SOPHYAINCP)sopnamsp.h \
+  piapplgen.h pimsghandler.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapplgen.cc
+ 
+$(SOPHYAOBJP)piapplx.o: piapplx.cc $(SOPHYAINCP)sopnamsp.h \
+  piapplx.h piapplgen.h pimsghandler.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapplx.cc
+ 
+$(SOPHYAOBJP)piaxes.o: piaxes.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piaxes.cc
+ 
+$(SOPHYAOBJP)piaxestools.o: piaxestools.cc \
+  $(SOPHYAINCP)sopnamsp.h piaxes.h pigraphuc.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piaxestools.cc
+ 
+$(SOPHYAOBJP)pibargraph.o: pibargraph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pibargraph.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibargraph.cc
+ 
+$(SOPHYAOBJP)pibwdggen.o: pibwdggen.cc $(SOPHYAINCP)sopnamsp.h \
+  pibwdggen.h pisysdep.h $(SOPHYAINCP)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 pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.h piwindowx.h piwindowgen.h \
+  picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h pibwdgx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibwdggen.cc
+ 
+$(SOPHYAOBJP)pibwdgx.o: pibwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  pixtbaseP.h pibwdgx.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pibwdgx.cc
+ 
+$(SOPHYAOBJP)picmap.o: picmap.cc $(SOPHYAINCP)sopnamsp.h \
+  picmap.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picmapx.h picmapgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmap.cc
+ 
+$(SOPHYAOBJP)picmapgen.o: picmapgen.cc $(SOPHYAINCP)sopnamsp.h \
+  picmapgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picmapx.h picmap.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapgen.cc
+ 
+$(SOPHYAOBJP)picmapview.o: picmapview.cc \
+  $(SOPHYAINCP)sopnamsp.h picmapview.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapview.cc
+ 
+$(SOPHYAOBJP)picmapx.o: picmapx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)machdefs.h \
+  pimsghandler.h picolist.h picmapx.h picmapgen.h pisysdep.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picmapx.cc
+ 
+$(SOPHYAOBJP)picons.o: picons.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picons.cc
+ 
+$(SOPHYAOBJP)picontainergen.o: picontainergen.cc \
+  $(SOPHYAINCP)sopnamsp.h picontainergen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picontainergen.cc
+ 
+$(SOPHYAOBJP)picontainerx.o: picontainerx.cc \
+  $(SOPHYAINCP)sopnamsp.h picontainerx.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h \
+  picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picontainerx.cc
+ 
+$(SOPHYAOBJP)pidrawer.o: pidrawer.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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 pimenux.h pimenugen.h \
+  pioptmenux.h pioptmenugen.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrawer.cc
+ 
+$(SOPHYAOBJP)pidrawwin.o: pidrawwin.cc $(SOPHYAINCP)sopnamsp.h \
+  pidrawwin.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrawwin.cc
+ 
+$(SOPHYAOBJP)pidrwtools.o: pidrwtools.cc \
+  $(SOPHYAINCP)sopnamsp.h pidrwtools.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h pistdwdgx.h \
+  pistdwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h pimenux.h \
+  pimenugen.h pioptmenux.h pioptmenugen.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pidrwtools.cc
+ 
+$(SOPHYAOBJP)pieldrw.o: pieldrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pieldrw.cc
+ 
+$(SOPHYAOBJP)pievthandler.o: pievthandler.cc \
+  $(SOPHYAINCP)sopnamsp.h pievthandler.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pievthandler.cc
+ 
+$(SOPHYAOBJP)pifilechogen.o: pifilechogen.cc \
+  $(SOPHYAINCP)sopnamsp.h pifilechogen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifilechogen.cc
+ 
+$(SOPHYAOBJP)pifilechox.o: pifilechox.cc \
+  $(SOPHYAINCP)sopnamsp.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifilechox.cc
+ 
+$(SOPHYAOBJP)pifontgen.o: pifontgen.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+  picmapgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifontgen.cc
+ 
+$(SOPHYAOBJP)pifontx.o: pifontx.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pifontx.h \
+  pifontgen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pifontx.cc
+ 
+$(SOPHYAOBJP)pigraph3d.o: pigraph3d.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraph3d.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraph3d.cc
+ 
+$(SOPHYAOBJP)pigraphgen.o: pigraphgen.cc \
+  $(SOPHYAINCP)sopnamsp.h pigraphgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphgen.cc
+ 
+$(SOPHYAOBJP)pigraphps.o: pigraphps.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphps.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphps.cc
+ 
+$(SOPHYAOBJP)pigraphuc.o: pigraphuc.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphuc.cc
+ 
+$(SOPHYAOBJP)pigraphx.o: pigraphx.cc $(SOPHYAINCP)sopnamsp.h \
+  pigraphx.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigraphx.cc
+ 
+$(SOPHYAOBJP)pigratt.o: pigratt.cc $(SOPHYAINCP)sopnamsp.h \
+  pigratt.h pisysdep.h $(SOPHYAINCP)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 \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigratt.cc
+ 
+$(SOPHYAOBJP)pigrcoord.o: pigrcoord.cc $(SOPHYAINCP)sopnamsp.h \
+  pigrcoord.h pisysdep.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigrcoord.cc
+ 
+$(SOPHYAOBJP)piimage.o: piimage.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piimage.h \
+  parradapter.h lut.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piimage.cc
+ 
+$(SOPHYAOBJP)piimgtools.o: piimgtools.cc \
+  $(SOPHYAINCP)sopnamsp.h piimgtools.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piimgtools.cc
+ 
+$(SOPHYAOBJP)pilineatt.o: pilineatt.cc $(SOPHYAINCP)sopnamsp.h \
+  pilineatt.h pisysdep.h $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilineatt.cc
+ 
+$(SOPHYAOBJP)pilistgen.o: pilistgen.cc $(SOPHYAINCP)sopnamsp.h \
+  pilistgen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilistgen.cc
+ 
+$(SOPHYAOBJP)pilistx.o: pilistx.cc $(SOPHYAINCP)sopnamsp.h \
+  pilistx.h pilistgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h piwdgx.h piwdggen.h \
+  pimsghandler.h picolist.h picontainerx.h picontainergen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pilistx.cc
+ 
+$(SOPHYAOBJP)pimenubargen.o: pimenubargen.cc \
+  $(SOPHYAINCP)sopnamsp.h pimenubargen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenubargen.cc
+ 
+$(SOPHYAOBJP)pimenubarx.o: pimenubarx.cc \
+  $(SOPHYAINCP)sopnamsp.h pimenubarx.h \
+  pimenubargen.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenubarx.cc
+ 
+$(SOPHYAOBJP)pimenugen.o: pimenugen.cc $(SOPHYAINCP)sopnamsp.h \
+  pimenugen.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenugen.cc
+ 
+$(SOPHYAOBJP)pimenux.o: pimenux.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pimenubarx.h \
+  pimenubargen.h pimenux.h pimenugen.h piwdgx.h piwdggen.h pimsghandler.h \
+  picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimenux.cc
+ 
+$(SOPHYAOBJP)pimsghandler.o: pimsghandler.cc \
+  $(SOPHYAINCP)sopnamsp.h pimsghandler.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pimsghandler.cc
+ 
+$(SOPHYAOBJP)pioptmenugen.o: pioptmenugen.cc \
+  $(SOPHYAINCP)sopnamsp.h pioptmenugen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pimenux.h \
+  pimenugen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pioptmenugen.cc
+ 
+$(SOPHYAOBJP)pioptmenux.o: pioptmenux.cc \
+  $(SOPHYAINCP)sopnamsp.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pioptmenux.cc
+ 
+$(SOPHYAOBJP)piperiodx.o: piperiodx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)machdefs.h \
+  pimsghandler.h picolist.h piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piperiodx.cc
+ 
+$(SOPHYAOBJP)pipixmapgen.o: pipixmapgen.cc \
+  $(SOPHYAINCP)sopnamsp.h pipixmapgen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipixmapgen.cc
+ 
+$(SOPHYAOBJP)pipixmapx.o: pipixmapx.cc $(SOPHYAINCP)sopnamsp.h \
+  pipixmapx.h pipixmapgen.h pisysdep.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipixmapx.cc
+ 
+$(SOPHYAOBJP)piscdrawwdg.o: piscdrawwdg.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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 pimenux.h pimenugen.h \
+  pioptmenux.h pioptmenugen.h piapplx.h piapplgen.h pimenubarx.h \
+  pimenubargen.h picons.h piaxestools.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piscdrawwdg.cc
+ 
+$(SOPHYAOBJP)pistdwdggen.o: pistdwdggen.cc \
+  $(SOPHYAINCP)sopnamsp.h pistdwdggen.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdwdggen.cc
+ 
+$(SOPHYAOBJP)pistdwdgx.o: pistdwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  pisysdep.h $(SOPHYAINCP)machdefs.h pistdwdgx.h \
+  pistdwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+  picontainerx.h picontainergen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdwdgx.cc
+ 
+$(SOPHYAOBJP)pistzwin.o: pistzwin.cc $(SOPHYAINCP)sopnamsp.h \
+  pistzwin.h pisysdep.h $(SOPHYAINCP)machdefs.h \
+  piwindowx.h piwindowgen.h picontainerx.h picontainergen.h piwdgx.h \
+  piwdggen.h pimsghandler.h picolist.h piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)machdefs.h psfile.h pifontgen.h \
+  pigraphgen.h picmap.h picmapx.h picmapgen.h pifontx.h pigrcoord.h \
+  pilineatt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistzwin.cc
+ 
+$(SOPHYAOBJP)pisurfdr.o: pisurfdr.cc $(SOPHYAINCP)sopnamsp.h \
+  pisurfdr.h parradapter.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pisurfdr.cc
+ 
+$(SOPHYAOBJP)pitherm.o: pitherm.cc $(SOPHYAINCP)sopnamsp.h \
+  pitherm.h pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitherm.cc
+ 
+$(SOPHYAOBJP)pitxtdrw.o: pitxtdrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pitxtdrw.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitxtdrw.cc
+ 
+$(SOPHYAOBJP)piwdggen.o: piwdggen.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdggen.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwdggen.cc
+ 
+$(SOPHYAOBJP)piwdgx.o: piwdgx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwdgx.h piwdggen.h $(SOPHYAINCP)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 \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwdgx.cc
+ 
+$(SOPHYAOBJP)piwindowgen.o: piwindowgen.cc \
+  $(SOPHYAINCP)sopnamsp.h piwindowgen.h \
+  pisysdep.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwindowgen.cc
+ 
+$(SOPHYAOBJP)piwindowx.o: piwindowx.cc $(SOPHYAINCP)sopnamsp.h \
+  piwindowx.h piwindowgen.h pisysdep.h \
+  $(SOPHYAINCP)machdefs.h picontainerx.h \
+  picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piwindowx.cc
+ 
+$(SOPHYAOBJP)pixtbase.o: pixtbase.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pixtbaseP.h pibwdgx.h \
+  pisysdep.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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pixtbase.cc
+ 
+$(SOPHYAOBJP)piyfxdrw.o: piyfxdrw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piyfxdrw.cc
+ 
+$(SOPHYAOBJP)psfile.o: psfile.cc $(SOPHYAINCP)sopnamsp.h \
+  psfile.h $(SOPHYAINCP)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
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psfile.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PI/ucckprot.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/ucckprot.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/ucckprot.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/xdispim.c
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/xdispim.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/xdispim.c	(revision 3445)
@@ -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_Nov2007/SophyaPI/PI/xdispim.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PI/xdispim.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PI/xdispim.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/Makefile	(revision 3445)
@@ -0,0 +1,220 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPIGcont.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)picntools.o $(SOPHYAOBJP)pigncont.o $(SOPHYAOBJP)gp_alloc.o $(SOPHYAOBJP)gp_axis.o $(SOPHYAOBJP)gp_contour.o
+	rm -f $(SOPHYALIBP)libPIGcont.a
+ 
+$(SOPHYALIBP)libPIGcont.a : $(SOPHYAOBJP)gp_alloc.o $(SOPHYAOBJP)gp_axis.o $(SOPHYAOBJP)gp_contour.o $(SOPHYAOBJP)picntools.o $(SOPHYAOBJP)pigncont.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)picntools.o: picntools.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h picntools.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)picmapview.h pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h gp_contour.h gp_types.h \
+  gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picntools.cc
+ 
+$(SOPHYAOBJP)pigncont.o: pigncont.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)nbtri.h picntools.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)picmapview.h pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h gp_contour.h \
+  gp_types.h gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigncont.cc
+ 
+$(SOPHYAOBJP)gp_alloc.o: gp_alloc.c gp_alloc.h gp_graph3d.h gp_types.h gpc_misc.h
+	$(CCOMPILE) -o $@  gp_alloc.c
+ 
+$(SOPHYAOBJP)gp_axis.o: gp_axis.c gp_axis.h gpc_misc.h
+	$(CCOMPILE) -o $@  gp_axis.c
+ 
+$(SOPHYAOBJP)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
+	$(CCOMPILE) -o $@  gp_contour.c
+ 
Index: /tags/V_Nov2007/SophyaPI/PIGcont/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_alloc.c
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_alloc.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_alloc.c	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_alloc.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_alloc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_alloc.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_axis.c
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_axis.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_axis.c	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_axis.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_axis.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_axis.h	(revision 3445)
@@ -0,0 +1,616 @@
+/*[
+ * 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 */
+/* NE SERT A RIEN ET DE TOUTE FACON PAS DEFINI (rz+cmv 100106)
+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_Nov2007/SophyaPI/PIGcont/gp_contour.c
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_contour.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_contour.c	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_contour.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_contour.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_contour.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_dynarray.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_dynarray.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_dynarray.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_graph3d.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_graph3d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_graph3d.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gp_types.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gp_types.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gp_types.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/gpc_misc.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/gpc_misc.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/gpc_misc.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/objlist.list	(revision 3445)
@@ -0,0 +1,5 @@
+gp_alloc.o
+gp_axis.o
+gp_contour.o
+picntools.o
+pigncont.o
Index: /tags/V_Nov2007/SophyaPI/PIGcont/picntools.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/picntools.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/picntools.cc	(revision 3445)
@@ -0,0 +1,852 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <string>
+#include <iostream>
+
+#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(), "PIUniCol32");
+mCasc[2] = new PIMenu(mOpt[1]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3,nsct4;
+//  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]);
+nsct3 = 17;  // Les 7 tables de couleurs uniforme
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[1]);
+//  Apres les tables importees de MIDAS
+nsct4 = PIColorMap::NumberStandardColorMaps()-2; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct3; kcc<nsct4; kcc++) 
+  mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[2]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct4; 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<3; 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_Nov2007/SophyaPI/PIGcont/picntools.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/picntools.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/picntools.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIGcont/pigncont.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/pigncont.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/pigncont.cc	(revision 3445)
@@ -0,0 +1,1008 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <iostream>
+#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() const
+{
+  return (mLabelOn);
+}
+
+bool PIContourDrawer::IsLineOn() const
+{
+  return (mLineOn);
+}
+
+bool PIContourDrawer::IsMarkOn() const
+{
+  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 == "laboff" )
+	this->SetLabelOn(false);
+      else if ( sopt == "autolevels" )
+	this->SetCntLevelKind(LEVELS_AUTO);
+      else if (sopt == "linear" ){
+	this->SetCntKind(CONTOUR_KIND_BSPLINE);
+	recalc = 1;
+      }
+      else if (sopt == "bspline" ){
+	this->SetCntKind(CONTOUR_KIND_BSPLINE);
+	recalc = 1;
+      }else if ((sopt == "3spl" )||(sopt == "cubicspl")) {
+	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);  
+  
+}
+
+// Methode ajoute en Oct 2007 - Reza
+int PIContourDrawer::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+
+ if (GetCntKind()==CONTOUR_KIND_LINEAR)  opt.push_back("linear");
+ else if (GetCntKind()==CONTOUR_KIND_BSPLINE)  opt.push_back("bspline");
+ else if (GetCntKind()==CONTOUR_KIND_CUBIC_SPL)  opt.push_back("cubicspl");
+
+ if (IsLabelOn()) opt.push_back("labon");
+ else opt.push_back("laboff");
+
+ return 1;
+}
+
+void PIContourDrawer::GetOptionsHelpInfo(string& info)
+{
+  info += " ---- PIContourDrawer options help info : \n" ;
+  info += " autolevels : automatic selection of levels and number of contours \n"; 
+  info += " ncont=nLevel (or nc=NLevel) : sets the number of contour\n"; 
+  info += " lev=v1,v2,v3... (or niv=v1,v2,v3...) set the number and levels of contours\n"; 
+  info += " lstep=nLev,start,step : define incremental levels \n"; 
+  info += " labon/laboff : display of contour level values on/off \n"; 
+  info += " linear/bspline/cubicspl=3spl : select contour kind \n"; 
+// On recupere ensuite la chaine info de la classe de base
+  PIDrawer::GetOptionsHelpInfo(info);
+  return;
+}
+
+
+
+ 
Index: /tags/V_Nov2007/SophyaPI/PIGcont/pigncont.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/pigncont.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/pigncont.h	(revision 3445)
@@ -0,0 +1,115 @@
+// 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() const {return Contour_Levels_kind ;};
+  void SetCntKind(t_contour_kind kind){Contour_kind = kind;};
+  t_contour_kind GetCntKind() const {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() const;
+  virtual bool      IsMarkOn() const;  
+  virtual bool      IsLabelOn() const;
+  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
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual int        OptionToString(vector<string> & opt) const;
+//   Texte d'aide des options disponibles
+  virtual void       GetOptionsHelpInfo(string& info);
+
+
+protected:
+  bool _autodel;
+  int _nz;
+  P2DArrayAdapter* _arr;
+  NTupleInterface* _nti;
+  bool mLineOn,mMarkOn,mLabelOn;
+  
+
+  
+
+};
+
+
+//
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIGcont/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libPI.so
Index: /tags/V_Nov2007/SophyaPI/PIGcont/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIGcont/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIGcont/smakefile	(revision 3445)
@@ -0,0 +1,220 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPIGcont.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)picntools.o $(SOPHYAOBJP)pigncont.o $(SOPHYAOBJP)gp_alloc.o $(SOPHYAOBJP)gp_axis.o $(SOPHYAOBJP)gp_contour.o
+	rm -f $(SOPHYALIBP)libPIGcont.a
+ 
+$(SOPHYALIBP)libPIGcont.a : $(SOPHYAOBJP)gp_alloc.o $(SOPHYAOBJP)gp_axis.o $(SOPHYAOBJP)gp_contour.o $(SOPHYAOBJP)picntools.o $(SOPHYAOBJP)pigncont.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)picntools.o: picntools.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h picntools.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)picmapview.h pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h gp_contour.h gp_types.h \
+  gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  picntools.cc
+ 
+$(SOPHYAOBJP)pigncont.o: pigncont.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)nbtri.h picntools.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)picmapview.h pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h gp_contour.h \
+  gp_types.h gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigncont.cc
+ 
+$(SOPHYAOBJP)gp_alloc.o: gp_alloc.c gp_alloc.h gp_graph3d.h gp_types.h gpc_misc.h
+	$(CCOMPILE) -o $@  gp_alloc.c
+ 
+$(SOPHYAOBJP)gp_axis.o: gp_axis.c gp_axis.h gpc_misc.h
+	$(CCOMPILE) -o $@  gp_axis.c
+ 
+$(SOPHYAOBJP)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
+	$(CCOMPILE) -o $@  gp_contour.c
+ 
Index: /tags/V_Nov2007/SophyaPI/PIext/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/Makefile	(revision 3445)
@@ -0,0 +1,2824 @@
+include ../BuildMgr/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPIext.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basexecut.o $(SOPHYAOBJP)contmodex.o $(SOPHYAOBJP)cxxexecutor.o $(SOPHYAOBJP)cxxexecwin.o $(SOPHYAOBJP)flowmodex.o $(SOPHYAOBJP)graphexecut.o $(SOPHYAOBJP)nobjmgr.o $(SOPHYAOBJP)nomdvladapter.o $(SOPHYAOBJP)nomgadapter.o $(SOPHYAOBJP)nomgfdadapter.o $(SOPHYAOBJP)nomherradapter.o $(SOPHYAOBJP)nomhistadapter.o $(SOPHYAOBJP)nomimagadapter.o $(SOPHYAOBJP)nommatvecadapter.o $(SOPHYAOBJP)nomskymapadapter.o $(SOPHYAOBJP)nomspecrespadapter.o $(SOPHYAOBJP)nomstladapter.o $(SOPHYAOBJP)nomtarradapter.o $(SOPHYAOBJP)nomtmatvecadapter.o $(SOPHYAOBJP)pawexecut.o $(SOPHYAOBJP)pi2dvec.o $(SOPHYAOBJP)piacmd.o $(SOPHYAOBJP)piafitting.o $(SOPHYAOBJP)pigfd1.o $(SOPHYAOBJP)pigfd2.o $(SOPHYAOBJP)pihisto.o $(SOPHYAOBJP)pihisto2d.o $(SOPHYAOBJP)piinit.o $(SOPHYAOBJP)pintup3d.o $(SOPHYAOBJP)pintuple.o $(SOPHYAOBJP)pipodrw.o $(SOPHYAOBJP)pisiadw.o $(SOPHYAOBJP)pistdimgapp.o $(SOPHYAOBJP)pistlist.o $(SOPHYAOBJP)pitvmaad.o $(SOPHYAOBJP)servnobjm.o $(SOPHYAOBJP)userfitfunex.o
+	rm -f $(SOPHYALIBP)libPIext.a
+ 
+$(SOPHYALIBP)libPIext.a : $(SOPHYAOBJP)basexecut.o $(SOPHYAOBJP)contmodex.o $(SOPHYAOBJP)cxxexecutor.o $(SOPHYAOBJP)cxxexecwin.o $(SOPHYAOBJP)flowmodex.o $(SOPHYAOBJP)graphexecut.o $(SOPHYAOBJP)nobjmgr.o $(SOPHYAOBJP)nomdvladapter.o $(SOPHYAOBJP)nomgadapter.o $(SOPHYAOBJP)nomgfdadapter.o $(SOPHYAOBJP)nomherradapter.o $(SOPHYAOBJP)nomhistadapter.o $(SOPHYAOBJP)nomimagadapter.o $(SOPHYAOBJP)nomskymapadapter.o $(SOPHYAOBJP)nomspecrespadapter.o $(SOPHYAOBJP)nomtarradapter.o $(SOPHYAOBJP)nomtmatvecadapter.o $(SOPHYAOBJP)pawexecut.o $(SOPHYAOBJP)pi2dvec.o $(SOPHYAOBJP)piacmd.o $(SOPHYAOBJP)piafitting.o $(SOPHYAOBJP)pigfd1.o $(SOPHYAOBJP)pigfd2.o $(SOPHYAOBJP)pihisto2d.o $(SOPHYAOBJP)pihisto.o $(SOPHYAOBJP)piinit.o $(SOPHYAOBJP)pintup3d.o $(SOPHYAOBJP)pintuple.o $(SOPHYAOBJP)pipodrw.o $(SOPHYAOBJP)pisiadw.o $(SOPHYAOBJP)pistdimgapp.o $(SOPHYAOBJP)pitvmaad.o $(SOPHYAOBJP)servnobjm.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)basexecut.o: basexecut.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmd.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h basexecut.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)strutilxx.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  nomgadapter.h $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basexecut.cc
+ 
+$(SOPHYAOBJP)contmodex.o: contmodex.cc $(SOPHYAINCP)sopnamsp.h \
+  contmodex.h $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)gp_contour.h \
+  $(SOPHYAINCP)gp_types.h \
+  $(SOPHYAINCP)gpc_misc.h \
+  $(SOPHYAINCP)gp_dynarray.h \
+  $(SOPHYAINCP)gp_graph3d.h \
+  $(SOPHYAINCP)gp_alloc.h \
+  $(SOPHYAINCP)pidrawer.h nomgadapter.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  contmodex.cc
+ 
+$(SOPHYAOBJP)cxxexecutor.o: cxxexecutor.cc \
+  $(SOPHYAINCP)sopnamsp.h cxxexecutor.h \
+  $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)cxxcmplnk.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxexecutor.cc
+ 
+$(SOPHYAOBJP)cxxexecwin.o: cxxexecwin.cc \
+  $(SOPHYAINCP)sopnamsp.h cxxexecutor.h \
+  $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h cxxexecwin.h \
+  $(SOPHYAINCP)pisysdep.h pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxexecwin.cc
+ 
+$(SOPHYAOBJP)flowmodex.o: flowmodex.cc $(SOPHYAINCP)sopnamsp.h \
+  flowmodex.h $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pi2dvec.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)pidrawer.h nomgadapter.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  flowmodex.cc
+ 
+$(SOPHYAOBJP)graphexecut.o: graphexecut.cc \
+  $(SOPHYAINCP)sopnamsp.h piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h graphexecut.h \
+  $(SOPHYAINCP)strutilxx.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pibargraph.h \
+  $(SOPHYAINCP)pitxtdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  graphexecut.cc
+ 
+$(SOPHYAOBJP)nobjmgr.o: nobjmgr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)datatypes.h \
+  $(SOPHYAINCP)machdefs.h nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)tvector.h pitvmaad.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pisurfdr.h pipodrw.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hist2err.h pintuple.h pintup3d.h \
+  $(SOPHYAINCP)pi3ddrw.h pigfd1.h \
+  $(SOPHYAINCP)generaldata.h pigfd2.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nobjmgr.cc
+ 
+$(SOPHYAOBJP)nomdvladapter.o: nomdvladapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomdvladapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)dvlist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomdvladapter.cc
+ 
+$(SOPHYAOBJP)nomgadapter.o: nomgadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomgadapter.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomgadapter.cc
+ 
+$(SOPHYAOBJP)nomgfdadapter.o: nomgfdadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomgfdadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pipodrw.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomgfdadapter.cc
+ 
+$(SOPHYAOBJP)nomherradapter.o: nomherradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomherradapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h pihisto.h \
+  phistwrapper.h pihisto2d.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h sohiswrap.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)pexceptions.h pipodrw.h \
+  servnobjm.h nobjmgr.h $(SOPHYAINCP)dvlist.h \
+  dlftypes.h $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)strutilxx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomherradapter.cc
+ 
+$(SOPHYAOBJP)nomhistadapter.o: nomhistadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomhistadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h pihisto.h \
+  phistwrapper.h sohiswrap.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)pexceptions.h pihisto2d.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h pipodrw.h servnobjm.h \
+  nobjmgr.h $(SOPHYAINCP)dvlist.h dlftypes.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomhistadapter.cc
+ 
+$(SOPHYAOBJP)nomimagadapter.o: nomimagadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomimagadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h pimgadapter.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomimagadapter.cc
+ 
+$(SOPHYAOBJP)nomskymapadapter.o: nomskymapadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomskymapadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h pitvmaad.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)complexios.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomskymapadapter.cc
+ 
+$(SOPHYAOBJP)nomspecrespadapter.o: nomspecrespadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomspecrespadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)gaussfilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomspecrespadapter.cc
+ 
+$(SOPHYAOBJP)nomtarradapter.o: nomtarradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomtarradapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tvector.h pitvmaad.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)fioarr.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomtarradapter.cc
+ 
+$(SOPHYAOBJP)nomtmatvecadapter.o: nomtmatvecadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h nomtmatvecadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pidrawer.h pitvmaad.h \
+  $(SOPHYAINCP)cimage.h pimgadapter.h \
+  $(SOPHYAINCP)fioarr.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomtmatvecadapter.cc
+ 
+$(SOPHYAOBJP)pawexecut.o: pawexecut.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h pawexecut.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h pihisto.h \
+  phistwrapper.h $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pawexecut.cc
+ 
+$(SOPHYAOBJP)pi2dvec.o: pi2dvec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)nbtri.h pi2dvec.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi2dvec.cc
+ 
+$(SOPHYAOBJP)piacmd.o: piacmd.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmd.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)srandgen.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h basexecut.h \
+  graphexecut.h piafitting.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tvector.h pawexecut.h \
+  cxxexecutor.h cxxexecwin.h contmodex.h flowmodex.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piacmd.cc
+ 
+$(SOPHYAOBJP)piafitting.o: piafitting.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)nbtri.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)fct1dfit.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)fct2dfit.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h piafitting.h \
+  $(SOPHYAINCP)machdefs.h nomgadapter.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)pdlmgr.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h nomhistadapter.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h nomgfdadapter.h \
+  nomimagadapter.h nomtmatvecadapter.h \
+  $(SOPHYAINCP)generaldata.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piafitting.cc
+ 
+$(SOPHYAOBJP)pigfd1.o: pigfd1.cc $(SOPHYAINCP)sopnamsp.h \
+  pigfd1.h $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigfd1.cc
+ 
+$(SOPHYAOBJP)pigfd2.o: pigfd2.cc $(SOPHYAINCP)sopnamsp.h \
+  pigfd2.h $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pigraph3d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigfd2.cc
+ 
+$(SOPHYAOBJP)pihisto.o: pihisto.cc pihisto.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h phistwrapper.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pihisto.cc
+ 
+$(SOPHYAOBJP)pihisto2d.o: pihisto2d.cc $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)sopnamsp.h pihisto2d.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h phistwrapper.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pihisto2d.cc
+ 
+$(SOPHYAOBJP)piinit.o: piinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h piinit.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h nomdvladapter.h \
+  nomgadapter.h $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h nomhistadapter.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h nomherradapter.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h nomgfdadapter.h \
+  nomimagadapter.h $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h nomtmatvecadapter.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)generaldata.h nomtarradapter.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h nomskymapadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)gaussfilt.h nomspecrespadapter.h \
+  $(SOPHYAINCP)specresp.h piaversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piinit.cc
+ 
+$(SOPHYAOBJP)pintup3d.o: pintup3d.cc $(SOPHYAINCP)sopnamsp.h \
+  pintup3d.h $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pigraph3d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pintup3d.cc
+ 
+$(SOPHYAOBJP)pintuple.o: pintuple.cc $(SOPHYAINCP)sopnamsp.h \
+  pintuple.h $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pintuple.cc
+ 
+$(SOPHYAOBJP)pipodrw.o: pipodrw.cc $(SOPHYAINCP)sopnamsp.h \
+  pipodrw.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipodrw.cc
+ 
+$(SOPHYAOBJP)pisiadw.o: pisiadw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pisiadw.cc
+ 
+$(SOPHYAOBJP)pistdimgapp.o: pistdimgapp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)psighand.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)piaxestools.h \
+  $(SOPHYAINCP)piscdrawwdg.h piinit.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)piversion.h piaversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdimgapp.cc
+ 
+$(SOPHYAOBJP)pitvmaad.o: pitvmaad.cc $(SOPHYAINCP)sopnamsp.h \
+  pitvmaad.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitvmaad.cc
+ 
+$(SOPHYAOBJP)servnobjm.o: servnobjm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fct1dfit.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)fct2dfit.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)matharr.h pitvmaad.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pisurfdr.h pintuple.h pintup3d.h \
+  $(SOPHYAINCP)pi3ddrw.h pipodrw.h \
+  $(SOPHYAINCP)hist2err.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  servnobjm.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PIext/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/Makefile.mgr	(revision 3445)
@@ -0,0 +1,2171 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libPIext.a
+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)nommatvecadapter.o $(OBJ)nomskymapadapter.o $(OBJ)nomspecrespadapter.o $(OBJ)nomstladapter.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)pistlist.o $(OBJ)pitvmaad.o $(OBJ)servnobjm.o $(OBJ)userfitfunex.o
+	rm -f $(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
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)basexecut.o: basexecut.cc $(INC)sopnamsp.h \
+  piacmd.h $(INC)machdefs.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h basexecut.h \
+  $(INC)strutilxx.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 pisiadw.h \
+  $(INC)pilistx.h \
+  $(INC)pilistgen.h \
+  $(INC)pistzwin.h \
+  $(INC)pitherm.h \
+  $(INC)resusage.h servnobjm.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)piyfxdrw.h \
+  $(INC)pibargraph.h \
+  $(INC)pitxtdrw.h \
+  $(INC)histos.h \
+  $(INC)histos2.h \
+  $(INC)hisprof.h \
+  $(INC)ntuple.h
+$(OBJ)contmodex.o: contmodex.cc $(INC)sopnamsp.h \
+  contmodex.h $(INC)machdefs.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h nobjmgr.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 $(INC)sopnamsp.h \
+  cxxexecutor.h $(INC)machdefs.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h nobjmgr.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 $(INC)sopnamsp.h \
+  cxxexecutor.h $(INC)machdefs.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h nobjmgr.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 $(INC)sopnamsp.h \
+  flowmodex.h $(INC)machdefs.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h nobjmgr.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)sopnamsp.h \
+  $(INC)strutil.h \
+  $(INC)datatypes.h \
+  $(INC)machdefs.h nobjmgr.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)commander.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.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)sopnamsp.h \
+  $(INC)machdefs.h nomgadapter.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h nomgfdadapter.h nomgadapter.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h nomhistadapter.h \
+  nomgadapter.h $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)histerr.h \
+  $(INC)ntuple.h \
+  $(INC)xntuple.h \
+  $(INC)basedtable.h \
+  $(INC)segdatablock.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 \
+  nobjmgr.h dlftypes.h $(INC)pdlmgr.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 \
+  $(INC)datatable.h \
+  $(INC)swppfdtable.h \
+  $(INC)swsegdb.h \
+  $(INC)ppfswapper.h \
+  $(INC)ppftpointerio.h
+$(OBJ)nomimagadapter.o: nomimagadapter.cc \
+  $(INC)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)datatype.h nomimagadapter.h \
+  nomgadapter.h $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)datatype.h nomskymapadapter.h \
+  nomgadapter.h $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sphereecp.h \
+  $(INC)fiospherethetaphi.h \
+  $(INC)fiospherehealpix.h \
+  $(INC)fiolocalmap.h \
+  $(INC)fiosphereecp.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)sopnamsp.h \
+  $(INC)machdefs.h nomspecrespadapter.h \
+  nomgadapter.h $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)datatype.h nomtarradapter.h \
+  nomgadapter.h $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(INC)strutil.h \
+  $(INC)strutilxx.h \
+  $(INC)machdefs.h \
+  $(INC)histos.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)histerr.h \
+  $(INC)ntuple.h \
+  $(INC)ntupintf.h pawexecut.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.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 pihisto.h
+$(OBJ)pi2dvec.o: pi2dvec.cc $(INC)sopnamsp.h \
+  $(INC)machdefs.h \
+  $(INC)histos.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.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 $(INC)sopnamsp.h piacmd.h \
+  $(INC)machdefs.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)mutyv.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.h dlftypes.h basexecut.h \
+  $(INC)strutil.h \
+  $(INC)strutilxx.h \
+  $(INC)srandgen.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 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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)commander.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.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)histerr.h \
+  $(INC)xntuple.h \
+  $(INC)basedtable.h \
+  $(INC)segdatablock.h nomgfdadapter.h \
+  nomimagadapter.h nomtmatvecadapter.h
+$(OBJ)pigfd1.o: pigfd1.cc $(INC)sopnamsp.h pigfd1.h \
+  $(INC)generaldata.h \
+  $(INC)objfio.h \
+  $(INC)machdefs.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h pigfd2.h \
+  $(INC)generaldata.h \
+  $(INC)objfio.h \
+  $(INC)machdefs.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 $(INC)sopnamsp.h pihisto.h \
+  $(INC)histos.h \
+  $(INC)objfio.h \
+  $(INC)machdefs.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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 \
+  $(INC)sopnamsp.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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)pigratt.h \
+  $(INC)piaxes.h \
+  $(INC)piscdrawwdg.h \
+  $(INC)piwindowx.h \
+  $(INC)piwindowgen.h \
+  $(INC)pieldrw.h \
+  $(INC)nbrandom.h \
+  $(INC)srandgen.h
+$(OBJ)piinit.o: piinit.cc $(INC)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)mutyv.h dlftypes.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.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)histerr.h \
+  $(INC)ntuple.h \
+  $(INC)xntuple.h \
+  $(INC)basedtable.h \
+  $(INC)segdatablock.h nomgfdadapter.h \
+  nomimagadapter.h $(INC)cimage.h \
+  $(INC)fioarr.h nomtmatvecadapter.h \
+  nomtarradapter.h $(INC)datatable.h \
+  $(INC)swppfdtable.h \
+  $(INC)swsegdb.h \
+  $(INC)ppfswapper.h \
+  $(INC)ppftpointerio.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)sphereecp.h \
+  $(INC)specrespvector.h \
+  $(INC)specresp.h \
+  $(INC)gaussfilt.h nomspecrespadapter.h
+$(OBJ)pintup3d.o: pintup3d.cc $(INC)sopnamsp.h \
+  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 $(INC)sopnamsp.h \
+  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 $(INC)sopnamsp.h 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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)mutyv.h dlftypes.h piacmd.h \
+  $(INC)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)zthread.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)sopnamsp.h \
+  $(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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)commander.h \
+  $(INC)pdlmgr.h \
+  $(INC)zthread.h pisiadw.h \
+  $(INC)pilistx.h \
+  $(INC)pilistgen.h \
+  $(INC)pistzwin.h \
+  $(INC)pitherm.h \
+  $(INC)resusage.h servnobjm.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 $(INC)sopnamsp.h \
+  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)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)tvector.h
+$(OBJ)servnobjm.o: servnobjm.cc $(INC)sopnamsp.h \
+  $(INC)strutil.h nobjmgr.h \
+  $(INC)machdefs.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)ppfbinstream.h \
+  $(INC)rawstream.h \
+  $(INC)ppfnametag.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)commander.h \
+  $(INC)ctimer.h \
+  $(INC)zthread.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_Nov2007/SophyaPI/PIext/basexecut.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/basexecut.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/basexecut.cc	(revision 3445)
@@ -0,0 +1,1415 @@
+#include "sopnamsp.h"
+#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 "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "generaldata.h"
+#include "datatable.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;
+}
+
+
+
+/* --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]);
+  }
+  
+// >>>>>>>>>>> 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;
+/*DEL----- Plus besoin en multi-thread ? / Reza 06/01/2004 
+//   On redirige la sortie sur le terminal 
+  bool red = mImgApp->HasRedirectedStdOutErr();
+  mImgApp->RedirectStdOutErr(false);
+                                    --------DEL  */
+#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);
+    return(0);
+  }
+  catch ( PThrowable & exc ) {
+    cerr << "\n PIABaseExecutor: Call / Catched Exception :" 
+	 << (string)typeid(exc).name() << " Msg= " 
+	 << exc.Msg() << endl;
+    return(-77);
+  }
+  catch ( ... ) {
+    cerr << "\n PIABaseExecutor: Call / Catched Exception ... " 
+	 << endl;
+    return(-79);
+  }
+#endif
+/*DEL----- Plus besoin en multi-thread ? / Reza 06/01/2004 
+  mImgApp->RedirectStdOutErr(red);
+                                    --------DEL    */
+}
+
+else if (kw == "openppf" ) {
+  if (tokens.size()<1) { 
+    cout<<"Usage: openppf [-s] file [objname1 objname2 ...]"<<endl; 
+    return(0); 
+  }
+  else if (tokens.size()==1)   // read all objects at nametags
+    mObjMgr->ReadAll(tokens[0],true);  
+  else { 
+    if (tokens[0] == "-s")  // Read all objects sequentially
+      mObjMgr->ReadAll(tokens[1],false);  
+    else mObjMgr->ReadObj(tokens);   // read specified objects
+  }
+}
+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 == "savelist")  {
+  if (tokens.size() < 2) {
+    cout << "Usage: savelist objname1 [objname2 ...] filename "<<endl;
+    return(0);
+  }
+  mObjMgr->SaveListObjects(tokens);  
+}
+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 [prtlev]" << endl; return(0); }
+  int lev = 0;
+  if (tokens.size()>1) lev = atoi(tokens[1].c_str());
+  mObjMgr->PrintObj(tokens[0], lev);  
+}
+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("*");
+  if  (tokens.size() < 2)  mObjMgr->ListObjs(tokens[0]);
+  else {
+    vector<string> olv;
+    mObjMgr->GetObjList(tokens[0], olv);
+    mpiac->SetVar(tokens[1], olv);
+  }
+}
+
+// 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 DataTable
+else if (kw == "newdt") {
+  if(tokens.size() < 2)
+    {cout<<"Usage: newdt name v1:t1 v2:t2 ... vn:tn / newdt name nvar"<<endl; return(0);}
+  DataTable* dt = new DataTable();
+  const char *c = tokens[1].c_str();
+  if(isdigit(c[0])) {
+    int n = atoi(tokens[1].c_str());
+    if(n<=0 || n>=10000) {
+      cout<<"newdt name nvar : nvar="<<n<<" must be an positive integer<10000"<<endl;
+      delete dt; return(0);
+    }
+    for(int i=0;i<n;i++) {
+      char str[16]; sprintf(str,"v%d",i);
+      dt->AddDoubleColumn(str);
+    }
+  } else {
+    for(int i=1;i<tokens.size();i++) {
+      string vname = tokens[i];
+      uint_4 p = tokens[i].find(':');
+      if(p<tokens[i].size()) vname = vname.substr(0,p);
+      if(vname.size()<1) {
+        cout<<"Zero size name for variable: tokens["<<i<<"]="<<tokens[i]<<endl;
+        delete dt; return(0);
+      }
+      if     (tokens[i].find(":r4")<tokens[i].size()) dt->AddFloatColumn(vname);
+      else if(tokens[i].find(":r8")<tokens[i].size()) dt->AddDoubleColumn(vname);
+      else if(tokens[i].find(":i4")<tokens[i].size()) dt->AddIntegerColumn(vname);
+      else if(tokens[i].find(":i8")<tokens[i].size()) dt->AddLongColumn(vname);
+      else if(tokens[i].find(":s") <tokens[i].size()) dt->AddStringColumn(vname);
+      else                                            dt->AddDoubleColumn(vname);
+    }
+  }
+  mObjMgr->AddObj(dt,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_8 kks = 0;
+  int_8 kke = v->NElts();
+  int_8 kkp = 1;
+  if (tokens.size() > 2) Services2NObjMgr::DecodeLoopParameters(tokens[2], kks, kke, kkp);
+  if (kks < 0)  kks = 0;
+  if (kke > (int_8)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;
+  }
+  
+  mpiac->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_8 kks = 0;
+    int_8 kke = nti->NbLines();
+    int_8 kkp = 1;
+    if (tokens.size() > 3) Services2NObjMgr::DecodeLoopParameters(tokens[3], kks, kke, kkp);
+    if (kks < 0)  kks = 0;
+    if (kke > (int_8)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;
+    }
+  }
+  mpiac->SetVar(tokens[2], v2str);
+  if (adel) delete nti;
+}
+// Operation sur objets a travers l'adaptateur NObjMgrAdapter::PerformOperation()
+else if (kw == "objaoper") {
+  if (tokens.size() < 2) {
+    cout << "Usage: objaoper objname operation [args ...]" << endl; 
+    return(0); 
+  }
+  NObjMgrAdapter* oa = mObjMgr->GetObjAdapter(tokens[0]);
+  if(oa == NULL) {
+    cerr << "objaoper Error , No such object " << tokens[0] << endl; 
+    return(0);
+  }
+  tokens.erase(tokens.begin());
+  return oa->PerformOperation(tokens);
+}
+
+// -------------------------------------------------------
+// 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]);
+}
+
+
+// >>>>>>>>>>>  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")||(kw == "plot2dc")) {   // Plot2d avec poids
+  if (tokens.size() < 4) { 
+    cout << "Usage: plot2dw/c nomobj expx expy expwt/expcolidx [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  if (tokens.size() < 5) tokens.push_back("1");
+  while (tokens.size() < 7) tokens.push_back("");
+  bool fgcolidx = false;
+  if (kw == "plot2dc") fgcolidx = true;
+  srvo->DisplayPoints2DW(tokens[0],tokens[1],tokens[2],tokens[3], tokens[4], 
+			 fgcolidx, 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 == "plot3dw" ) {  
+  if (tokens.size() < 5) { 
+    cout << "Usage: plot3dw nomobj expx expy expz expwt [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  if (tokens.size() < 6) tokens.push_back("1");
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->DisplayPoints3DW(tokens[0],tokens[1],tokens[2],tokens[3], tokens[4], tokens[5], 
+			 tokens[6], tokens[7]);
+}
+
+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 == "expmeansig" ) {
+  if (tokens.size() < 2) { 
+    cout << "Usage: expmeansig nameobj expx [expcut loop_par]" << endl;
+    return(0);
+    }
+  while (tokens.size() < 4) tokens.push_back("");
+  string dummy = "";
+  cout << " expmeansig: computing mean/sigma + min/max for " << tokens[0] 
+       << "." << tokens[1] << endl;
+  srvo->ExpressionToVector(tokens[0],tokens[1],tokens[2],dummy,dummy,tokens[3]);
+  }
+
+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);
+}
+
+/* --Methode-- */
+bool PIABaseExecutor::IsThreadable(string const & keyw)
+{
+  if ( (keyw == "fillvec") || (keyw == "fillmtx") || 
+       (keyw == "fillnt") || (keyw == "ntloop") )  return true;
+  else if (keyw.substr(0,4) == "func")  return true;
+  else {
+    string skw = keyw.substr(0,5);
+    if ( (skw == "plot2") || (skw == "plot3") || (skw == "projh") )  return true; 
+  } 
+  return false;	
+}
+
+
+/* --Methode-- */
+void PIABaseExecutor::RegisterCommands()
+{
+string kw, usage, grp;
+//--------- Commandes du groupe modules externes
+grp = "External Modules";
+string gdesc = "Dynamic load (shared object modules) management command group";
+mpiac->AddHelpGroup(grp, gdesc);
+kw = "loadmodule";
+usage = "To load and initialize modules \n  Usage: loadmodule fnameso modulename";
+usage += "\n  Related commands: link";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+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, grp);
+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, grp);
+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, grp);
+
+kw = "openppf";
+usage = "Reads all or some objects from a PPF file";
+usage += "\n  Usage: (1) openppf filename ";
+usage += "\n     Or  (2) openppf -s filename (2)";
+usage += "\n     Or  (3) openppf filename objname1 [ objname2 ...]";
+usage += "\n  The first form reads all objects at NameTags,";
+usage += "\n    or all objects if the file has no NameTags.";     
+usage += "\n  The third reads only the objects with the specified nametags";
+usage += "\n  Related commands: saveppf saveall savelist";  
+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 savelist saveall openppf";  
+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 savelist saveall openppf ";  
+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 savelist openppf";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "savelist";
+usage = "Saves a list of objects into a PPF file";
+usage = "\n Usage: savelist objname1 [objname2 ...] filename";
+usage += "\n  Related commands: saveobj openppf";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "ntfrascii";
+usage = "Fills an existing NTuple or DataTable 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 [prtlev]";
+usage += "\n prtlev = 0,1,2...  default: prtlev=0";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+
+//------- Commandes gestion de repertoires et d'objets
+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=*]  ";
+usage += "\n    Or  listobjs patt VarName ";
+usage += "\n   Obj. name pattern patt in the form abc?x* or /*/x?y ... ";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "ls";
+usage = " Alias for listobjs ";
+usage += "\n Usage: ls [patt=*] [VarName]";
+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");
+
+//------- Commandes creation/manipulation d'objets 
+kw = "newh1d";
+usage = "Creates a 1D histogramm \n Usage: newh1d name xmin xmax nbin";
+usage += "\n  Related commands: newh2d  newprof[e] newdt 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] newdt 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 newdt 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 newdt 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: newdt newh1d  newh2d newprof[e] newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newdt";
+usage = "Creates a datatable \n Usage: newdt name v1:t1 v2:t2 v3:t3 .. vn:tn";
+usage += "\n        newdt name nvar";  
+usage += "\n    vi : variable name";  
+usage += "\n    ti : variable type";  
+usage += "\n         r8,r4 for 8 and 4 bytes float";  
+usage += "\n         i8,i4 for 8 and 4 bytes signed integer";  
+usage += "\n         s for string";  
+usage += "\n  Related commands: newnt 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] newdt 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 = "objaoper";
+usage = "Perform an operation through the object adapter NObjMgrAdapter::PerformOperation()\n";
+usage += "  Usage: objaoper objname operation [arg1 ...] \n";
+usage += "  Examples of defined operations : \n";
+usage += "  Matrices: row indx_row , col indx_col \n";  
+usage += "  Arrays: slicexy indx_Z , slicexz indx_Y, sliceyz indxX \n";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+
+//------- Commandes trace de fonctions
+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");
+
+//------ Commandes trace d'expression
+kw = "ObjectExpressions";
+usage = "Any mathematical expression (math.h) with object variables can be used";
+usage += "\n  ------ Object Variable names (double) -------- ";
+usage += "\n  (_nl is the table line number or the sequential index)";
+usage += "\n- NTuple: ntuple variable names,_nl";
+usage += "\n- Histo1D/HProf: i,x,val,err,nb,_nl";
+usage += "\n- Histo2D: i,j,x,y,val,err,_nl";
+usage += "\n- HistoErr: i,x,val,err2,nb,_nl";
+usage += "\n- Histo2DErr: i,j,x,y,val,err2,nb,_nl";
+usage += "\n- Vector/Matrix: n,r,c,val,real,imag,mod,phas,_nl";
+usage += "\n- TArray: n,x,y,z,t,u,val,real,imag,mod,phas,_nl";
+usage += "\n- Image: i,j,x,y,val(=pix),_nl";
+usage += "\n- GeneralFitData: x0,ex0 x1,ex1 ...  xn,exn   y,ey   ok  ,_nl";
+usage += "\n- LocalMap/SphereThetaPhi/SphereHEALPix: ";
+usage += "\n-         i,k,val,real,imag,mod,phas,teta,phi,_nl";
+usage += "\n- FITS Binary/ASCII table: fits column names,_nl";
+#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,_nl";
+#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 plot3dw"; 
+usage += "\n         projh1d projh2d  projprof fillvec fillmtx "; 
+usage += "\n         fillnt fillgd1 fillgd2 ntloop exptovec ... ";
+grp = "Expr. Plotting";
+mpiac->RegisterHelp(kw, usage, grp);
+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 plot3dw 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 plot2dc plot3d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "plot2dc";
+usage = "Plots (2D) Y=g(Object) vs. X=f(Object) with Color ColIndex=h(Object) ";
+usage += "\n Usage: plot2dc nameobj f_X() g_Y() h_Col() [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)";
+usage += "\n Usage: plot3d nameobj f_X() g_Y() h_Z() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2d plot2de plot3dw ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "plot3dw";
+usage = "Plots (3D) Z=h(Object) vs. Y=g(Object) vs. X=f(Object) with Weight W=k(Object)  ";
+usage += "\n Usage: plot3d nameobj f_X() g_Y() h_Z() k_Wt() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2d plot2dw 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 = "expmeansig";
+usage = "Computes Mean/Sigma (+Min/Max) for an expression X=f(Object)";
+usage += "\n Usage: expmeansig nameobj f_X() [Cut() loop_param]";
+usage += "\n  Related commands: exptovec ntloop fillnt ObjectExpressions ..."; 
+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);
+}
+
Index: /tags/V_Nov2007/SophyaPI/PIext/basexecut.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/basexecut.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/basexecut.h	(revision 3445)
@@ -0,0 +1,38 @@
+// 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);
+  virtual bool  IsThreadable(string const & keyw);
+
+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_Nov2007/SophyaPI/PIext/contmodex.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/contmodex.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/contmodex.cc	(revision 3445)
@@ -0,0 +1,208 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PIext/contmodex.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/contmodex.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/contmodex.h	(revision 3445)
@@ -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> 
+#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_Nov2007/SophyaPI/PIext/cxxexecutor.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/cxxexecutor.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/cxxexecutor.cc	(revision 3445)
@@ -0,0 +1,897 @@
+#include "sopnamsp.h"
+#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);
+  }
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  return ( ExecuteCXX(toks) ); 
+
+} else if(kw == "c++execfrf") {
+  if(tokens.size()<1) {
+    cout<<"Usage: c++execfrf fileuser.cc [fileuserfct.cc]"<<endl;
+    return(1);
+  }
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  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(rc);
+  rc = Compile();  if(rc) return(rc);
+  rc = Link();     if(rc) return(rc);
+  rc = Call();     
+  return(rc);
+
+} 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);
+  }
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  rc = FillUserCode(toks,2);        if(rc) return(rc);
+  rc = FillUserFctFrS();            if(rc) return(rc);
+  rc = CrFile(tokens[0],tokens[1]); 
+  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);
+  }
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  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]); 
+  return rc;
+
+} else if(kw == "c++compile") {
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  if(tokens.size()>=1) rc = Compile(tokens[0]);
+  else                 rc = Compile();
+  return(rc);
+
+} else if(kw == "c++link") {
+  // Pour synchronisation d'execution simultanee
+  ZSync zs(mutx_cxxe);  zs.NOp(); 
+
+  if(tokens.size()>=2)      rc = Link(tokens[0],tokens[1]);
+  else if(tokens.size()>=1) rc = Link(tokens[0]);
+  else                      rc = Link();
+  return(rc);
+
+} 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-- */
+bool  CxxExecutor::IsThreadable(string const & kw)
+{
+if ( (kw == "c++exec") || (kw == "c++execfrf") || 
+     (kw == "c++create") || (kw == "c++createfrf") ||
+     (kw == "c++compile") || (kw == "c++link") )   return true;
+else return false;
+}
+
+/* --Methode-- */
+int  CxxExecutor::ExecuteCXX(string usercode,string userfct)
+{
+int rc=0;
+rc = FillUserCode(usercode,0); if(rc) return(rc);
+rc = FillUserFctFrS(userfct);  if(rc) return(rc);
+rc = CrFile();   if(rc) return(rc);
+rc = Compile();  if(rc) return(rc);
+rc = Link();     if(rc) return(rc);
+rc = Call();     if(rc) return(rc);
+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>"<<endl
+  <<"#include <fstream>"<<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
+  // Si on enleve sopnamsp.h (using namespace SOPHYA), il faudra accoler 
+  // SOPHYA:: à toutes les déclarations automatiques - Reza, 10/09/2004 
+  <<"//---- Sophya include files"<<endl
+  <<"#include \"sopnamsp.h\""<<endl  // using namespace SOPHYA
+  <<"#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 $(SOPHYABASEREP)/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 rc;
+}
+
+/* --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]);
+return ( mpiac->ExecuteCommand(key,arg,toks) );
+}
+
+/* --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_Nov2007/SophyaPI/PIext/cxxexecutor.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/cxxexecutor.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/cxxexecutor.h	(revision 3445)
@@ -0,0 +1,105 @@
+// 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>
+
+#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);
+  virtual bool  IsThreadable(string const & keyw);
+
+  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
+
+  // Mutex de controle de thread pour dynamic-link 
+  ZMutex mutx_cxxe;
+
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/cxxexecwin.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/cxxexecwin.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/cxxexecwin.cc	(revision 3445)
@@ -0,0 +1,412 @@
+// 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 "sopnamsp.h"
+#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_Nov2007/SophyaPI/PIext/cxxexecwin.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/cxxexecwin.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/cxxexecwin.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIext/dlftypes.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/dlftypes.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/dlftypes.h	(revision 3445)
@@ -0,0 +1,32 @@
+// 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 long long int_8_exprf;
+// ^- Doit etre le meme que dans (Services2NObjMgr::)LinkExprFunc,PrepareNTExpressionCFile
+typedef int (* PlotExprFunc) (int_8_exprf nl, double* x, double* rx, double* ry, double* rz, double* rt);
+typedef int (* NTLoopExprFunc) (int_8_exprf nl, double* x, double* rx, double* ry, double* rz, 
+                                double* rt, int_8_exprf nstart, int_8_exprf nend);
+
+// ---------- 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_Nov2007/SophyaPI/PIext/exclude
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/exclude	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/exclude	(revision 3445)
@@ -0,0 +1,4 @@
+userfitfunex.c
+nommatvecadapter.cc
+nomstladapter.cc
+pistlist.cc
Index: /tags/V_Nov2007/SophyaPI/PIext/exclude.peida
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/exclude.peida	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/exclude.peida	(revision 3445)
@@ -0,0 +1,5 @@
+modrecst.cc
+userfitfunex.c
+nommatvecadapter.cc
+nomstladapter.cc
+pistlist.cc
Index: /tags/V_Nov2007/SophyaPI/PIext/exclude_dpc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/exclude_dpc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/exclude_dpc	(revision 3445)
@@ -0,0 +1,5 @@
+modrecst.cc
+userfitfunex.c
+nommatvecadapter.cc
+nomstladapter.cc
+pistlist.cc
Index: /tags/V_Nov2007/SophyaPI/PIext/flowmodex.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/flowmodex.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/flowmodex.cc	(revision 3445)
@@ -0,0 +1,155 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaPI/PIext/flowmodex.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/flowmodex.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/flowmodex.h	(revision 3445)
@@ -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> 
+#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_Nov2007/SophyaPI/PIext/graphexecut.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/graphexecut.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/graphexecut.cc	(revision 3445)
@@ -0,0 +1,992 @@
+#include "sopnamsp.h"
+#include "piacmd.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "graphexecut.h"
+
+#include "strutilxx.h"
+
+#include "pistdimgapp.h"
+#include "nobjmgr.h"
+
+#include "nomgadapter.h"
+#include "piyfxdrw.h"
+#include "pibargraph.h"
+#include "pitxtdrw.h"
+
+
+
+/* --Methode-- */
+PIAGraphicExecutor::PIAGraphicExecutor(PIACmd* piac, NamedObjMgr* omg, PIStdImgApp* app)
+{
+mpiac = piac;
+mObjMgr = omg; 
+mImgApp = app;
+RegisterCommands();
+}
+
+PIAGraphicExecutor::~PIAGraphicExecutor()
+{
+}
+
+
+/* Macro pour tester si flag normalized coordinate est present */
+#define _CkBoolNC_(_jk_) ((tokens.size()>_jk_) && (tokens[_jk_] == "true")) ? true : false;
+
+
+/* --Methode-- */
+int PIAGraphicExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+// >>>>>>>>>>> Fenetre graphique , changement d'attributs graphiques 
+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->LockMutex();  // <ZThread> global event loop synchronisation 
+    mImgApp->SetZone(nx, ny);
+    mImgApp->UnlockMutex(true);  // <ZThread> global event loop synchronisation 
+  }
+}  
+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->LockMutex();   // <ZThread> global event loop synchronisation 
+    mImgApp->CreateGraphWin(nx, ny, sx, sy);
+    mImgApp->UnlockMutex(true); // <ZThread> global event loop synchronisation 
+  }
+}  
+else if (kw == "stacknext") { 
+  mImgApp->LockMutex();  // <ZThread> global event loop synchronisation 
+  mImgApp->StackWinNext(); 
+  mImgApp->UnlockMutex(true);  // <ZThread> global event loop synchronisation 
+}
+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); 
+}
+//---- Ajout d'elements graphiques
+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 == "addoval") || (kw == "addfoval") || 
+	 (kw == "addarrow") ) {
+  if (tokens.size() < 4) { 
+    if ( (kw == "addoval") || (kw == "addfoval") )
+      cout << "Usage  addoval/addfoval/addarrow xc yc dx dy [colatt] [fgnc]" << endl;  
+    else 
+      cout << "Usage: addline/addrect/addfrect/addarrow 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") || (kw == "addoval")) ? false : true;
+    if ( (kw == "addrect") || (kw == "addfrect") )
+      mImgApp->AddRectangle(xp1, yp1, xp2, yp2, sop, fgfill, fgnc);
+    else  mImgApp->AddOval(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);
+}
+  
+// >>>>>>>>>>>  Affichage des objets 
+else if ( (kw == "disp") || (kw == "surf") || (kw == "imag") || (kw == "imagnav") ) {
+  if (tokens.size() < 1) { cout << "Usage: disp/surf/imag/imagnav 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, false);
+  else if (kw == "imagnav")  mObjMgr->DisplayImage(tokens[0], opt, true);
+  }
+
+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], ph, false, tokens[7], false);
+  }
+else if ((kw == "nt2dcn")||(kw == "nt2dci")) {
+  if (tokens.size() < 4) { 
+    cout << "Usage: nt2dcn nameobj color varx vary [errx erry wt label opt]" << endl; 
+    return(0); 
+  }
+  while (tokens.size() < 9) tokens.push_back("");
+  string ph = "";
+  bool colidx = false;
+  if (kw == "nt2dci")  colidx = true;
+  mObjMgr->DisplayNT(tokens[0], tokens[2], tokens[3], ph, tokens[4], tokens[5], ph, 
+                     tokens[6], tokens[7], tokens[1], colidx, tokens[8], 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("");
+  string ph = "";
+  mObjMgr->DisplayNT(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5],
+                     tokens[6], tokens[7], tokens[8], ph, false, 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]);
+}
+else if (kw == "bargraph") return BarGraph(kw, tokens);
+else if (kw == "textdrawer") return TextDrawer(kw, tokens);
+
+// 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);
+  }
+
+
+else  { 
+  cerr << "PIAGraphicExecutor::Do() Erreur - Commande " << kw << " inconuue ! " << endl;    
+  return(-1);
+  }
+
+return(0);
+}
+
+/* --Methode-- */
+bool PIAGraphicExecutor::IsThreadable(string const & keyw)
+{
+  return false;	
+}
+
+
+/* --Methode-- */
+void PIAGraphicExecutor::RegisterCommands()
+{
+string kw, usage, grp;
+
+RegisterPIGraphicsHelp(mpiac);
+
+grp = "Graphics";
+string gdesc = "Basic graphics and object display commands";
+mpiac->AddHelpGroup(grp, gdesc);
+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, grp);
+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, grp);
+kw = "stacknext";
+usage = "Displays the next widget on stack window \n  Usage: stacknext";
+mpiac->RegisterCommand(kw, usage, this, grp);
+
+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 += "   or \"color=name\" \"fgcolor=name\" \"bgcolor=name\" ex: \"color=red\"\n";
+usage += ">> Lines: defline normalline thinline thickline dashedline thindashedline\n";
+usage += "          thickdashedline dottedline thindottedline thickdottedline\n";
+usage += "   or \"line=type,width\"   ex: \"line=dotted,7\"\n";
+usage += ">> Fonts:\n";
+usage += "   > 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 += "   > Names: deffont courierfont helveticafont timesfont symbolfont \n";
+usage += "   or \"font=name,type,size\"   ex: \"font=courrier,bolditalic,10\"\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 += "   or \"marker=type,size\"   ex: \"marker=plus,10\"\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 += "   or \"arrow=type,size\"   ex: \"arrow=arrowshaped,10\"\n";
+usage += "------ Specific options for image displays:\n";
+usage += ">> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32\n";
+usage += "                grey128  invgrey128  colrj128  colbr128\n";
+usage += "                red32cm  green32cm  blue32cm  yellow32cm\n";
+usage += "                orange32cm cyan32cm violet32cm\n";
+usage += "                midas_pastel midas_heat midas_rainbow3 midas_bluered\n";
+usage += "                midas_bluewhite midas_redwhite\n";
+usage += "                multicol16 multicol64\n";
+usage += ">> revcmap : reverse colorMap\n";
+usage += ">> ZoomFactors :  zoomxN   ex: zoomx1 zoomx2 zoomx3 ...\n";
+usage += "                  zoom/N   ex: 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\n";
+usage += "                   (ltyp=lin/log/sqrt/square)\n";
+usage += ">> autolut=alt[,ns[,min,max]] : AutoLut method selection \n";
+usage += "                   (alt=minmax/meansig/hispeak/histail)\n";
+usage += ">> invx,invy,exchxy : image axes configuration\n";
+usage += "--- General purpose options:\n";
+usage += ">> stat,stats / nsta,nstat,nostat,nostats : Toggle statistic display\n";
+usage += ">> title,tit / notitle,notit -> Toggle automatic title display\n";
+usage += ">> Choose display window: next same win stack inset\n";
+usage += ">> for Axes / Axe labels / LogScale / xylimits / defdrrect\n";
+usage += "       see setaxesatt command\n";
+usage += "\n";  
+usage += "   Related commands: setaxesatt setinsetlimits ";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+
+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: axesnone stdaxes=defaxes=boxaxes boxaxesgrid \n";
+usage += "         fineaxes fineaxesgrid centeredaxes finecenteredaxes \n"; 
+usage += "         centeredaxesgrid finecenteredaxesgrid\n"; 
+usage += "         axescenter=x0,y0 (only with centered axes, default \"axescenter=\")\n"; 
+usage += "         grid nogrid labels nolabels  \n"; 
+usage += "         ticks noticks minorticks nominorticks \n"; 
+usage += "         extticks intticks extintticks \n"; 
+usage += "         nbticks=X_NTicks,Y_NTicks  \n"; 
+usage += "         tickslen=MajTickLenFrac,MinTickLenFrac \n"; 
+usage += ">> Axe labels font size: fixedfontsize/autofontsize=fszf \n";
+usage += "         autofontsize=fsizef: Font size computed automatically \n";
+usage += "         fixedfontsize: Use font size attribute (BaseDrawer) \n";
+usage += ">> Scale type: 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, grp);
+
+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 \n ";
+usage += " Usage: setinsetlimits xmin xmax ymin ymax";
+usage += "\n  Related commands: graphicatt /inset";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+
+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, grp);
+
+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 = "addoval";
+usage = "Adds an oval (ellipse) to the current graphic object";
+usage += "\n centered on xc,yc - semi-axis ds,dy (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added rectangle"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addoval xc yc dx dy [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addfoval addline addarrow addfrect addcirc addfcirc";
+usage += "\n       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfoval";
+usage = "Adds a filled oval (ellipse) to the current graphic object";
+usage += "\n centered on xc,yc - semi-axis ds,dy (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added rectangle"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addfoval xc yc dx dy [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addoval addline addarrow addfrect addcirc addfcirc";
+usage += "\n       addcirc addfcirc 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, grp);
+
+kw = "addtitle";
+usage = "Set the title string (top title / bottom title) \n";
+usage += "   alias for settitle ";
+mpiac->RegisterCommand(kw, usage, this, grp);
+
+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, grp);
+
+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, grp);
+
+grp = "Obj. Display";
+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, grp);
+kw = "imag";
+usage = "Displays an object as an image \n Usage: imag nameobj [graphic_attributes]";
+usage += "\n  Related commands: disp imagnav surf nt2d nt3d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+kw = "imagnav";
+usage = "Displays an object as an image with the ImageNavigator viewer \n";
+usage += "Usage: imagnav nameobj [graphic_attributes]";
+usage += "\n  Related commands: disp imag surf nt2d nt3d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+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, grp);
+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 nt2dcn nt2dci nt3d  gfd2d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+kw = "nt2dcn";
+usage = "Displays Points (X-Y) [with error-bar / Weight / Label ] from an NTuple ";
+usage = "   with colors specified by a column content (as color names) ";
+usage += "\n Usage : nt2dcn nameobj color varx vary [errx erry wt label graphic_attributes]";
+usage += "\n  Related commands: disp  surf  nt2d nt2dci nt3d  gfd2d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+kw = "nt2dci";
+usage = "Displays Points (X-Y) [with error-bar / Weight / Label ] from an NTuple ";
+usage = "   with colors specified by a column content (as color index) ";
+usage += "\n Usage : nt2dci nameobj color varx vary [errx erry wt label graphic_attributes]";
+usage += "\n  Related commands: disp  surf  nt2d nt2dci nt3d  gfd2d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+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, grp);
+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, grp);
+
+kw = "bargraph";
+usage = "Bar-Graph view of a sequence of values ";
+usage += "\n Usage: bargraph ValueVarName [gr_opt]  ";
+usage += "\n    or  bargraph ValueVarName LabelVarName ColPosVarName [gr_opt] ";
+usage += "\n  ValueVarName,LabelVarName,ColPosVarName are PIACmd interpreter "; 
+usage += "\n     variable name (vectors) ";
+usage += "\n - ValueVarName: Sequence of values to be represented";
+usage += "\n - LabelVarName: Corresponding labels";
+usage += "\n - ColPosVarName: Corresponding colors or color,position pairs ";
+usage += "\n Use a dash (-) or ! as placeholder for LabelVarName/ColPosVarName";
+usage += "\n Specific graphic options: fill/nofill packfrac=value ";
+usage += "\n    horizontalbars/verticalbars  barvaluelabel/nobarvaluelabel";
+usage += "\n Related commands: disp nt2d vecplot ...";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+kw = "textdrawer";
+usage = "Multi line text darwer ";
+usage += "\n Usage : textdrawer LinesVarName AttVarName [gr_opt] ";
+usage += "\n  LinesVarName,AttVarName are PIACmd interpreter variables"; 
+usage += "\n - LinesVarName: Lines to be displayed";
+usage += "\n - AttVarName: Corresponding font/marker/color attributes";
+usage += "\n Use a dash (-) or ! as placeholder for AttVarName";
+usage += "\n Specific graphic options: frame/noframe";
+usage += "\n Related commands: disp ... ";  
+mpiac->RegisterCommand(kw, usage, this, grp);
+
+
+// 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, grp);
+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, grp);
+
+}
+
+
+/* --Methode-- */
+void PIAGraphicExecutor::RegisterPIGraphicsHelp(PIACmd* piac)
+// Methode pour enregistrer le Help des Widgets et Windows de piapp 
+{
+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>D : Shows the drawer manipulation pop-up menu \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 += "           (2-D histograms, contour plot ...) \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>D : Shows the drawer manipulation pop-up menu \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>O : Displays a specific control window (default: PIDrawerTools) \n";
+usage += "           (2-D histograms, contour plot ...) \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>D : Shows the drawer manipulation pop-up menu \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 += "  or by specifying a widget name samew=Widgetname \n";
+usage += "o The widget/window name can be specified (gr_att wname=Name) \n";
+usage += "o The overlay can be on a selected rectangle of the last \n";  
+usage += "  displayed widget (gr_att: inset  or inset=fxmin,fxmax,fymin,fymax) \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);
+}
+
+/* --Methode-- */
+int PIAGraphicExecutor::BarGraph(string& keyw, vector<string>& tokens)
+{
+  //PAS necessaire pour le moment-- if (kw != "bargraph") return 2;
+  if (tokens.size() < 1) { 
+    cout << "Usage: bargraph ValueVarName [gr_opt]" << endl;
+    cout << "   or  bargraph ValueVarName LabelVarName ColPosVarName [gr_opt]" << endl;
+    return(0); 
+  }
+  PIBarGraph* bgd = NULL; 
+  vector<string> barvals;
+  string gropt;
+  if (!mpiac->GetVar(tokens[0], barvals)) {
+    cout << "bargraph/Error: No variable with name " << tokens[0] << endl;
+    return(1);
+  }
+  if (tokens.size() < 3) {   
+    bgd = new PIBarGraph;
+    for(int k=0; k<barvals.size(); k++)
+      bgd->AddBar(atof(barvals[k].c_str()));
+    if (tokens.size() > 1)  gropt = tokens[1]; 
+  }
+  else {
+    vector<string> barlabs;
+    if (!mpiac->GetVar(tokens[1], barlabs)) {
+      cout << "bargraph/Warning: No variable with name "  << tokens[1] 
+           << " using Values as labels " << endl;
+      barlabs = barvals;
+    }
+    vector<string> barcols;
+    if (!mpiac->GetVar(tokens[2], barcols)) {
+      cout << "bargraph/Warning: No variable with name "  << tokens[1] 
+           << " using default attributes " << endl;
+      for(int kad=0; kad<barvals.size(); kad++) barcols.push_back("");
+    }
+    if ( (barvals.size() != barlabs.size()) || 
+	 (barvals.size() != barcols.size()) ) {
+      cout << "bargraph/Error: Variables " << tokens[0] << "," << tokens[1]
+	   << "," << tokens[2] << " have different sizes" << endl;
+      return(1);      
+    }
+    bgd = new PIBarGraph;
+    // Synchronisation necessaire a cause de PIGraphicAtt qui peuvent faire appel a des fontes (Pb Serveur X)
+    mImgApp->LockMutex();   // <ZThread> global event loop synchronisation 
+    for(int k=0; k<barvals.size(); k++) {
+      double id = k+1;
+      size_t p = barcols[k].find(',');
+      vector<string> sgra;
+      if (p < barcols[k].length()-1) {
+	mImgApp->ParseDisplayOption(barcols[k].substr(0, p), sgra);
+        id = atof(barcols[k].substr(p+1).c_str());
+      }
+      else  mImgApp->ParseDisplayOption(barcols[k], sgra);
+      PIGraphicAtt gracol(sgra);
+      bgd->AddBar(id, atof(barvals[k].c_str()), barlabs[k], gracol.GetColor());
+    }
+    mImgApp->UnlockMutex(true); // <ZThread> global event loop synchronisation 
+    if (tokens.size() > 3)  gropt = tokens[3]; 
+  }
+  string grname = "BarGraph";
+  mImgApp->DispScDrawer(bgd, grname, gropt); 
+  return 0;
+}
+
+/* --Methode-- */
+int PIAGraphicExecutor::TextDrawer(string& keyw, vector<string>& tokens)
+{
+  if (tokens.size() < 2) { 
+    cout << "Usage: textdrawer TextLinesVarName AttVarName [gr_opt]" << endl;
+    return(0); 
+  }
+  vector<string> txtlines;
+  if (!mpiac->GetVar(tokens[0], txtlines)) {
+    cout << "textdrawer/Error: No variable with name" << tokens[0] << endl;
+    return(1);
+  }
+  vector<string> lineatt;
+  if (!mpiac->GetVar(tokens[1], lineatt)) {
+    cout << "textdrawer/Warning: No variable with name" << tokens[1] 
+	 << " using default attributes " << endl;
+    for(int kad=0; kad<txtlines.size(); kad++) lineatt.push_back("");    
+  }
+  if ( (txtlines.size() != lineatt.size()) ) { 
+    cout << "textdrawer/Error: Variables " << tokens[0] << "," << tokens[1]
+	 << " have different sizes" << endl;
+    return(1);      
+  }
+  PITextDrawer* txd = new PITextDrawer;
+  // Synchronisation necessaire a cause de PIGraphicAtt qui peuvent faire appel a des fontes (Pb Serveur X)
+  mImgApp->LockMutex();   // <ZThread> global event loop synchronisation 
+  for(int k=0; k<txtlines.size(); k++) {
+    vector<string> sgra;
+    mImgApp->ParseDisplayOption(lineatt[k], sgra);
+    PIGraphicAtt gra(sgra);
+    txd->AddLine(txtlines[k], gra);
+  }
+  mImgApp->UnlockMutex(true); // <ZThread> global event loop synchronisation 
+  string grname = "TextDrawer";
+  string gropt = "inset ";
+  if (tokens.size() > 2)  gropt += tokens[2]; 
+  mImgApp->DispScDrawer(txd, grname, gropt); 
+  return 0;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/graphexecut.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/graphexecut.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/graphexecut.h	(revision 3445)
@@ -0,0 +1,31 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe executeur de commandes graphique pour piapp
+//                                   Reza 05/2005
+// (C) LAL-IN2P3/CNRS  DAPNIA/CEA
+
+#ifndef PIAGraphicExecutor_H_SEEN
+#define PIAGraphicExecutor_H_SEEN
+
+#include "piacmd.h"
+
+class PIAGraphicExecutor : public CmdExecutor {
+public :
+		PIAGraphicExecutor(PIACmd* piac, NamedObjMgr* omg, PIStdImgApp* app);
+  virtual	~PIAGraphicExecutor();
+  virtual int	Execute(string& keyw, vector<string>& args, string& toks);
+  virtual bool  IsThreadable(string const & keyw);
+
+protected :
+  void		RegisterCommands();
+  void          RegisterPIGraphicsHelp(PIACmd* piac);
+  int		BarGraph(string& keyw, vector<string>& args);
+  int		TextDrawer(string& keyw, vector<string>& args);
+
+  PIACmd* mpiac;
+  NamedObjMgr* mObjMgr;
+  PIStdImgApp* mImgApp;
+
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.cc	(revision 3445)
@@ -0,0 +1,1833 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <typeinfo>
+#include <iostream>
+#include <string>
+#include <list>
+#include <map>
+
+#include "sopnamsp.h"
+#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 "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"
+
+#include "zthread.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 = NULL;  // Repertoire pour les compilations / link dynamique
+
+// Pour gestion multithread 
+static ZMutex* myMutex = NULL;
+static bool myMtxLocked = false;   // if myMutex has been locked
+static bool obmWvis = false;  // true -> ObjMgrWindow() is active/visible
+static bool obmWUpdReq = false; // true -> ObjMgrWindow Update requested
+// ..................................................................
+// .... Classe NObjMgrSync ....
+class NObjMgrSync {
+public:
+  explicit NObjMgrSync(int sigbr) 
+  {
+    myMtxLocked = true;
+    myMutex->lock();
+    _sigbr = sigbr;
+  }
+  ~NObjMgrSync()
+  {
+    if (_sigbr == 1) myMutex->signal(); 
+    else  if (_sigbr == 2) myMutex->broadcast(); 
+    myMutex->unlock();
+    myMtxLocked = false;
+    if (obmWUpdReq) {
+      NamedObjMgr _momg;
+      _momg.UpdateObjMgrWindow(-1);
+      obmWUpdReq = false;
+    }
+  }
+  inline int NOp() { return _sigbr; } 
+
+  int _sigbr;
+};
+//.............................
+
+//++
+// 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(bool fgimgapp)
+{
+_fgimgapp = fgimgapp;
+if (fgOInit == 0) { 
+  myNObj = 0;
+  myDirId = 0;
+  myDirs = new NObjDirList;
+  myObjs = new NObjList;  
+  myVars = new DVList;
+  myMutex = new ZMutex;
+  currDir = new string("home");
+  string dirn = "home";
+  CreateDir_P(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "tmp";
+  CreateDir_P(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "autoc";
+  CreateDir_P(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "old";
+  CreateDir_P(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(*TmpDir);
+  }
+fgOInit++;
+}
+
+  
+/* --Methode-- */
+NamedObjMgr::~NamedObjMgr()
+{
+fgOInit--;
+if (fgOInit == 0)  {
+  string patt = "/*/*";
+  DelObjects(patt, true);
+  delete myObjs;
+  delete myDirs;
+  delete myVars;
+  delete myMutex;
+}
+}
+
+//++
+// 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);
+  }
+  NObjMgrSync zs(0); zs.NOp(); 
+#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);
+  }
+  NObjMgrSync zs(0); zs.NOp(); 
+#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);
+  }
+  NObjMgrSync zs(0); zs.NOp(); 
+#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("");
+  }
+  NObjMgrSync zs(0); zs.NOp(); 
+  //  cout << " DEBUG::GetVar " << *myVars << endl;
+  return(myVars->GetS(key));
+}
+
+/* --Methode-- */
+DVList& NamedObjMgr::GetVarList()
+{
+  //  cout << " DEBUG::GetVarList " << *myVars << endl;
+  NObjMgrSync zs(0); zs.NOp(); 
+  return(*myVars);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::CreateDir(string & dirname)
+{
+  NObjMgrSync zs(0); zs.NOp(); 
+  return CreateDir_P(dirname);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::CreateDir_P(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;
+  if ( !_fgimgapp )  myImgApp->LockMutex();
+  (myImgApp->ObjMgrW())->AddDirectory(str.c_str(), myDirId);
+  if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+}
+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); 
+  }
+NObjMgrSync zs(0); zs.NOp(); 
+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) {
+  if ( !_fgimgapp )  myImgApp->LockMutex();
+  if ((myImgApp->ObjMgrW())->GetCurDirId() == (*it).second.id) {
+    (myImgApp->ObjMgrW())->SetCurDir(*currDir);
+    obmWUpdReq = true;
+  }
+  (myImgApp->ObjMgrW())->DelDirectory((*it).second.id);
+  
+  if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+}
+myDirs->erase(it);
+if (verbeux) cout << "NamedObjMgr::DeleteDir() " << dirname << " deleted " << endl;  
+return(true);
+}
+
+/* --Methode-- */
+void NamedObjMgr::LockDir(string & dirname)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+dirname = *currDir;
+}
+
+/* --Methode-- */
+void NamedObjMgr::ListDirs(string & patt)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+CleanDir_P(dirname);
+}
+
+/* --Methode-- */
+void NamedObjMgr::CleanDir_P(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_P(*ii,true);
+
+if (obmWvis) UpdateObjMgrWindow_P(did);  // On met a jour la fenetre de gestion des objets
+}
+
+
+
+//++
+// 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)
+{
+  NObjMgrSync zs(0); zs.NOp(); 
+  return AddObj_P(obj, nom, crd);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::AddObj_P(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_P(nrep);  did =  myDirId; }
+  }
+
+// Si c'est le repertoire /autoc, on nettoie
+if (nrep == "autoc")  {
+  CleanDir_P(nrep);
+  }
+
+myNObj++;
+if ( !CheckName(nobj) ) {
+  sprintf(buff,"O%d", myNObj);
+  cout << "NamedObjMgr::AddObj() Name changed: " << nom << " -> " << buff << endl;
+  nobj = buff;
+}
+
+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_P(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_P(nom, nomnew);
+    }
+  else {  // Sinon, on remplace l'objet
+    cout << "NamedObjMgr::AddObj() - Replacing " << nom << endl;
+    DelObj_P(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 (obmWvis && (myImgApp != NULL)) {
+  if ( !_fgimgapp )  myImgApp->LockMutex();
+  if ( (myImgApp->ObjMgrW())->Visible() ) {
+    string oln = nobj + "  (T= " + no.obja->GetDataObjType() + ")" ; 
+    (myImgApp->ObjMgrW())->AddObjList(did, oln.c_str(), no.oid);
+  }
+  if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+}
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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_P(cloneobj , nom, crd) );
+}
+
+/* --Methode-- */
+bool NamedObjMgr::RenameObj(string & nom, string& nomnew)
+{
+  NObjMgrSync zs(0); zs.NOp(); 
+  return RenameObj_P(nom, nomnew);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::RenameObj_P(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 ( !CheckName(n2) ) {
+  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 (obmWvis && (myImgApp != NULL)) {
+  if ( !_fgimgapp )  myImgApp->LockMutex();
+  if ( (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 ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+}
+if (verbeux) 
+  cout << "NamedObjMgr::RenameObj() - Object " << nom << " renamed to " << nomnew << endl;
+return(true);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::CopyObj(string & nom, string& nomcp)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+if(nomcp.length()<=0)
+  {cout<<"NamedObjMgr::CopyObj() Error, copied obj name "<<nomcp<<" not valid"<<endl;
+  return(false);}
+NObjMgrAdapter* obnom = GetObjAdapter_P(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_P(obnomcp,nomcp,false) ) {delete obnomcp; return(false);}
+return true;
+}
+
+/* --Methode-- */
+bool NamedObjMgr::DelObj(string & nom, bool fgd)
+{
+  NObjMgrSync zs(0); zs.NOp(); 
+  return DelObj_P(nom, fgd);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::DelObj_P(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; 
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+  bool fglock = (_fgimgapp) ? false : true;
+  if (fglock) myImgApp->LockMutex();
+  for(ii=(*it).second.wrsid.begin(); ii != (*it).second.wrsid.end(); ii++) 
+      myImgApp->DelWRsId((*ii));
+  if (fglock) myImgApp->UnlockMutex(true);
+}
+delete (*it).second.obja;  // destruction de l'adaptateur 
+if (fgd) delete (*it).second.obj;
+
+if (obmWvis && (myImgApp != NULL)) {
+  if ( !_fgimgapp )  myImgApp->LockMutex();
+  if ( (myImgApp->ObjMgrW())->Visible() ) {
+    int olid = (*it).second.oid;
+    (myImgApp->ObjMgrW())->DelObjList(did, olid);
+  }
+  if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+}
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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_P(nom, true));
+else return(false);
+}
+
+/* --Methode-- */
+void NamedObjMgr::DelObjects(string & patt, bool fgd)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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_P(*ii, fgd);
+}
+
+/* --Methode-- */
+AnyDataObj* NamedObjMgr::GetObj(string & nom)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+return GetObj_P(nom);
+}
+
+/* --Methode-- */
+AnyDataObj* NamedObjMgr::GetObj_P(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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+return GetObjAdapter_P(nom);
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NamedObjMgr::GetObjAdapter_P(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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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(vector<string> & flnm_objname)
+// flnm_objname[0] = nom du fichier .ppf
+// flnm_objname[1...] = nom des tags des objects a lire
+{
+if(flnm_objname.size()<2) return;
+int nread=0;
+try {
+  PInPersist pis(flnm_objname[0]);
+  for(int i=1;i<flnm_objname.size();i++) {
+    bool ok = pis.GotoNameTag(flnm_objname[i]);
+    if(!ok) {
+      cout<<"NamedObjMgr::ReadObj(...) Unknown object: "<<flnm_objname[i]<<endl;
+      continue;
+    }
+    PPersist *ppobj = pis.ReadObject();;
+    if(ppobj==NULL) {
+      cout<<"NamedObjMgr::ReadObj(...) impossible to read "<<flnm_objname[i]<<endl;
+      continue;
+    }
+    AddObj(ppobj->DataObj(),flnm_objname[i],true);
+    nread++;
+    cout<<"NamedObjMgr::ReadObj(...) object "<<flnm_objname[i]<<" read from file "<<endl;
+  }
+} catch (IOExc iox) {
+  cerr<<"NamedObjMgr::ReadObj()/Error Exception - Msg= "<<iox.Msg()<<endl;
+}
+cout<<nread<<" objects have been read"<<endl;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::ReadObj(PInPersist& s, int num)
+{
+NObjMgrSync zs(0); zs.NOp();
+ReadObj_P(s, num); 
+}
+
+/* --Methode-- */
+void NamedObjMgr::ReadObj_P(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;
+int nbtags = 0;
+#ifdef SANS_EVOLPLANCK
+nbtags = s.NbTags();
+#else 
+nbtags = s.NbNameTags();
+#endif
+if ( (nbtags < 1) || (num >= nbtags) ) {
+  if (num >= 0) { 
+    cerr << "NamedObjMgr::ReadObj(PInPersist, " << num << "  Error! NbTags =" 
+         << 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_P(obj->DataObj(), nom, false);
+  nread++;
+}
+ 
+if (num < 0) { n0 = 0; n1 = 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.GotoNameTagNum(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_P(obj->DataObj(), nom, true);  nread++; }
+}
+
+cout << "NamedObjMgr::ReadObj(...) " << nread << " Objects read " << endl;
+return;
+}
+/* --Methode-- */
+void NamedObjMgr::ReadAll(string const & flnm, bool atnametags)
+  // Lit tous les objets d'un fichier PPF
+  // si atnametags == true -> objets avec nametags seulement
+  //    sinon, tous les objets sequentiellement
+{
+#ifdef SANS_EVOLPLANCK
+bool ok = true;
+PPersist* obj=NULL;
+
+PInPersist* ppin=NULL;
+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;
+if (!ok)  return;
+if (obj) {
+  string nom = servnobjm->FileName2Name(flnm);
+  AddObj(obj->DataObj(), nom, false);
+  }
+else ReadObj((*ppin), -1);
+delete ppin;
+#else
+try {
+  PInPersist pis(flnm);
+  if (atnametags && (pis.NbNameTags() >= 1))  { 
+    if (pis.NbNameTags() < pis.NbTopLevelObjects()) { 
+      cout << "NamedObjMgr::ReadAll()/Warning File " << flnm << " NbNameTags="
+	   << pis.NbNameTags() << " < NbTopLevelObjects= " 
+	   << pis.NbTopLevelObjects() << endl;
+      cout << " ... Reading " << pis.NbNameTags() << " objects at NameTags " ;
+    }
+    ReadObj(pis, -1);
+    return;
+  }
+
+  // On lit tous les objets sequentiellement ...
+  string nomr = servnobjm->FileName2Name(flnm);  
+  string nom = nomr;
+  string nums;
+  int kn = 1;
+  bool fgrdok = true;
+  while (fgrdok) {
+    try {
+      PPersist* obj = pis.ReadObject();
+      if (!obj) continue;
+      AddObj(obj->DataObj(), nom, false);
+      kn++;  nom = nomr + MuTyV(kn).Convert(nums);
+    }
+    catch (IOExc& iox) {
+      fgrdok = false;  
+    }
+  }
+  cout<<"NamedObjMgr::ReadAll(" << flnm << " ,seq) "<< kn-1 << " objects read from File" << endl;
+}
+catch (IOExc& iox) {
+  cerr << "NamedObjMgr::ReadAll()/Error Exception - Msg= " << iox.Msg() << endl;
+}
+#endif
+return;
+}
+
+
+/* --Methode-- */
+void NamedObjMgr::SaveObj(string & nom, POutPersist& s, bool keeppath)
+{
+  NObjMgrSync zs(0); zs.NOp(); 
+  SaveObj_P(nom, s, keeppath);
+}
+
+static int key_for_write = 5000;
+/* --Methode-- */
+void NamedObjMgr::SaveObj_P(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_P(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)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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_P(cn, (*pout), keeppath);
+  }
+delete pout;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SaveListObjects(vector<string> &liste)
+// Les n-1 premiers elements (liste[0 -> n-2]) contiennent
+// les noms des objects a mettre  dans le fichier ppf
+// dont le nom est le dernier argument (liste[n-1])
+{
+ NObjMgrSync zs(0); zs.NOp(); 
+
+ if(liste.size()<2) {
+   cerr<<"NamedObjMgr::SaveListObjects()/Error not enough argument"<<endl;
+   return;
+ }
+
+ // open ppf file
+ string ppfname = liste[liste.size()-1];
+ POutPersist* pout=NULL;
+ try {
+   pout = new POutPersist(ppfname);
+ } catch(IOExc iox) {
+   cerr<<"NamedObjMgr::SaveObjects()/Error Exception - Msg= "<<iox.Msg()<<endl;
+   return;
+ }
+ 
+ // put objects in ppf file
+ for(int i=0;i<liste.size()-1;i++) {
+   bool keeppath = (liste[i][0] == '/') ? true : false;
+   SaveObj_P(liste[i], (*pout), keeppath);
+ }
+
+ // close ppf file
+ delete pout;
+
+ return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SaveAll(string const& flnm)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+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_P(no, (*pout), true);
+  }
+delete pout;
+return;
+}
+
+
+
+/* --Methode-- */
+void NamedObjMgr::PrintObj(string& nom, int lev)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter_P(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, lev);
+
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::DisplayObj(string& nom, string dopt) 
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter_P(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);
+
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+bool fglock = (_fgimgapp) ? false : true;
+
+if (dr) { 
+  PIDrawer3D * dr3 = dynamic_cast<PIDrawer3D *>(dr);
+  if(dr3)  wrsid = myImgApp->Disp3DDrawer(dr3, n1, dopt, "", 0, fglock);
+  else wrsid = myImgApp->DispScDrawer( dr, n1, dopt, "", 0, fglock); 
+  }
+else if (arr) wrsid = myImgApp->DispImage(arr, n1, dopt, false, 0, fglock);
+
+AddWRsId_P(nom, wrsid);
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::DisplayImage(string& nom, string dopt, bool fgimagnav)
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter_P(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);
+
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+bool fglock = (_fgimgapp) ? false : true;
+
+int wrsid = 0;
+wrsid = myImgApp->DispImage(arr, n1, dopt, fgimagnav, 0, fglock);
+
+AddWRsId_P(nom, wrsid);
+return;
+}
+/* --Methode-- */
+void NamedObjMgr::DisplaySurf3D(string& nom, string dopt)
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter_P(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);
+
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+bool fglock = (_fgimgapp) ? false : true;
+
+int wrsid = 0;
+PISurfaceDrawer* sdr = new PISurfaceDrawer(arr, true, true, true);
+wrsid = myImgApp->Disp3DDrawer(sdr, n1, dopt, "", 0, fglock);
+AddWRsId_P(nom, 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& colornm, bool coloridx, string dopt, bool fg3d)
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+AnyDataObj* obj=GetObj_P(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);
+
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+bool fglock = (_fgimgapp) ? false : true;
+
+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, 0, fglock);  
+}
+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());
+  if (colornm.length() > 0) {   // Juin 2007 : gestion de nom de colonne pour la couleur
+    if (coloridx) pin->SelectColorByIndex(colornm.c_str());
+    else pin->SelectColorByName(colornm.c_str());
+  }
+  string titre = nmy + "%" + nmx;
+  wrsid = myImgApp->DispScDrawer( (PIDrawer*)pin, n1, dopt, titre, 0, fglock);
+  }
+
+AddWRsId_P(nom, 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.
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+AnyDataObj* obj=GetObj_P(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);
+ // Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+ bool fglock = (_fgimgapp) ? false : true;
+
+ 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,"",0,fglock);  
+} else {                   // display 2D
+  PIGenFitDat* pigfd = new PIGenFitDat(((GeneralFitData*)obj),false);
+  pigfd->SelectX(numvx);
+  pigfd->SelectErrBar(errx,erry);
+  wrsid = myImgApp->DispScDrawer((PIDrawer*)pigfd,n1,dopt,"",0,fglock);
+}
+
+AddWRsId_P(nom, 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
+{
+// Pas de display si option dopt = nodisp 
+if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+NObjMgrSync zs(0); zs.NOp(); 
+
+#ifdef SANS_EVOLPLANCK
+  cerr << " NamedObjMgr::DisplayVector() Error: Not implemented with PEIDA " << endl;
+#else
+
+if(!myImgApp) return; 
+
+AnyDataObj* obj;
+obj = GetObj_P(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_P(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);
+
+// Si appel venant de PIStdImgApp, il ne faut pas locker le Mutex global de la boucle d'evts
+bool fglock = (_fgimgapp) ? false : true;
+
+string title = ny + " (Y) vs. " + nx + " (X)";
+// display 2D
+myImgApp->DispScDrawer(vxydrw, title, dopt, "", 0, fglock);
+
+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-- */
+int NamedObjMgr::NameToOId(string & nom)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+return NameToOId_P(nom);
+}
+
+/* --Methode-- */
+int NamedObjMgr::NameToOId_P(string & nom)
+{
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+nom = '/' + r1 + '/' + n1;
+NObjList::iterator it = myObjs->find(nom);
+if (it == myObjs->end()) return(-1); 
+else return((*it).second.oid);
+}
+
+
+/* --Methode-- */
+void NamedObjMgr::AddWRsId(string & nom, int wrsid)
+{
+NObjMgrSync zs(0); zs.NOp(); 
+AddWRsId_P(nom, wrsid);
+}
+
+/* --Methode-- */
+void NamedObjMgr::AddWRsId_P(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;
+NObjMgrSync zs(0); zs.NOp();
+UpdateObjMgrWindow_P(did);
+}
+
+/* --Methode-- */
+void NamedObjMgr::SetObjMgrWindowVisibility(bool fgvis)
+{
+obmWvis = fgvis;
+}
+
+/* --Methode-- */
+void NamedObjMgr::UpdateObjMgrWindow_P(int did)
+{
+obmWUpdReq = false;
+obmWvis = false;
+if (!myImgApp)  return;
+if ( !_fgimgapp )  myImgApp->LockMutex();
+// On ne fait rien si la fenetre non visible ou autre repertoire courant ds fenetre
+if ( !(myImgApp->ObjMgrW())->Visible() || 
+     ( (did >= 0) && (myImgApp->ObjMgrW())->GetCurDirId() != did) ) {
+  if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+  return;
+  }
+
+// on change le repertoire courant de la fenetre si did<0
+if (did < 0) {
+  string cdir = *currDir;
+  cdir = '/' + cdir;
+  (myImgApp->ObjMgrW())->SetCurDir(cdir);
+  did = (myImgApp->ObjMgrW())->GetCurDirId();
+}
+
+(myImgApp->ObjMgrW())->ClearObjList();
+
+NObjList::iterator it;  
+string cn;
+int loid = 0;
+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() + ")" ;
+  loid = (*it).second.oid;
+  (myImgApp->ObjMgrW())->AddObj(cn.c_str(), loid);
+  }
+(myImgApp->ObjMgrW())->SelObjByOid(loid);
+
+(myImgApp->ObjMgrW())->SetSensitive();
+if ( !_fgimgapp )  myImgApp->UnlockMutex(true);
+obmWvis = true;
+return;
+}
+
+
+/* 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);
+}
+
+/* Nouvelle-Fonction */
+bool NamedObjMgr::CheckName(string const & nom)
+{
+if (nom.length() < 1) return false;
+if (! isalpha(nom[0]) ) return false;
+for(int k=0; k<nom.length(); k++)
+  if ((!isalnum(nom[k])) && (nom[k] != '_')) return false;
+return true;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nobjmgr.h	(revision 3445)
@@ -0,0 +1,139 @@
+// 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>
+#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(bool fgimgapp=false);
+  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          ReadObj(vector<string> & flnm_objname);
+  virtual void		ReadAll(string const & nomppf, bool atnametags=true);
+  virtual void          SaveObj(string & nom, POutPersist& s, bool keeppath=false);
+  virtual void          SaveObjects(string & patt, string const& nomppf);
+  virtual void          SaveListObjects(vector<string> &liste);
+  virtual void          SaveAll(string const& nomppf);
+
+// Info sur les objets 
+  virtual void          PrintObj(string & nom, int lev=0);
+
+//  Affichage des objets 
+  virtual void          DisplayObj(string & nom, string dopt="");
+  virtual void          DisplayImage(string & nom, string dopt="", bool fgimagnav=false);
+  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& colornm, bool coloridx=false, 
+				  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);
+
+// Pour convertir un nom d'objet en identificateur d'objet (OId)
+  virtual int           NameToOId(string & nom);
+
+// Ajoute un identificateur d'objet widget/drawer/fenetre pour l'objet nom
+// Ces identificateurs servent lors de la destruction de l'objet nom
+  virtual void		AddWRsId(string & nom, int wrsid);
+// Pour utilisation par ObjMgrWind
+  virtual void		UpdateObjMgrWindow(int did);
+  virtual void          SetObjMgrWindowVisibility(bool fgvis=false);
+
+// 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);
+// return true if name is valid
+  static bool CheckName(string const & nom);
+
+protected:
+  // Les methodes _P sont celles SANS ZSync() - pour un usage interne par NamedObjMgr
+  virtual bool		CreateDir_P(string & dirname);
+  virtual void		CleanDir_P(string & dirname);
+  virtual bool		AddObj_P(AnyDataObj* obj, string & nom, bool crd);
+  virtual bool		RenameObj_P(string & nom, string& nomnew);
+  virtual bool          DelObj_P(string & nom, bool fgd=true);
+  virtual AnyDataObj*	GetObj_P(string & nom);
+  virtual NObjMgrAdapter*	GetObjAdapter_P(string & nom);
+  virtual void		ReadObj_P(PInPersist& s, int num=-1);
+  virtual void          SaveObj_P(string & nom, POutPersist& s, bool keeppath=false);
+
+  virtual int           NameToOId_P(string & nom);
+  virtual void		AddWRsId_P(string & nom, int wrsid);
+  virtual void		UpdateObjMgrWindow_P(int did);
+
+  bool _fgimgapp;  // true -> cree par PIStdImgApp / pour gestion de thread
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.cc	(revision 3445)
@@ -0,0 +1,84 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+
+#include "nomdvladapter.h"
+
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) DVList 
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_DVList::NOMAdapter_DVList(DVList* o)
+  : NObjMgrAdapter(o)
+{
+mDvl = o;
+}
+
+/* --Methode-- */
+NOMAdapter_DVList::~NOMAdapter_DVList()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_DVList::Clone(AnyDataObj* o)
+{
+DVList* dvl = dynamic_cast<DVList *>(o);
+if (dvl) return ( new NOMAdapter_DVList(dvl) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_DVList::GetDataObjType()
+{
+  return ("DVList ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_DVList::CloneDataObj(bool)
+{
+  return new DVList(*mDvl);
+}
+
+/* --Methode-- */
+void NOMAdapter_DVList::SavePPF(POutPersist& pos, string const & nom)
+{
+  ObjFileIO<DVList> fio(mDvl);
+  fio.Write(pos, nom);
+  return;
+}
+
+/* --Methode-- */
+void NOMAdapter_DVList::Print(ostream& os, int lev)
+{
+  mDvl->Show(os);
+  if (lev > 1) mDvl->Print(os);
+}
+
+
+/* --Methode-- */
+string NOMAdapter_DVList::GetInfoString(vector<string>& opts)
+{
+if (opts.size() == 0) return NObjMgrAdapter::GetInfoString(opts); 
+char buff[128];
+if ((opts[0] == "nvar") || (opts[0] == "size")) {
+  sprintf(buff, "%d", mDvl->Size());
+  return string(buff);   
+}
+ else if (mDvl->HasKey(opts[0])) {
+   return mDvl->GetS(opts[0]);
+ }
+ else if (opts[0] == "?") 
+   return string("BaseDataTable.Att: nvar/size/VarName");
+ else {
+   cerr << "NOMAdapter_DVList::GetInfoString() - No such key=" << opts[0] 
+	<< " in DVList " << endl;
+   return string("");
+ }
+}
+
Index: /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomdvladapter.h	(revision 3445)
@@ -0,0 +1,39 @@
+// Adaptateur d objets (pour NamedObjMgr) pour DVList 
+//       R. Ansari , Avril 2007
+// (C) UPS-LAL(IN2P3/CNRS)             (C)  CEA-DAPNIA     
+ 
+#ifndef NOMDVLISTADAPTER_H_SEEN
+#define NOMDVLISTADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "dvlist.h"
+#include "sopnamsp.h"
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) DVList  
+//-------------------------------------------------------------------------
+
+class NOMAdapter_DVList : public NObjMgrAdapter {
+public:
+				NOMAdapter_DVList(DVList* dvl = NULL);
+  virtual			~NOMAdapter_DVList();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+// Returns a string with synthetic information about the object
+  virtual string                GetInfoString(vector<string>& opts);
+
+  virtual void			Print(ostream& os, int lev=0);
+
+protected:
+  DVList* mDvl;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomgadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomgadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomgadapter.cc	(revision 3445)
@@ -0,0 +1,148 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#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(buff,"%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-- */
+string NObjMgrAdapter::GetInfoString(vector<string>& /*opts*/)
+{
+char buff[128];
+sprintf(buff, "Type: %s @ %lx", typeid(*mObj).name(), (long)mObj);
+return(buff);
+}
+
+/* --Methode-- */
+int NObjMgrAdapter::PerformOperation(vector<string>& /*opts*/)
+{
+cout << "No operation defined for " << typeid(*mObj).name() << endl;
+return 1;
+}
+
+
+/* --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&, int /*lev*/)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::Print() " << typeid(*mObj).name() << hex 
+     << " @" << (unsigned long long)mObj << dec << 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_Nov2007/SophyaPI/PIext/nomgadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomgadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomgadapter.h	(revision 3445)
@@ -0,0 +1,77 @@
+// 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();
+
+// Returns a string with synthetic information about the object 
+// opts : additional optional argument 
+  virtual string                GetInfoString(vector<string>& opts);
+// Perform an operation on the object definded 
+// opts : operation definition 
+  virtual int                   PerformOperation(vector<string>& opts);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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_Nov2007/SophyaPI/PIext/nomgfdadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomgfdadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomgfdadapter.cc	(revision 3445)
@@ -0,0 +1,132 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#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, int)
+{
+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_Nov2007/SophyaPI/PIext/nomgfdadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomgfdadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomgfdadapter.h	(revision 3445)
@@ -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, int lev=0);
+  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_Nov2007/SophyaPI/PIext/nomherradapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomherradapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomherradapter.cc	(revision 3445)
@@ -0,0 +1,377 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+
+#include "nomherradapter.h"
+#include "pihisto.h"   /* Traceur pour Histo1D */
+#include "pihisto2d.h"   /* Traceur pour Histo2D */
+#include "sohiswrap.h"   /* Wrapper pour histos (HistoErr Histo2DErr ...) */
+
+#include "pipodrw.h"
+
+#include "servnobjm.h"
+
+#include "objfitter.h"
+#include "strutilxx.h"
+
+//-----------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet HistoErr
+//-----------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_HistoErr::NOMAdapter_HistoErr(HistoErr* o)
+  : NObjMgrAdapter(o)
+{
+mHerr = o;
+}
+
+/* --Methode-- */
+NOMAdapter_HistoErr::~NOMAdapter_HistoErr()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_HistoErr::Clone(AnyDataObj* o)
+{
+HistoErr* h = dynamic_cast<HistoErr *>(o);
+if (h) return ( new NOMAdapter_HistoErr(h) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_HistoErr::GetDataObjType()
+{
+return("HistoErr ");
+}
+
+/* --Methode-- */
+string NOMAdapter_HistoErr::GetInfoString(int lev)
+{
+  char buff[128];
+  string rs;
+  if (lev > 2) {
+    sprintf(buff, "HistoErr: NBin=%d XMin=%lg XMax=%lg\n", mHerr->NBins(), 
+	  mHerr->XMin(), mHerr->XMax());
+    rs += buff;
+  }
+  return rs;
+}
+
+/* --Methode-- */
+string NOMAdapter_HistoErr::GetInfoString(vector<string>& opts)
+{
+  string blabla = "HistoErr: nbin binw xmin xmax";
+         blabla += " sum sum2 sumn";
+
+  if(opts.size() == 0) return GetInfoString(3);
+
+  char buff[64];
+  if(opts[0] == "nbin") {
+    sprintf(buff, "%d",mHerr->NBins());
+  } else if(opts[0] == "binw") {
+    sprintf(buff, "%lg",mHerr->BinWidth());
+  } else if(opts[0] == "xmin") {
+    sprintf(buff, "%lg",mHerr->XMin());
+  } else if(opts[0] == "xmax") {
+    sprintf(buff, "%lg",mHerr->XMax());
+  } else if(opts[0] == "sum") {
+     sprintf(buff, "%lg",mHerr->Sum());
+  } else if(opts[0] == "sum2") {
+     sprintf(buff, "%lg",mHerr->Sum2());
+  } else if(opts[0] == "sumn") {
+     sprintf(buff, "%lg",mHerr->SumN());
+  } else {
+    return blabla;
+  }
+  return string(buff);
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_HistoErr::CloneDataObj(bool /*share*/)
+{
+  return( new HistoErr(*mHerr) );
+}
+
+/* --Methode-- */
+void NOMAdapter_HistoErr::SavePPF(POutPersist& pos, string const & nom)
+{
+ObjFileIO<HistoErr> fio(mHerr);
+fio.Write(pos, nom);
+}
+
+/* --Methode-- */
+void NOMAdapter_HistoErr::Print(ostream& os, int lev)
+{
+mHerr->Show(os);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_HistoErr::GetDrawer(string & dopt)
+{
+dopt = "thinline " + dopt;
+HistoErrWrapper* hw = new HistoErrWrapper(mHerr, false); // false: le Wrapper ne delete pas l'objet mHerr
+PIHisto * pih = new PIHisto(hw, true); // true: PIHisto delete l'objet HistoErrWrapper hw
+return( pih );
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_HistoErr::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_HistoErr(mHerr) );
+}
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_HistoErr::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+  cout<<"NOMAdapter_HistoErr::GetGeneralFitData: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+AnyDataObj* NOMAdapter_HistoErr::FitResidusObj(GeneralFit& mfit)
+{
+  cout<<"NOMAdapter_HistoErr::FitResidusObj: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+AnyDataObj* NOMAdapter_HistoErr::FitFunctionObj(GeneralFit& mfit)
+{
+  cout<<"NOMAdapter_HistoErr::FitFunctionObj: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_HistoErr::NTupInt_HistoErr(HistoErr* h)
+{
+mHerr  = h;
+}
+
+/* --Methode-- */
+NTupInt_HistoErr::~NTupInt_HistoErr()
+{
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_HistoErr::NbLines() const 
+{
+return(mHerr->NBins());
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_HistoErr::NbColumns() const
+{
+return(5);
+}
+
+/* --Methode-- */
+r_8* NTupInt_HistoErr::GetLineD(sa_size_t k) const
+{
+ int i;
+ if(k<0 || k>=mHerr->NBins()) {
+   for(i=0; i<5; i++)  mRet[i] = 0.;
+ } else { 
+   mRet[0] = k;  mRet[1] = mHerr->BinCenter(k);
+   mRet[2] = (*mHerr)(k); mRet[3] = mHerr->Error2(k);
+   mRet[4] = mHerr->NEntBin(k);
+ }
+ return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_HistoErr::VarList_C(const char* nx) const
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,x,val,err2,nb; \n";
+vardec += "i = " + nomx + "[0];  x = " + nomx + "[1]; \n";
+vardec += "val = " + nomx + "[2];  err2 = " + nomx + "[3]; \n";
+vardec += "nb = " + nomx + "[4]; \n";
+return(vardec);
+}
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo2DErr
+//-------------------------------------------------------------------------
+
+
+/* --Methode-- */
+NOMAdapter_Histo2DErr::NOMAdapter_Histo2DErr(Histo2DErr* o)
+  : NObjMgrAdapter(o)
+{
+mHerr = o;
+}
+
+/* --Methode-- */
+NOMAdapter_Histo2DErr::~NOMAdapter_Histo2DErr()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_Histo2DErr::Clone(AnyDataObj* o)
+{
+Histo2DErr* h = dynamic_cast<Histo2DErr *>(o);
+if (h) return ( new NOMAdapter_Histo2DErr(h) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_Histo2DErr::GetDataObjType()
+{
+return ("Histo2DErr ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_Histo2DErr::CloneDataObj(bool /*share*/)
+{
+return ( new Histo2DErr(*mHerr) );
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo2DErr::SavePPF(POutPersist& pos, string const & nom)
+{
+ObjFileIO<Histo2DErr> fio(mHerr);
+fio.Write(pos, nom);
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo2DErr::Print(ostream& os, int lev)
+{
+mHerr->Show(os);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Histo2DErr::GetDrawer(string & dopt)
+{
+dopt = "thinline " + dopt;
+return( new PIHisto2D(new Histo2DErrWrapper(mHerr, false), true) );
+}
+
+/* --Methode-- */
+P2DArrayAdapter* NOMAdapter_Histo2DErr::Get2DArray(string & dopt)
+{
+Histo2DErrWrapper* hwp = new Histo2DErrWrapper(mHerr, false);
+return hwp;
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_Histo2DErr::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Histo2DErr(mHerr) );
+}
+
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_Histo2DErr::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+  cout<<"NOMAdapter_Histo2DErr::GetGeneralFitData: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+AnyDataObj* NOMAdapter_Histo2DErr::FitResidusObj(GeneralFit& mfit)
+{
+  cout<<"NOMAdapter_Histo2DErr::FitResidusObj: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+AnyDataObj* NOMAdapter_Histo2DErr::FitFunctionObj(GeneralFit& mfit)
+{
+  cout<<"NOMAdapter_Histo2DErr::FitFunctionObj: NOT IMPLEMENTED"<<endl;
+  return NULL;
+}
+
+
+/* --Methode-- */
+string NOMAdapter_Histo2DErr::GetInfoString(vector<string>& opts)
+{
+  string blabla = "Histo2DErr: nbin binw xmin xmax ymin ymax";
+
+  if(opts.size() == 0) return blabla;
+
+  char buff[128];
+  if(opts[0] == "nbin") {
+    sprintf(buff, "%d %d",mHerr->NBinX(),mHerr->NBinY());
+  } else if(opts[0] == "binw") {
+    sprintf(buff, "%lg %lg",mHerr->WBinX(),mHerr->WBinY());
+  } else if(opts[0] == "xmin") {
+    sprintf(buff, "%lg",mHerr->XMin());
+  } else if(opts[0] == "xmax") {
+    sprintf(buff, "%lg",mHerr->XMax());
+  } else if(opts[0] == "ymin") {
+    sprintf(buff, "%lg",mHerr->YMin());
+  } else if(opts[0] == "ymax") {
+    sprintf(buff, "%lg",mHerr->YMax());
+  } else {
+    return blabla;
+  }
+  return string(buff);
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Histo2DErr::NTupInt_Histo2DErr(Histo2DErr* h)
+{
+mHerr = h;
+}
+
+/* --Methode-- */
+NTupInt_Histo2DErr::~NTupInt_Histo2DErr()
+{
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo2DErr::NbLines() const 
+{
+return(mHerr->NBinX()*mHerr->NBinY());
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo2DErr::NbColumns() const 
+{
+return(6);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Histo2DErr::GetLineD(sa_size_t n) const
+{
+int i,j;
+r_8 f2,f3;
+if(n<0 || n>=mHerr->NBinX()*mHerr->NBinY())
+    for(i=0; i<7; i++)  mRet[i] = 0.;
+else { 
+  i = n%mHerr->NBinX();  j = n/mHerr->NBinX(); 
+  mRet[0] = i;  mRet[1] = j;
+  mHerr->BinCenter(i,j,f2,f3);
+  mRet[2] = f2;  mRet[3] = f3;  
+  mRet[4] =  (*mHerr)(i,j);
+  mRet[5] = mHerr->Error2(i,j);
+  mRet[6] = mHerr->NEntBin(i,j);
+}
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_Histo2DErr::VarList_C(const char* nx) const
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,j,x,y,val,err2,nb; \n";
+vardec += "i = " + nomx + "[0];  j = " + nomx + "[1]; \n";
+vardec += "x = " + nomx + "[2];  y = " + nomx + "[3]; \n";
+vardec += "val = " + nomx + "[4];  err2 = " + nomx + "[5]; \n";
+vardec += "nb = " + nomx + "[6]; \n";
+return(vardec);
+}
+
Index: /tags/V_Nov2007/SophyaPI/PIext/nomherradapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomherradapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomherradapter.h	(revision 3445)
@@ -0,0 +1,113 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour HistoErr
+//             C. Magneville                    2007
+// (C) LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMHERRADAPTER_H_SEEN
+#define NOMHERRADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "histerr.h"
+#include "hist2err.h"
+
+//-----------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet HistoErr
+//-----------------------------------------------------------------------------
+
+class NOMAdapter_HistoErr : public NObjMgrAdapter {
+public:
+				NOMAdapter_HistoErr(HistoErr* h = NULL);
+  virtual			~NOMAdapter_HistoErr();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+// Returns a string with synthetic information about the object
+  virtual string                GetInfoString(int lev=0);
+
+  virtual string                GetInfoString(vector<string>& opts);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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:
+  HistoErr* mHerr;
+};
+
+// Class Interface NTuple pour HistoErr
+class NTupInt_HistoErr : public NTupleInterface {
+public:
+			NTupInt_HistoErr(HistoErr* h);
+  virtual		~NTupInt_HistoErr();
+  virtual sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  HistoErr* mHerr;
+  mutable r_8 mRet[5];
+};
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo2DErr
+//-------------------------------------------------------------------------
+
+class NOMAdapter_Histo2DErr : public NObjMgrAdapter {
+public:
+				NOMAdapter_Histo2DErr(Histo2DErr* h = NULL);
+  virtual			~NOMAdapter_Histo2DErr();
+
+  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, int lev=0);
+  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);
+
+  virtual string                GetInfoString(vector<string>& opts);
+
+protected:
+  Histo2DErr* mHerr;
+};
+
+// Class Interface NTuple pour Histo2DErr
+class NTupInt_Histo2DErr : public NTupleInterface {
+public:
+			NTupInt_Histo2DErr(Histo2DErr* h);
+  virtual		~NTupInt_Histo2DErr();
+  virtual sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Histo2DErr* mHerr;
+  mutable r_8 mRet[7];
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.cc	(revision 3445)
@@ -0,0 +1,793 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+
+#include "nomhistadapter.h"
+#include "pihisto.h"
+#include "sohiswrap.h"
+
+#include "pihisto2d.h"
+#include "pipodrw.h"
+
+#include "servnobjm.h"
+#include "strutilxx.h"
+
+#ifndef SANS_EVOLPLANCK
+#include "objfitter.h"
+// Pour les DataTable ( Depuis Avril 2005 )
+#include "datatable.h"
+#include "swppfdtable.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-- */
+string NOMAdapter_Histo::GetInfoString(int lev)
+{
+  char buff[128];
+  string rs;
+  if (lev > 2) {
+    sprintf(buff, "Histo: NBin=%d XMin=%lg XMax=%lg\n", mHis->NBins(), 
+	  mHis->XMin(), mHis->XMax());
+    rs += buff;
+  }
+  sprintf(buff, "Entries= %llu \n",mHis->NEntries());
+  rs += buff;
+  if (lev > 0) {
+    sprintf(buff, "Overflow= %lg \n", mHis->NOver());
+    rs += buff;
+    sprintf(buff, "Underflow= %lg \n", mHis->NUnder());
+    rs += buff;
+  } 
+  sprintf(buff, "Mean= %lg \n", mHis->Mean());
+  rs += buff;
+  sprintf(buff, "Sigma= %lg \n", mHis->Sigma());
+  rs += buff;
+  return rs;
+}
+
+/* --Methode-- */
+string NOMAdapter_Histo::GetInfoString(vector<string>& opts)
+{
+  string blabla = "Histo1D: nbin binw mean sigma over under nentries ndata";
+         blabla += " xmin xmax vmin vmax imin imax sum sum2";
+
+  if(opts.size() == 0) return GetInfoString(3);
+
+  char buff[64];
+  if(opts[0] == "nbin") {
+    sprintf(buff, "%d",mHis->NBins());
+  } else if(opts[0] == "binw") {
+    sprintf(buff, "%lg",mHis->BinWidth());
+  } else if(opts[0] == "mean") {
+    sprintf(buff, "%lg",mHis->Mean());
+  } else if(opts[0] == "sigma") {
+    sprintf(buff, "%lg",mHis->Sigma());
+  } else if(opts[0] == "over") {
+    sprintf(buff, "%lg",mHis->NOver());
+  } else if(opts[0] == "under") {
+    sprintf(buff, "%lg",mHis->NUnder());
+  } else if(opts[0] == "nentries") {
+    sprintf(buff, "%llu",mHis->NEntries());
+  } else if(opts[0] == "ndata") {
+    sprintf(buff, "%lg",mHis->NData());
+  } else if(opts[0] == "xmin") {
+    sprintf(buff, "%lg",mHis->XMin());
+  } else if(opts[0] == "xmax") {
+    sprintf(buff, "%lg",mHis->XMax());
+  } else if(opts[0] == "vmin") {
+    sprintf(buff, "%lg",mHis->VMin());
+  } else if(opts[0] == "vmax") {
+    sprintf(buff, "%lg",mHis->VMax());
+  } else if(opts[0] == "imin") {
+     sprintf(buff, "%d",mHis->IMin());
+  } else if(opts[0] == "imax") {
+     sprintf(buff, "%d",mHis->IMax());
+  } else if(opts[0] == "sum") {
+     sprintf(buff, "%lg",mHis->Sum());
+  } else if(opts[0] == "sum2") {
+     sprintf(buff, "%lg",mHis->Sum2());
+  } else {
+    return blabla;
+  }
+  return string(buff);
+}
+
+/* --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) return( new HProf(*hp) );
+else return( new Histo(*mHis) );
+}
+
+/* --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, int lev)
+{
+mHis->Show(os);
+if (lev > 0)  mHis->Print(60);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Histo::GetDrawer(string & dopt)
+{
+if (typeid(*mHis) == typeid(HProf))  dopt = "fcirclemarker5 " + dopt;
+else dopt = "thinline " + dopt;
+HistoWrapper* hw = new HistoWrapper(mHis, false); // false: le Wrapper ne delete pas l'objet Histo mHis
+PIHisto * pih = new PIHisto(hw, true); // true: PIHisto delete l'objet HistoWrapper hw
+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;
+mHpr  = dynamic_cast<HProf *>(h);
+}
+
+/* --Methode-- */
+NTupInt_Histo::~NTupInt_Histo()
+{
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo::NbLines() const 
+{
+return(mHis->NBins());
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo::NbColumns() const
+{
+return(5);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Histo::GetLineD(sa_size_t k) const
+{
+int i;
+if ((k < 0) || (k >= mHis->NBins())) 
+    for(i=0; i<5; i++)  mRet[i] = 0.;
+else { 
+  mRet[0] = k;  mRet[1] = mHis->BinCenter(k);
+  mRet[2] = (*mHis)(k); mRet[3] = mHis->Error(k);
+  if(mHpr) mRet[4] = mHpr->SumW(k); else mRet[4] = 0.;
+  }
+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,nb; \n";
+vardec += "i = " + nomx + "[0];  x = " + nomx + "[1]; \n";
+vardec += "val = " + nomx + "[2];  err = " + nomx + "[3]; \n";
+vardec += "nb = " + nomx + "[4]; \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, int lev)
+{
+mHis->Show(os);
+if (lev > 0)  mHis->Print();
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Histo2D::GetDrawer(string & dopt)
+{
+dopt = "thinline " + dopt;
+return( new PIHisto2D(new Histo2DWrapper(mHis, false), true) );
+}
+
+/* --Methode-- */
+P2DArrayAdapter* NOMAdapter_Histo2D::Get2DArray(string & dopt)
+{
+Histo2DWrapper* hwp = new Histo2DWrapper(mHis, false);
+return hwp;
+}
+
+/* --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-- */
+string NOMAdapter_Histo2D::GetInfoString(vector<string>& opts)
+{
+  string blabla = "Histo2D: nbin binw nband nslice nentries ndata xmin xmax";
+         blabla += " ymin ymax vmin vmax ijmin ijmax";
+
+  if(opts.size() == 0) return blabla;
+
+  char buff[128];
+  if(opts[0] == "nbin") {
+    sprintf(buff, "%d %d",mHis->NBinX(),mHis->NBinY());
+  } else if(opts[0] == "binw") {
+    sprintf(buff, "%lg %lg",mHis->WBinX(),mHis->WBinY());
+  } else if(opts[0] == "nband") {
+    sprintf(buff, "%d %d",mHis->NBandX(),mHis->NBandY());
+  } else if(opts[0] == "nslice") {
+    sprintf(buff, "%d %d",mHis->NSliX(),mHis->NSliY());
+  } else if(opts[0] == "nentries") {
+    sprintf(buff, "%d",mHis->NEntries());
+  } else if(opts[0] == "ndata") {
+    sprintf(buff, "%lg",mHis->NData());
+  } else if(opts[0] == "xmin") {
+    sprintf(buff, "%lg",mHis->XMin());
+  } else if(opts[0] == "xmax") {
+    sprintf(buff, "%lg",mHis->XMax());
+  } else if(opts[0] == "ymin") {
+    sprintf(buff, "%lg",mHis->YMin());
+  } else if(opts[0] == "ymax") {
+    sprintf(buff, "%lg",mHis->YMax());
+  } else if(opts[0] == "vmin") {
+    sprintf(buff, "%lg",mHis->VMin());
+  } else if(opts[0] == "vmax") {
+    sprintf(buff, "%lg",mHis->VMax());
+  } else if(opts[0] == "ijmin") {
+    int_4 i,j;
+     mHis->IJMin(i,j);
+     sprintf(buff, "%d %d",i,j);
+  } else if(opts[0] == "ijmax") {
+    int_4 i,j;
+     mHis->IJMax(i,j);
+     sprintf(buff, "%d %d",i,j);
+  } else {
+    return blabla;
+  }
+  return string(buff);
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Histo2D::NTupInt_Histo2D(Histo2D* h)
+{
+mHis = h;
+}
+
+/* --Methode-- */
+NTupInt_Histo2D::~NTupInt_Histo2D()
+{
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo2D::NbLines() const 
+{
+return(mHis->NBinX()*mHis->NBinY());
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Histo2D::NbColumns() const 
+{
+return(6);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Histo2D::GetLineD(sa_size_t 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::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-- */
+string NOMAdapter_NTuple::GetInfoString(vector<string>& opts)
+{
+if (opts.size() == 0) return NObjMgrAdapter::GetInfoString(opts); 
+char buff[128];
+if (opts[0] == "sizes") {
+  sprintf(buff, "%ld %ld", mNt->NEntry(), mNt->NVar());
+  return string(buff);   
+}
+else if ((opts[0] == "nlines") || (opts[0] == "nentry") || (opts[0] == "nrows")) {
+  sprintf(buff, "%ld", mNt->NEntry());
+  return string(buff);   
+}
+else if ((opts[0] == "nvar") || (opts[0] == "ncols")) {
+  sprintf(buff, "%ld", mNt->NVar());
+  return string(buff);   
+}
+else if (opts[0] == "info") { // Acces aux valeurs stockes ds le DVList Info()
+  if (opts.size() < 2)  return string(""); 
+  else if (mNt->Info().HasKey(opts[1]) == false) return string(""); 
+  else return mNt->Info().GetS(opts[1]);
+}
+else if (opts[0] == "row") { // Pour recuperer une ligne de la table
+  if (opts.size() < 2)  return string(""); 
+  sa_size_t num = atol(opts[1].c_str());
+  return mNt->LineToString(num);
+}
+else return "NTuple.Att: nlines/nentry/nrows nvar/ncols info.varname row.num";
+}
+
+/* --Methode-- */
+void NOMAdapter_NTuple::Print(ostream& os, int lev)
+{
+mNt->Show(os);
+if (lev > 2) os << mNt->Info();
+if (lev > 0) mNt->Print(0, 10*lev);
+}
+
+
+/* --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::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, int lev)
+{
+// os << mNt->Info();
+mNt->Show(os);
+}
+
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_XNTuple::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mNt);
+}
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet BaseDataTable
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_DataTable::NOMAdapter_DataTable(BaseDataTable* o)
+  : NObjMgrAdapter(o)
+{
+mDT = o;
+}
+
+/* --Methode-- */
+NOMAdapter_DataTable::~NOMAdapter_DataTable()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_DataTable::Clone(AnyDataObj* o)
+{
+  BaseDataTable* dt = dynamic_cast<BaseDataTable *>(o);
+  if (dt) return ( new NOMAdapter_DataTable(dt) );
+  else return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_DataTable::GetDataObjType()
+{
+  DataTable* dt = dynamic_cast<DataTable *>(mDT);
+  if (dt) return ("DataTable ");
+  else { 
+    SwPPFDataTable* swdt = dynamic_cast<SwPPFDataTable *>(mDT);
+    if (swdt) return ("SwPPFDataTable ");
+    return  ("BaseDataTable ");
+  }
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_DataTable::CloneDataObj(bool share)
+{
+  DataTable* dt = dynamic_cast<DataTable *>(mDT);
+  if (dt) return new DataTable(*dt, share);
+  else {
+    SwPPFDataTable* swdt = dynamic_cast<SwPPFDataTable *>(mDT);
+    if (swdt) cout << "NOMAdapter_DataTable::CloneDataObj() Object type SwPPFDataTable can not be cloned !" << endl;
+    return NULL;
+  }
+}
+
+
+/* --Methode-- */
+void NOMAdapter_DataTable::SavePPF(POutPersist& pos, string const & nom)
+{
+  DataTable* dt = dynamic_cast<DataTable *>(mDT);
+  SwPPFDataTable* swdt = dynamic_cast<SwPPFDataTable *>(mDT);
+  if (dt) { 	
+    ObjFileIO<BaseDataTable> fio(dt);
+    fio.Write(pos, nom);
+  }
+  else if (swdt) {
+    ObjFileIO<BaseDataTable> fio(swdt);
+    fio.Write(pos, nom);
+  }		
+  else {
+    cerr << " NOMAdapter_DataTable::SavePPF() Objet pas de type DataTable/SwPPFDataTable (nom="
+	 << nom << ")" << endl;
+  }
+}
+
+/* --Methode-- */
+string NOMAdapter_DataTable::GetInfoString(vector<string>& opts)
+{
+if (opts.size() == 0) return NObjMgrAdapter::GetInfoString(opts); 
+char buff[128];
+if (opts[0] == "sizes") {
+  sprintf(buff, "%ld %ld", mDT->NEntry(), mDT->NVar());
+  return string(buff);   
+}
+else if ((opts[0] == "nlines") || (opts[0] == "nentry") || (opts[0] == "nrows")) {
+  sprintf(buff, "%ld", mDT->NEntry());
+  return string(buff);   
+}
+else if ((opts[0] == "nvar") || (opts[0] == "ncols")) {
+  sprintf(buff, "%ld", mDT->NVar());
+  return string(buff);   
+}
+else if (opts[0] == "info") { // Acces aux valeurs stockes ds le DVList Info()
+  if (opts.size() < 2)  return string(""); 
+  else if (mDT->Info().HasKey(opts[1]) == false) return string(""); 
+  else return mDT->Info().GetS(opts[1]);
+}
+else if (opts[0] == "row") { // Pour recuperer une ligne de la table
+  if (opts.size() < 2)  return string(""); 
+  long num = atol(opts[1].c_str());
+  return mDT->TableRowToString(num, true);
+}
+
+else return "BaseDataTable.Att: nlines/nentry/nrows nvar/ncols info.varname row.num";
+}
+
+/* --Methode-- */
+void NOMAdapter_DataTable::Print(ostream& os, int lev)
+{
+mDT->Show(os);
+if (lev < 1) return;
+if (lev < 5)  mDT->Print(os, 0, lev*10);
+else mDT->Print(os);
+}
+
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_DataTable::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mDT);
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomhistadapter.h	(revision 3445)
@@ -0,0 +1,195 @@
+// 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"
+#include "basedtable.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			SavePPF(POutPersist& s, string const & nom);
+
+// Returns a string with synthetic information about the object
+  virtual string                GetInfoString(int lev=0);
+
+  virtual string                GetInfoString(vector<string>& opts);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Histo* mHis;
+  HProf* mHpr;
+  mutable r_8 mRet[5];
+};
+
+//-------------------------------------------------------------------------
+// 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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);
+
+  virtual string                GetInfoString(vector<string>& opts);
+
+protected:
+  Histo2D* mHis;
+};
+
+// Class Interface NTuple pour Histo2D
+class NTupInt_Histo2D : public NTupleInterface {
+public:
+			NTupInt_Histo2D(Histo2D* h);
+  virtual		~NTupInt_Histo2D();
+  virtual sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual string                GetInfoString(vector<string>& opts);
+  virtual void			Print(ostream& os, int lev=0);
+  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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  XNTuple* mNt;
+};
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet BaseDataTable 
+//-------------------------------------------------------------------------
+
+class NOMAdapter_DataTable : public NObjMgrAdapter {
+public:
+				NOMAdapter_DataTable(BaseDataTable* dt = NULL);
+  virtual			~NOMAdapter_DataTable();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual string                GetInfoString(vector<string>& opts);
+  virtual void			Print(ostream& os, int lev=0);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  BaseDataTable* mDT;
+};
+
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.cc	(revision 3445)
@@ -0,0 +1,258 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+
+#include "datatype.h"
+
+#include "nomimagadapter.h"
+#include "pimgadapter.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "fitsimage.h"
+#else
+#include "objfitter.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>::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, int lev)
+{
+if (lev < 3) mImg->Show(os, false);
+else  mImg->Show(os, true);
+if (lev > 0) mImg->Print(os, 10*lev);
+}
+
+
+/* --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>
+sa_size_t NTupInt_Image<T>::NbLines() const 
+{
+return( mImg->XSize() * mImg->YSize() );
+}
+
+/* --Methode-- */
+template <class T>
+sa_size_t NTupInt_Image<T>::NbColumns() const 
+{
+return(3);
+}
+
+/* --Methode-- */
+template <class T>
+r_8* NTupInt_Image<T>::GetLineD(sa_size_t 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 NOMAdapter_Image<r_8>
+#pragma define_template NTupInt_Image<uint_2>
+#pragma define_template NTupInt_Image<int_4>
+#pragma define_template NTupInt_Image<r_4>
+#pragma define_template NTupInt_Image<r_8>
+#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 NOMAdapter_Image<r_8>;
+template class NTupInt_Image<uint_2>;
+template class NTupInt_Image<int_4>;
+template class NTupInt_Image<r_4>;
+template class NTupInt_Image<r_8>;
+#ifdef SANS_EVOLPLANCK
+template class NOMAdapter_Image<int_2>;
+template class NTupInt_Image<int_2>;
+#endif
+#endif
+
+
Index: /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomimagadapter.h	(revision 3445)
@@ -0,0 +1,63 @@
+// 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Image<T> * mImg;
+  mutable r_8 mRet[3];
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nommatvecadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nommatvecadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nommatvecadapter.cc	(revision 3445)
@@ -0,0 +1,337 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#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, int)
+{
+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-- */
+sa_size_t NTupInt_Vector::NbLines() const
+{
+return(mVec->NElts());
+}
+
+/* --Methode-- */
+sa_size_t NTupInt_Vector::NbColumns() const 
+{
+return(2);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Vector::GetLineD(sa_size_t 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, int)
+{
+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-- */
+sa_size_t  NTupInt_Matrix::NbLines() const
+{
+return( mMtx->NRows()*mMtx->NCol() );
+}
+
+/* --Methode-- */
+sa_size_t  NTupInt_Matrix::NbColumns() const 
+{
+return(3);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Matrix::GetLineD(sa_size_t  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_Nov2007/SophyaPI/PIext/nommatvecadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nommatvecadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nommatvecadapter.h	(revision 3445)
@@ -0,0 +1,116 @@
+// 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Matrix* mMtx;
+  mutable r_8 mRet[3];
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomskymapadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomskymapadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomskymapadapter.cc	(revision 3445)
@@ -0,0 +1,409 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <math.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "nomskymapadapter.h"
+#include "skymap.h"
+#include "pitvmaad.h"
+#include "complexios.h"
+
+// Valeur par defaut pour la projection MolleWeide, en dehors de la sphere 
+static double _prjmol_defval = 0.;
+void Set_Project_Mol_DefVal(double def)
+{
+  _prjmol_defval = def;
+  return;
+}
+
+//  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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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< ";
+SphereECP<T>* se = dynamic_cast< SphereECP<T> * >(mMap); 
+if (se != NULL) type = "SphereECP< ";
+
+// 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) );
+SphereECP<T>* se = dynamic_cast< SphereECP<T> * >(mMap); 
+if (se != NULL) return( new SphereECP<T>(*se, share) );
+return(NULL);
+}
+
+
+/* --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;
+  }
+SphereECP<T>* se = dynamic_cast< SphereECP<T> * >(mMap); 
+if (se != NULL) {
+  FIO_SphereECP<T> fio(se);
+  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, int lev)
+{
+mMap->Show(os);
+if (lev > 0) {
+  T moy, sig;
+  MeanSig(moy, sig);
+  os << "PixelMap:  Mean= " << moy << "  Sig2= " << sig << endl;
+}
+if (lev > 1) {
+  int_4 nprmx = 10*lev;
+  if (nprmx > mMap->NbPixels()) nprmx = mMap->NbPixels();
+  os << "[k]   (Theta,Phi) :  PixVal" << endl; 
+  double t, p;
+  for(int k=0; k<nprmx; k++) {
+    mMap->PixThetaPhi(k, t, p);
+    os << "[" << k << "]  (" << t << "," << p << ") :  " << mMap->PixVal(k) << 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 & opt)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) return(new LocalMapArrAdapter<T>(lm, false));
+int nr = 250;
+int nc = 500;
+SphereECP<T>* se = dynamic_cast< SphereECP<T> * >(mMap); 
+size_t olen = opt.length();
+if ((se != NULL) && (opt.find("ecparray") < olen)) {
+  // On veut la carte bi-dim complete de la sphere ECP
+  TMatrix<T> * mtxecp = new TMatrix<T>(se->GetPixelArray(), true);  // on partage les donnees
+  POTMatrixAdapter<T> * potmtxecp = new POTMatrixAdapter<T>(mtxecp, true);
+  if (opt.find("ecpscaledeg") < olen)  // Echelle angulaire en degre
+    potmtxecp->DefineXYCoordinates(se->MinPhi()*180./M_PI, se->MinTheta()*180./M_PI, 
+				   se->DeltaPhi()*180./M_PI, se->DeltaTheta()*180./M_PI);
+  else if (opt.find("ecpscalerad") < olen)  // Echelle angulaire en radian
+    potmtxecp->DefineXYCoordinates(se->MinPhi(), se->MinTheta(), se->DeltaPhi(), se->DeltaTheta());
+
+  return ( potmtxecp );
+}
+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, (T)_prjmol_defval);
+POTMatrixAdapter<T> * potma = new POTMatrixAdapter<T>(mtx, true);
+potma->DefineXYCoordinates(0.,90.,360./(double)(mtx->NCols()),-180./(double)(mtx->NRows()));
+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> 
+sa_size_t NTupInt_PixelMap<T>::NbLines() const
+{
+return( mMap->NbPixels() );
+}
+
+/* --Methode-- */
+template <class T> 
+sa_size_t NTupInt_PixelMap<T>::NbColumns() const 
+{
+return(8);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_PixelMap<T>::GetLineD(sa_size_t 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);
+}
+
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_PixelMap< complex<float> >::GetLineD(sa_size_t 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);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_PixelMap< complex<double> >::GetLineD(sa_size_t 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_Nov2007/SophyaPI/PIext/nomskymapadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomskymapadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomskymapadapter.h	(revision 3445)
@@ -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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  PixelMap<T>* mMap;
+  mutable r_8 mRet[8];
+};
+
+// Valeur par defaut pour la projection MolleWeide, en dehors de la sphere 
+void Set_Project_Mol_DefVal(double def);
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomspecrespadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomspecrespadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomspecrespadapter.cc	(revision 3445)
@@ -0,0 +1,141 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#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, int)
+{
+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_Nov2007/SophyaPI/PIext/nomspecrespadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomspecrespadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomspecrespadapter.h	(revision 3445)
@@ -0,0 +1,36 @@
+// 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			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+//  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  SpectralResponse* mSR;
+};
+
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomstladapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomstladapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomstladapter.cc	(revision 3445)
@@ -0,0 +1,138 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#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, int)
+{
+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_Nov2007/SophyaPI/PIext/nomstladapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomstladapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomstladapter.h	(revision 3445)
@@ -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, int lev=0);
+  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_Nov2007/SophyaPI/PIext/nomtarradapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomtarradapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomtarradapter.cc	(revision 3445)
@@ -0,0 +1,507 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "nomtarradapter.h"
+#include "tvector.h"
+#include "pitvmaad.h"
+#include "piyfxdrw.h"
+
+#include "fioarr.h"
+
+#include "nobjmgr.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> 
+string NOMAdapter_TArray<T>::GetInfoString(vector<string>& opts)
+{
+  if (opts.size() == 0) return mArr->InfoString();
+  else {
+    char buff[128];
+    if (opts[0] == "rank") {
+      sprintf(buff,"%d", (int)mArr->Rank());
+      return string(buff);      
+    }
+    if (opts[0] == "sizes") {
+      string rs;
+      for(int_4 kd=0; kd<mArr->Rank(); kd++) {
+	sprintf(buff, "%ld ", (long)mArr->Size(kd)); 
+	rs += buff;
+      }
+      return rs;      
+    }
+    else if ((opts[0] == "size") || (opts[0] == "nelts")) {
+      sprintf(buff, "%ld", (long)mArr->Size()); 
+      return string(buff);
+    }
+    else if (opts[0] == "sum") {
+      MuTyV mtv(mArr->Sum());
+      string s;
+      return mtv.Convert(s);
+    }
+    else if (opts[0] == "sumsq") {
+      MuTyV mtv(mArr->SumSq());
+      string s;
+      return mtv.Convert(s);
+    }
+    else if (opts[0] == "norm2") {
+      MuTyV mtv(mArr->Norm2());
+      r_8 nrm2 = mtv.Convert(nrm2);  // we force the conversion to double
+      mtv = nrm2;
+      string s;
+      return mtv.Convert(s);
+    }
+    else if ((opts[0] == "min")||(opts[0] == "max")||(opts[0] == "minmax")) {
+      T amin, amax;
+      MuTyV mtv;
+      string s;
+      mArr->MinMax(amin, amax);
+      if (opts[0] == "minmax") {
+	mtv = amin;  mtv.Convert(s);
+	s += " ";
+	string mms;
+	mtv = amax;  mtv.Convert(mms);
+	s += mms;
+      }
+      else {
+	if (opts[0] == "min")  mtv = amin;
+	else if (opts[0] == "max")  mtv = amax;
+	mtv.Convert(s); 
+      }
+      return s;
+    }
+    else if (opts[0] == "info") { // Acces aux valeurs stockes ds le DVList Info()
+      if (opts.size() < 2)  return string(""); 
+      else if (mArr->Info().HasKey(opts[1]) == false) return string(""); 
+      else return mArr->Info().GetS(opts[1]);
+    }
+    else return "TArray.Att: rank sizes size/nelts sum sumsq/norm2 min max minmax";
+  }
+}
+
+/* --Methode-- */
+template <class T> 
+int NOMAdapter_TArray<T>::PerformOperation(vector<string>& opts)
+{
+  bool ok = false;
+  if ((mArr->Rank() >= 3) && (opts.size() >= 2)) {
+    int_4 ks = atoi(opts[1].c_str());
+    TMatrix<T> * slice = new TMatrix<T>;
+    char buff[40];
+    if (opts[0] == "slicexy") {
+      slice->Share(mArr->SubArray(Range::all(), Range::all(), Range(ks), 
+				  Range::first(), Range::first()) );  
+      ok = true; 
+      sprintf(buff,"slicexy_%ld",(long)ks);
+      cout << "PerformOperation(): Extracting SliceXY(" << ks << ") from array" << endl;
+    }
+    else if (opts[0] == "sliceyz") {
+      slice->Share(mArr->SubArray(Range(ks), Range::all(), Range::all(), Range::first(), 
+				  Range::first()).CompactAllDimensions() );  
+      ok = true; 
+      sprintf(buff,"sliceyz_%ld",(long)ks);
+      cout << "PerformOperation(): Extracting SliceYZ(" << ks << ") from array" << endl;
+    }
+    else if (opts[0] == "slicexz") {
+      slice->Share(mArr->SubArray(Range::all(), Range(ks), Range::all(), Range::first(), 
+				  Range::first()).CompactAllDimensions() );  
+      ok = true; 
+      sprintf(buff,"slicexz_%ld",(long)ks);
+      cout << "PerformOperation(): Extracting SliceYZ(" << ks << ") from array" << endl;
+    }
+    if (ok) {
+      string nslice;
+      if (opts.size() > 2)  nslice = opts[2];
+      else nslice = buff;
+      NamedObjMgr omg;
+      omg.AddObj(slice, nslice, true); 
+      return 0;
+    }
+  }
+  
+  cout << "NOMAdapter_TArray<T>::PerformOperation(): Error operation/arguments !" << endl;
+  cout << "...Valid args: slicexy idxZ [slicename], sliceyz idxX [nm] slicexz idxY [nm]" << endl;
+  return 1; 
+}
+
+/* --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, int lev)
+{
+if (lev < 3) mArr->Show(os, false);
+else  mArr->Show(os, true);
+if (lev > 0) mArr->Print(os, 10*lev);
+}
+
+/* --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> 
+sa_size_t NTupInt_TArray<T>::NbLines() const
+{
+return( mArr->Size() );
+}
+
+/* --Methode-- */
+template <class T> 
+sa_size_t NTupInt_TArray<T>::NbColumns() const 
+{
+return(11);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8 NTupInt_TArray<T>::GetCell(sa_size_t n, sa_size_t k) const
+{
+  if ((n < 0) || (n >= (int)(mArr->Size()) ) ) 
+    return 0.;
+  if ((k < 0) || (k > 10))  return 0.;
+  GetLineD(n);
+  return mRet[k];
+}
+
+/* --Methode-- */
+template <class T> 
+sa_size_t NTupInt_TArray<T>::ColumnIndex(string const & nom)  const 
+{
+string vardec = "double n,x,y,z,t,u,val,real,imag,mod,phas; \n";
+ if (nom == "n") return 0;
+ else if (nom == "x") return 1;
+ else if (nom == "y") return 2;
+ else if (nom == "z") return 3;
+ else if (nom == "t") return 4;
+ else if (nom == "u") return 5;
+ else if (nom == "val") return 6;
+ else if (nom == "real") return 7;
+ else if (nom == "imag") return 8;
+ else if (nom == "mod") return 9;
+ else if (nom == "phase") return 10;
+ else return -1;
+}
+
+/* --Methode-- */
+template <class T> 
+void NTupInt_TArray<T>::GetMinMax(sa_size_t k, double& min, double& max) const
+{
+  if (k == 0) {
+    min = 0.; max = (r_8)(mArr->Size());  }
+  else if (k == 1) {
+    min = 0.; max = (r_8)(mArr->SizeX());  }
+  else if (k == 2) {
+    min = 0.; max = (r_8)(mArr->SizeY());  }
+  else if (k == 3) {
+    min = 0.; max = (r_8)(mArr->SizeZ());  }
+  else if (k == 4) {
+    min = 0.; max = (r_8)(mArr->Size(3));  }
+  else if (k == 5) {
+    min = 0.; max = (r_8)(mArr->Size(4));  }
+  else if ((k == 6) || (k == 7) || (k == 9)) {
+    T tmin, tmax;
+    mArr->MinMax(tmin, tmax);
+    min = (r_8)(tmin); 
+    max = (r_8)(tmax); 
+  }
+  else { min = max = 0.; }
+  return;
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_TArray<T>::GetLineD(sa_size_t 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[6];  mRet[8] = 0.;
+  mRet[9] = mRet[6];  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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_TArray< complex<r_4> >::GetLineD(sa_size_t 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[6] = mRet[9] = sqrt(mRet[7]*mRet[7]+mRet[8]*mRet[8]);
+  mRet[10] = atan2(mRet[8], mRet[7]);
+}
+return(mRet);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_TArray< complex<r_8> >::GetLineD(sa_size_t 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[6] = mRet[9] = sqrt(mRet[7]*mRet[7]+mRet[8]*mRet[8]);
+  mRet[10] = atan2(mRet[8], mRet[7]);
+}
+return(mRet);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void NTupInt_TArray< complex<r_4> >::GetMinMax(sa_size_t k, double& min, double& max) const
+{
+  if (k == 0) {
+    min = 0.; max = (r_8)(mArr->Size());  }
+  else if (k == 1) {
+    min = 0.; max = (r_8)(mArr->SizeX());  }
+  else if (k == 2) {
+    min = 0.; max = (r_8)(mArr->SizeY());  }
+  else if (k == 3) {
+    min = 0.; max = (r_8)(mArr->SizeZ());  }
+  else if (k == 4) {
+    min = 0.; max = (r_8)(mArr->Size(3));  }
+  else if (k == 5) {
+    min = 0.; max = (r_8)(mArr->Size(4));  }
+  else if ((k >= 6) || (k <= 9)) {
+    r_8 tmin[3] = {9.e39,9.e39,9.e39};
+    r_8 tmax[3] = {-9.e39,-9.e39,-9.e39};
+    for(sa_size_t jj=0; jj<mArr->Size(); jj++) {
+      sa_size_t ix, iy, iz, it, iu;
+      mArr->IndexAtPosition(jj, ix, iy, iz, it, iu);
+      r_8 cv[3];
+      cv[0] = (*mArr)(ix,iy,iz,it,iu).real();
+      cv[1] = (*mArr)(ix,iy,iz,it,iu).imag();
+      cv[2] = sqrt(cv[0]*cv[0]+cv[1]*cv[1]);
+      for(int i=0; i<3; i++) {
+	if (cv[i] < tmin[i]) tmin[i] = cv[i];
+	if (cv[i] > tmax[i]) tmax[i] = cv[i];
+      }
+    }
+    if (k == 7) { min = tmin[0]; max = tmax[0]; }
+    else if (k == 8) { min = tmin[0]; max = tmax[0]; }
+    else { min = tmin[2]; max = tmax[2]; }
+  }
+  else { min = max = 0.; }
+  return;
+}
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void NTupInt_TArray< complex<r_8> >::GetMinMax(sa_size_t k, double& min, double& max) const
+{
+  if (k == 0) {
+    min = 0.; max = (r_8)(mArr->Size());  }
+  else if (k == 1) {
+    min = 0.; max = (r_8)(mArr->SizeX());  }
+  else if (k == 2) {
+    min = 0.; max = (r_8)(mArr->SizeY());  }
+  else if (k == 3) {
+    min = 0.; max = (r_8)(mArr->SizeZ());  }
+  else if (k == 4) {
+    min = 0.; max = (r_8)(mArr->Size(3));  }
+  else if (k == 5) {
+    min = 0.; max = (r_8)(mArr->Size(4));  }
+  else if ((k >= 6) || (k <= 9)) {
+    r_8 tmin[3] = {9.e39,9.e39,9.e39};
+    r_8 tmax[3] = {-9.e39,-9.e39,-9.e39};
+    for(sa_size_t jj=0; jj<mArr->Size(); jj++) {
+      sa_size_t ix, iy, iz, it, iu;
+      mArr->IndexAtPosition(jj, ix, iy, iz, it, iu);
+      r_8 cv[3];
+      cv[0] = (*mArr)(ix,iy,iz,it,iu).real();
+      cv[1] = (*mArr)(ix,iy,iz,it,iu).imag();
+      cv[2] = sqrt(cv[0]*cv[0]+cv[1]*cv[1]);
+      for(int i=0; i<3; i++) {
+	if (cv[i] < tmin[i]) tmin[i] = cv[i];
+	if (cv[i] > tmax[i]) tmax[i] = cv[i];
+      }
+    }
+    if (k == 7) { min = tmin[0]; max = tmax[0]; }
+    else if (k == 8) { min = tmin[0]; max = tmax[0]; }
+    else { min = tmin[2]; max = tmax[2]; }
+  }
+  else { min = max = 0.; }
+  return;
+}
+
+#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<int_8>
+#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<int_8>
+#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<int_8>;
+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<int_8>;
+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_Nov2007/SophyaPI/PIext/nomtarradapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomtarradapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomtarradapter.h	(revision 3445)
@@ -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 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);
+
+// Returns a string with synthetic information about the object 
+// opts : additional optional argument 
+  virtual string                GetInfoString(vector<string>& opts);
+// Perform an operation on the object definded 
+// opts : operation definition 
+  virtual int                   PerformOperation(vector<string>& opts);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8		GetCell(sa_size_t n, sa_size_t k) const ;
+  virtual sa_size_t     ColumnIndex(string const & nom)  const ;
+  virtual void		GetMinMax(sa_size_t k, double& min, double& max)   const ; 
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  TArray<T>* mArr;
+  mutable r_8 mRet[11];
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/nomtmatvecadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomtmatvecadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomtmatvecadapter.cc	(revision 3445)
@@ -0,0 +1,529 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "tvector.h"
+#include "objfitter.h"
+#include "nomtmatvecadapter.h"
+#include "piyfxdrw.h"
+#include "pitvmaad.h"
+
+#include "cimage.h"       // Pour la prise en charge des Image<T> (Avr 2007)
+#include "pimgadapter.h"  // Adaptateur de tableaux PIImage pour Image<T>
+
+#include "fioarr.h"
+
+#include "nobjmgr.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< ";
+else {
+  Image<T>* img = dynamic_cast<Image<T> *>(mMtx);
+  if (img != NULL) type = "Image< ";
+}
+// 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 {
+  Image<T>* img = dynamic_cast<Image<T> *>(mMtx);
+  if (img != NULL) return ( new Image<T>(*img, share) );
+  else return ( new TMatrix<T>(*mMtx, share) );
+}
+
+}
+
+/* --Methode-- */
+template <class T> 
+string NOMAdapter_TMatrix<T>::GetInfoString(vector<string>& opts)
+{
+  if (opts.size() == 0) return mMtx->InfoString();
+  else {
+    if (opts[0] == "rank") return string("2");
+    else if (opts[0] == "sizes") {
+      char buff[64];
+      TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+      if (v != NULL) sprintf(buff, "%ld", (long)mMtx->Size());
+      else sprintf(buff, "%ld %ld", (long)mMtx->NRows(), (long)mMtx->NCols()); 
+      return string(buff);
+    }
+    else if ((opts[0] == "size") || (opts[0] == "nelts")) {
+      char buff[32];
+      sprintf(buff, "%ld", (long)mMtx->Size()); 
+      return string(buff);
+    }
+    else if ((opts[0] == "nrow") || (opts[0] == "nrows")) {
+      char buff[32];
+      sprintf(buff, "%ld", (long)mMtx->NRows()); 
+      return string(buff);
+    }
+    else if ((opts[0] == "ncol") || (opts[0] == "ncols")) {
+      char buff[32];
+      sprintf(buff, "%ld", (long)mMtx->NCols()); 
+      return string(buff);
+    }
+    else if (opts[0] == "sum") {
+      MuTyV mtv(mMtx->Sum());
+      string s;
+      return mtv.Convert(s);
+    }
+    else if (opts[0] == "sumsq") {
+      MuTyV mtv(mMtx->SumSq());
+      string s;
+      return mtv.Convert(s);
+    }
+    else if (opts[0] == "norm2") {
+      MuTyV mtv(mMtx->Norm2());
+      r_8 nrm2 = mtv.Convert(nrm2);  // we force the conversion to double
+      mtv = nrm2;
+      string s;
+      return mtv.Convert(s);
+    }
+    else if ((opts[0] == "min")||(opts[0] == "max")||(opts[0] == "minmax")) {
+      T amin, amax;
+      MuTyV mtv;
+      string s;
+      mMtx->MinMax(amin, amax);
+      if (opts[0] == "minmax") {
+	mtv = amin;  mtv.Convert(s);
+	s += " ";
+	string mms;
+	mtv = amax;  mtv.Convert(mms);
+	s += mms;
+      }
+      else {
+	if (opts[0] == "min")  mtv = amin;
+	else if (opts[0] == "max")  mtv = amax;
+	mtv.Convert(s); 
+      }
+      return s;
+    }
+    else if (opts[0] == "info") { // Acces aux valeurs stockes ds le DVList Info()
+      if (opts.size() < 2)  return string(""); 
+      else if (mMtx->Info().HasKey(opts[1]) == false) return string(""); 
+      else return mMtx->Info().GetS(opts[1]);
+    }
+    else return "TMatrix.Att: rank size/nelts nrow/nrows ncol/ncols sum sumsq norm2 min max minmax info.varname";
+  }
+}
+
+/* --Methode-- */
+template <class T> 
+int NOMAdapter_TMatrix<T>::PerformOperation(vector<string>& opts)
+{
+  bool ok = false;
+  if (opts.size() >= 2) {
+    int_4 kk = atoi(opts[1].c_str());
+    TVector<T> * vrc = new TVector<T>;
+    char buff[40];
+    if ((opts[0] == "row") || (opts[0] == "line")) { 
+      vrc->Share(mMtx->Row((sa_size_t)kk));  
+      ok = true; 
+      sprintf(buff,"row_%ld",(long)kk);
+      cout << "PerformOperation(): Extracting Row(" << kk << ") from matrix" << endl;
+    }
+    else if ((opts[0] == "col") || (opts[0] == "column")) { 
+      vrc->Share(mMtx->Column((sa_size_t)kk));  
+      ok = true; 
+      sprintf(buff,"col_%ld",(long)kk);
+      cout << "PerformOperation(): Extracting Column(" << kk << ") from matrix" << endl;
+    }
+    if (ok) {
+      string nvrc;
+      if (opts.size() > 2)  nvrc = opts[2];
+      else nvrc = buff;
+      NamedObjMgr omg;
+      omg.AddObj(vrc, nvrc, true); 
+      return 0;
+    }
+  }
+  
+  cout << "NOMAdapter_TMatrix<T>::PerformOperation(): Error operation/arguments !" << endl; 
+  cout << "...Valid args: row/line r [rowname] , col/column c [rowname]" << endl;
+  return 1; 
+}
+
+/* --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 {
+  Image<T>* img = dynamic_cast<Image<T> *>(mMtx);
+  if (img != NULL) {
+    FIO_Image<T> fio(img);
+    fio.Write(pos, nom);
+  }
+  else {
+    FIO_TArray<T> fio(mMtx);
+    fio.Write(pos, nom);
+  }
+}
+return;
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TMatrix<T>::Print(ostream& os, int lev)
+{
+if (lev < 3) mMtx->Show(os, false);
+else  mMtx->Show(os, true);
+if (lev > 0) mMtx->Print(os, 10*lev);
+}
+
+/* --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 &)
+{
+Image<T>* img = dynamic_cast<Image<T> *>(mMtx);
+if (img != NULL) return ( new ImageAdapter<T>(img, false) );
+else return ( new POTMatrixAdapter<T>(mMtx, false) );
+}
+
+// ---- Specialisation pour complexes -----
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+P2DArrayAdapter* NOMAdapter_TMatrix< complex<r_4> >::Get2DArray(string &)
+{
+return ( new POTMatrixAdapter< complex<r_4> >(mMtx, false) );
+}
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+P2DArrayAdapter* NOMAdapter_TMatrix< complex<r_8> >::Get2DArray(string &)
+{
+return ( new POTMatrixAdapter< complex<r_8> >(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 -----
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+AnyDataObj* NOMAdapter_TMatrix< complex<r_4> >::FitResidusObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+AnyDataObj* NOMAdapter_TMatrix< complex<r_4> >::FitFunctionObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+AnyDataObj* NOMAdapter_TMatrix< complex<r_8> >::FitResidusObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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> 
+sa_size_t NTupInt_TMatrix<T>::NbLines() const
+{
+return( mMtx->NRows()*mMtx->NCols() );
+}
+
+/* --Methode-- */
+template <class T> 
+sa_size_t  NTupInt_TMatrix<T>::NbColumns() const 
+{
+return(8);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_TMatrix<T>::GetLineD(sa_size_t 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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_TMatrix< complex<r_4> >::GetLineD(sa_size_t 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);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+r_8* NTupInt_TMatrix< complex<r_8> >::GetLineD(sa_size_t 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<int_8>
+#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<int_8>
+#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<int_8>;
+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<int_8>;
+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_Nov2007/SophyaPI/PIext/nomtmatvecadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/nomtmatvecadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/nomtmatvecadapter.h	(revision 3445)
@@ -0,0 +1,72 @@
+// 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);
+
+// Returns a string with synthetic information about the object 
+// opts : additional optional argument 
+  virtual string                GetInfoString(vector<string>& opts);
+// Perform an operation on the object definded 
+// opts : operation definition 
+  virtual int                   PerformOperation(vector<string>& opts);
+
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os, int lev=0);
+  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 sa_size_t     NbLines() const ;
+  virtual sa_size_t     NbColumns() const ;
+  virtual r_8 *         GetLineD(sa_size_t n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  TMatrix<T>* mMtx;
+  mutable r_8 mRet[8];
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/objlist.list
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/objlist.list	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/objlist.list	(revision 3445)
@@ -0,0 +1,33 @@
+basexecut.o
+contmodex.o
+cxxexecutor.o
+cxxexecwin.o
+flowmodex.o
+graphexecut.o
+nobjmgr.o
+nomdvladapter.o
+nomgadapter.o
+nomgfdadapter.o
+nomherradapter.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_Nov2007/SophyaPI/PIext/pawexecut.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pawexecut.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pawexecut.cc	(revision 3445)
@@ -0,0 +1,2472 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "sopnamsp.h"
+#include "strutil.h"
+#include "strutilxx.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "histerr.h"
+#include "hist2err.h"
+#include "ntuple.h"
+#include "datatable.h"
+
+#include "pawexecut.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+#include "pihisto.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "cvector.h"
+#include "matrix.h"
+#else
+#include "tmatrix.h"
+#include "tvector.h"
+#endif
+
+/* Reza + cmv  13/10/99 */
+
+inline bool __vector_sort_up_r8(r_8 x1,r_8 x2) {return x1<x2;}
+inline bool __vector_sort_down_r8(r_8 x1,r_8 x2) {return x1>x2;}
+inline bool __vector_sort_up_r4(r_4 x1,r_4 x2) {return x1<x2;}
+inline bool __vector_sort_down_r4(r_4 x1,r_4 x2) {return x1>x2;}
+inline bool __vector_sort_up_i4(int_4 x1,int_4 x2) {return x1<x2;}
+inline bool __vector_sort_down_i4(int_4 x1,int_4 x2) {return x1>x2;}
+inline bool __vector_sort_up_u8(uint_8 x1,uint_8 x2) {return x1<x2;}
+inline bool __vector_sort_down_u8(uint_8 x1,uint_8 x2) {return x1>x2;}
+
+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 for 1 dimensional (1D) projection:";
+usage += "\n   use graphic option \"keepbin\" to keep previous";
+usage += "\n   plot binning for 1D distribution";
+usage += "\n  Related commands: plot2dw plot3d";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/pl";
+usage = "alias to n/plot (see n/plot)";
+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 for 1 dimensional (1D) projection:";
+usage += "\n   no display is performed if \"nameproj\" is an existing histogram";
+usage += "\n   unless a graphic option \"gratt\" is given";
+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 = "n/read";
+usage = "Read columns in an ASCII file and fill a NTuple or a DataTable";
+usage += "\n n/read nt fascii [options] var_1,c_1 var_2,c_2 ... var_n,c_n ";
+usage += "\n nt : NTuple or DataTable (see options) name";
+usage += "\n var_i,c_i : variable name, associated column in ASCII file [0,n[";
+usage += "\n where [options] are:";
+usage += "\n   \"-dt\": create a DataTable of double instead of a NTuple";
+usage += "\n   \"=s\": separator character is \'s\' (could be \"\t\")";
+usage += "\n   \"-^abcd\": do not read lines beginning with string \"abcd\" ";
+usage += "\n   \"+^abcd\": read only lines beginning with string \"abcd\" ";
+usage += "\n   \"-abcd\": do not read lines which contain string \"abcd\" ";
+usage += "\n   \"+abcd\": read only lines which contain string \"abcd\" ";
+usage += "\n these options may be repeated (ex: \"-^abcd\" \"-^xyz\") ";
+usage += "\n   - in case of \"do not read\" options are added with logical AND ";
+usage += "\n   - in case of \"read only\" options are added with logical OR ";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/merge";
+usage = "Merge ntuples (by adding lines)";
+usage += "\n n/merge nt nt_1 nt_2 ... nt_n";
+usage += "\n Merge ntuples nt_i lines into ntuple nt";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/merge/col";
+usage = "Merge ntuples (by adding columns for each line)";
+usage += "\n n/merge/col nt nt_1[,ext] nt_2[,ext] ... nt_n[,ext]";
+usage += "\n Merge ntuples nt_i columns into ntuple nt";
+usage += "\n ext : character string to add at the end of the ntuple variable names";
+usage += "\n   if \"ext\"=\"!\" no extension is added";
+usage += "\n   if no \"ext\" is given, automatic extension \"_0\" \"_1\" \"_2\" ...";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/assoc/col";
+usage = "Merge ntuples columns with an association index";
+usage += "\n n/assoc/col ntass[,u/i] nt_1[,ext] nt_2[,ext] nt_assoc[,icass]";
+usage += "\n Merge ntuples nt_1 and nt_2 columns into ntuple ntass";
+usage += "\n   with line association number given by ntuple nt_assoc";
+usage += "\n ---";
+usage += "\n icass: association number given by column \"icass\" of nt_assoc (def=0)";
+usage += "\n ---";
+usage += "\n ext : character string to add at the end of the ntuple variable names";
+usage += "\n   if \"ext\"=\"!\" no extension is added";
+usage += "\n   if no \"ext\" is given, automatic extension \"_0\" \"_1\" \"_2\" ...";
+usage += "\n ---";
+usage += "\n u   : do the union of all the lines of nt_1 and nt_2";
+usage += "\n       (all ssociated and un-associated lines of nt_1 and nt_2)";
+usage += "\n i   : do the intersection of all the lines of nt_1 and nt_2";
+usage += "\n       (only associated lines of nt_1 and nt_2)";
+usage += "\n def : write all lines of nt_1 with possible associated line of nt_2";
+usage += "\n       (number of entries of ntass = number of entries of nt_1)";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/copy";
+usage = "Copy all or some variables of a ntuple into another new ntuple";
+usage += "\n n/merge ntnew nt [vname1 vname2 vname3 ...]";
+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);
+
+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);
+
+kw = "v/sort";
+usage = "Sort a vector into itself";
+usage += "\n v/sort namevec [+1/-1]";
+usage += "\n \"+1\" means increasing order, \"-1\" decreasing order";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+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);
+
+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);
+
+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 projections";
+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/2d/geth";
+usage = "Get histo projections, bandes and slices";
+usage += "\n h/2d/geth nameh2d         : infos on 2D histogramme projections";
+usage += "\n h/2d/geth h nameh2d px    : copy X projection into histo h";
+usage += "\n h/2d/geth h nameh2d py    : copy Y projection into histo h";
+usage += "\n h/2d/geth h nameh2d bx n  : copy X band number n into histo h";
+usage += "\n h/2d/geth h nameh2d by n  : copy Y band number n into histo h";
+usage += "\n h/2d/geth h nameh2d sx n  : copy X slice number n into histo h";
+usage += "\n h/2d/geth h nameh2d sy n  : copy Y slice number n into histo h";
+usage += "\n  Related commands: h/plot/2d";  
+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);
+
+kw = "herr/mean";
+usage = "Perform bin mean computation for HistoErr and Histo2DErr";
+usage += "\n herr/mean nameherr todo";
+usage += "\n    todo = +1 : compute mean";
+usage += "\n         = -1 : cancel computation";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "herr/variance";
+usage = "Perform bin mean and variance computation for HistoErr and Histo2DErr";
+usage += "\n herr/variance nameherr todo";
+usage += "\n    todo = +1 : compute mean and variance";
+usage += "\n         = -1 : cancel computation";
+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 == "n/read") {
+  n_read(tokens); return(0);
+} else if(kw == "n/merge") {
+  n_merge(tokens); return(0);
+} else if(kw == "n/merge/col") {
+  n_merge_col(tokens); return(0);
+} else if(kw == "n/assoc/col") {
+  n_assoc_col(tokens); return(0);
+} else if(kw == "n/copy") {
+  n_copy(tokens); return(0);
+} else if(kw == "h/integ") {
+  h_integ(tokens); return(0);
+} else if(kw == "v/integ") {
+  v_integ(tokens); return(0);
+} else if(kw == "v/sort") {
+  v_sort(tokens); return(0);
+} else if(kw == "h/deriv") {
+  h_deriv(tokens); return(0);
+} else if(kw == "v/deriv") {
+  v_deriv(tokens); return(0);
+} 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/2d/geth") {
+  h_2d_geth(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 if(kw == "herr/mean") {
+  herr_mean_variance(tokens,0); return(0);
+} else if(kw == "herr/variance") {
+  herr_mean_variance(tokens,1); return(0);
+} else return(1); 
+}
+
+
+/* methode */
+bool PAWExecutor::IsThreadable(string const & keyw)
+{
+  if ( (keyw == "n/plot")  || (keyw == "n/pl") || 
+       (keyw == "n/proj") )  return true;
+  else return false;
+}
+
+
+/* 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 if(typeid(*mobj)==typeid(HistoErr)) {HistoErr* ob=(HistoErr*)  mobj; ob->Zero();}
+else if(typeid(*mobj)==typeid(Histo2DErr)) {Histo2DErr* ob=(Histo2DErr*)  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;
+    }
+    // --- Si option "keepbin" on projete avec le meme binning que l'histo 1D precedent
+    if(dopt.find("keepbin")<dopt.size()) {
+      PIStdImgApp* piimapp = omg.GetImgApp();
+      if(piimapp) {
+	PIBaseWdg* pibwdg = piimapp->CurrentBaseWdg();
+	if(pibwdg) {
+          int nbdrw = pibwdg->NbDrawers();
+          if(nbdrw>0) {
+            for(int i=nbdrw-1;i>=0;i--) {
+              PIDrawer* pidwr = pibwdg->GetDrawer(i);
+              PIHisto* pih = NULL;
+              if( (pih = dynamic_cast<PIHisto *>(pidwr))==NULL ) continue;
+              P1DHistoWrapper* h = pih->HistoWrapper();
+              if(h==NULL) continue;
+              if(h->NBins()<1) continue;
+              Histo* hsame = new Histo(h->XMin(),h->XMax(),h->NBins());
+              omg.AddObj(hsame,nameproj);
+              break;
+	    }
+	  }
+	}
+      }
+    }
+    // --- 
+  }
+  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_8 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_8)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_8 k=k1; k<k2; k += dk)    {
+    xn = objnt->GetLineD(k);
+    if(f((int_8_exprf)k,xn,xnt,xnt+1,xnt+2,xnt+3) != 0) {
+      if(fout) fprintf(fout,"%ld ",(long)k); else printf("%ld ",(long)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 */
+#define __LENLINE_N_READ__ 8192
+void PAWExecutor::n_read(vector<string>& tokens)
+{
+ int lp=1;
+
+ if(tokens.size()<3) {
+   cerr<<"Usage: n/read nt fascii [options] var_1,c_1 ... var_n,c_n"<<endl;
+   return;
+ }
+
+ // decodage des arguments
+ string nament = tokens[0];
+ string nameascii = tokens[1];
+ bool create_datatable = false;
+ vector<string> donotreadbeg;
+ vector<string> donotreadin;
+ vector<string> onlyreadbeg;
+ vector<string> onlyreadin;
+ vector<string> varname;
+ vector<int> colnum;
+ char separator = ' ';
+ int numcolmaxi=-1;
+
+ for(int i=2;i<(int_4)tokens.size();i++) {
+   int lc = tokens[i].size();
+   if(lc<2) continue;
+   if(tokens[i].find("-dt")==0) { // create DataTable instead of NTuple
+     create_datatable = true;
+     continue;
+   }
+   const char *c = tokens[i].c_str();
+   if(c[0]=='=') { // Separator
+     separator = c[1];
+     if(lc==3) if(c[1]=='\\' && c[2]=='t') separator = '\t';
+     continue;
+   }
+   if(c[0]=='+') { // Selection des lignes a lire
+     if(c[1]!='^') onlyreadin.push_back(&c[1]);
+       else if(lc>2) onlyreadbeg.push_back(&c[2]);
+     continue;
+   }
+   if(c[0]=='-') { // Selection des lignes commentaire
+     if(c[1]!='^') donotreadin.push_back(&c[1]);
+       else if(lc>2) donotreadbeg.push_back(&c[2]);
+     continue;
+   }
+   // decodage des noms de variables et des colonnes associees
+   int p = tokens[i].find(',');
+   if(p<1 || p>=lc-1) continue;
+   string vn = tokens[i].substr(0,p);
+   string cn = tokens[i].substr(p+1,lc-p-1);
+   int ic = atoi(cn.c_str());
+   if(ic<0) continue;
+   if( !isalpha(vn[0]) ) continue;
+   if(ic>numcolmaxi) numcolmaxi = ic;
+   varname.push_back(vn);
+   colnum.push_back(ic);
+ }
+
+ int nvar = varname.size();
+ if(nvar<=0) {
+   cerr<<"n_read: no variables to be read"<<endl;
+   return;
+ }
+
+ // Print what has to be done
+ if(lp) {
+   if(onlyreadin.size()>0) {
+     cout<<"n_read Only read line containing ["<<onlyreadin.size()<<"]:";
+     for(int i=0;i<(int_4)onlyreadin.size();i++) cout<<" \'"<<onlyreadin[i]<<"\'";
+     cout<<endl;
+   }
+   if(onlyreadbeg.size()>0) {
+     cout<<"n_read Only read line begining with ["<<onlyreadbeg.size()<<"]:";
+     for(int i=0;i<(int_4)onlyreadbeg.size();i++) cout<<" \'"<<onlyreadbeg[i]<<"\'";
+     cout<<endl;
+   }
+   if(donotreadin.size()>0) {
+     cout<<"n_read Do not read line containing ["<<donotreadin.size()<<"]:";
+     for(int i=0;i<(int_4)donotreadin.size();i++) cout<<" \'"<<donotreadin[i]<<"\'";
+     cout<<endl;
+   }
+   if(donotreadbeg.size()>0) {
+     cout<<"n_read Do not read line begining with ["<<donotreadbeg.size()<<"]:";
+     for(int i=0;i<(int_4)donotreadbeg.size();i++) cout<<" \'"<<donotreadbeg[i]<<"\'";
+     cout<<endl;
+   }
+   if(nvar>0) {
+     cout<<"n_read Number of variables to be read: "<<nvar<<endl;
+     for(int i=0;i<nvar;i++) cout<<" \'"<<varname[i].c_str()<<","<<colnum[i]<<"\'";
+     cout<<endl;
+   }
+   if(separator!=' ') cout<<"n_read Separator is: \'"<<separator<<"\'"<<endl;
+ }
+
+ // Open ASCII file
+ FILE * fascii = fopen(nameascii.c_str(),"r");
+ if(fascii==NULL) {
+   cerr<<"n_read: cannot open file "<<nameascii<<endl;
+   return;
+ }
+
+ // Creation du NTuple ou de la DataTable
+ NTuple *nt = NULL;
+ DataTable *dt = NULL;
+ if(!create_datatable) { //create NTuple
+   char** ntvn = new char*[nvar];
+   for(int i=0;i<nvar;i++) ntvn[i] = const_cast<char *>(varname[i].c_str());
+   nt = new NTuple(nvar,ntvn);
+   delete [] ntvn;
+ } else { //create DataTable
+   dt = new DataTable();
+   for(int i=0;i<nvar;i++) dt->AddDoubleColumn(varname[i]);
+ }
+ r_8 *xnt = new r_8[nvar];
+
+ // Read file
+ char *line = new char[__LENLINE_N_READ__];
+ int nline=0, nlinecom=0;
+ while(fgets(line,__LENLINE_N_READ__,fascii) != NULL ) {
+   nline++;
+   uint_4 lc = strlen(line); if(lc<1) continue;
+   // Pour enlever le \n final
+   if(line[lc-1]=='\n' || line[lc-1]=='\r')
+     {line[lc-1]='\0'; lc = strlen(line); if(lc<1) continue;}
+
+   string const sline(line);
+   //cout<<"\'"<<sline<<"\'  lc="<<lc<<endl;
+
+   // Faut t'il lire cette ligne ?
+   bool read_line_1 = true;
+   if(onlyreadin.size()>0 || onlyreadbeg.size()>0) read_line_1 = false;
+   if(onlyreadin.size()>0) {
+     for(int i=0;i<(int_4)onlyreadin.size();i++) {
+       uint_4 p = sline.find(onlyreadin[i].c_str());
+       if(p>=lc) continue;
+       read_line_1 = true;
+       break;
+     }
+   }
+   if(onlyreadbeg.size()>0) {
+     for(int i=0;i<(int_4)onlyreadbeg.size();i++) {
+       uint_4 p = sline.find(onlyreadbeg[i].c_str());
+       if(p!=0) continue;
+       read_line_1 = true;
+       break;
+     }
+   }
+
+   // Faut t'il ne pas lire cette ligne ?
+   bool read_line_2 = true;
+   if(donotreadin.size()>0) {
+     for(int i=0;i<(int_4)donotreadin.size();i++) {
+       uint_4 p = sline.find(donotreadin[i].c_str());
+       if(p>=lc) continue;
+       read_line_2 = false;
+       break;
+     }
+   }
+   if(donotreadbeg.size()>0) {
+     for(int i=0;i<(int_4)donotreadbeg.size();i++) {
+       uint_4 p = sline.find(donotreadbeg[i].c_str());
+       if(p!=0) continue;
+       read_line_2 = false;
+       break;
+     }
+   }
+   if(!read_line_2) nlinecom++;
+
+   if(!read_line_1 || !read_line_2) continue;
+
+   // Decodage de la ligne
+   vector<string> vs;
+   //FillVStringFrString(sline,vs,separator);
+   SplitStringToVString(sline,vs,separator);
+   int lvs = vs.size();
+   //for(int i=0;i<lvs;i++) cout<<"|"<<vs[i]<<"| "; cout<<endl;
+   if(lvs<numcolmaxi) continue; // Pas assez de champs decodes, mauvaise ligne
+
+   // Remplissage du NTuple ou de la DataTable
+   for(int i=0;i<nvar;i++) {
+     xnt[i] = 0.;
+     int ic = colnum[i];
+     if(ic>=lvs) continue;
+     xnt[i] = atof(vs[ic].c_str());
+   }
+   if(nt)      nt->Fill(xnt);
+   else if(dt) dt->Fill(xnt);
+   //cout<<"...xnt"; for(int i=0;i<nvar;i++) cout<<" "<<xnt[i]; cout<<endl;
+
+ }
+ int_4 nentries = (nt)? nt->NEntry(): dt->NEntry();
+ cout<<"n_read: "<<nline<<" lines in file, "
+     <<nlinecom<<" commentary, "
+     <<nentries<<" object entries"<<endl;
+
+ // On sauve le NTuple/DataTable si besoin, on ferme et detruit ce qu'il faut
+ NamedObjMgr omg;
+ if(nentries>0) {
+   if(nt) omg.AddObj(nt,nament);
+   if(dt) omg.AddObj(dt,nament);
+ } else {
+   if(nt) delete nt;
+   if(dt) delete dt;
+ }
+ delete [] xnt;
+ delete [] line;
+ fclose(fascii);
+
+ return;
+}
+#undef __LENLINE_N_READ__
+
+/* methode */
+void PAWExecutor::n_merge(vector<string>& tokens)
+{
+ if(tokens.size()<2) {
+   cerr<<"Usage: n/merge nt nt_1 nt_2 ... nt_n"<<endl;
+   return;
+ }
+
+ NamedObjMgr omg;
+
+ // decodage des arguments
+ string nament = tokens[0];
+
+ // boucle sur les ntuples
+ NTuple * nt = NULL;
+ int nvar=0, nfill=0;
+ r_8 *xnt=NULL;
+
+ for(int i=1;i<(int_4)tokens.size();i++) {
+
+   AnyDataObj* mobj = omg.GetObj(tokens[i]);
+   if(mobj==NULL) {
+     cout<<"n_merge Error: unknow object"<<tokens[i]<<endl;
+     continue;
+   }
+   NTuple* nt1 = dynamic_cast<NTuple*>(mobj);
+   if(nt1==NULL) {
+     cout<<"n_merge Error: "<<tokens[i]<<" not a NTuple"<<endl;
+     continue;
+   }
+   if(nt1->NEntry()==0) {
+     cout<<"n_merge Error: "<<tokens[i]<<" is empty"<<endl;
+     continue;
+   }
+   if(nt1->NVar()==0) {
+     cout<<"n_merge Error: "<<tokens[i]<<" has no variable"<<endl;
+     continue;
+   }
+
+   // create receiving ntuple if first pass
+   if(nt==NULL) {
+     nvar = nt1->NVar();
+     vector<string> sntvn;
+     for(int iv=0;iv<nvar;iv++) sntvn.push_back(nt1->ColumnName(iv));
+     char **ntvn = new char*[nvar];
+     for(int iv=0;iv<nvar;iv++) ntvn[iv] = const_cast<char *>(sntvn[iv].c_str());
+     nt = new NTuple(nvar,ntvn);
+     delete [] ntvn;
+   }
+
+   // filling with current ntuple
+   int nvar1 = nt1->NVar();
+   int n = (nvar1>nvar)? nvar1: nvar;
+   r_8 *xnt1 = new r_8[n];
+   for(int iev=0;iev<n;iev++) xnt1[iev]=0.;
+   for(uint_4 iev=0;iev<(uint_4)nt1->NEntry();iev++) {
+     nt1->GetVecD(iev,xnt1);
+     nt->Fill(xnt1);
+   }
+   nfill++;
+   delete [] xnt1;
+
+ }
+
+ if(xnt!=NULL) delete [] xnt;
+ if(nt!=NULL) {
+   cout<<"n_merge: ntuple filled with "<<nfill
+       <<" ntuples, "<<nt->NEntry()<<" entries"<<endl;
+   if(nt->NEntry()>0) omg.AddObj(nt,nament); else delete nt;
+ }
+ return;
+}
+
+/* methode */
+void PAWExecutor::n_merge_col(vector<string>& tokens)
+{
+ if(tokens.size()<2) {
+   cerr<<"Usage: n/merge/col nt nt_1[,ext] nt_2[,ext] ... nt_n[,ext]"<<endl;
+   return;
+ }
+
+ NamedObjMgr omg;
+
+ // decodage des arguments
+ string nament = tokens[0];
+
+ // boucle sur les ntuples
+ uint_4 numnt=0, nentmax=0, ipos=0;
+ vector<string> varname;
+ vector<string> ntname;
+ vector<int> posfirst;
+ for(int i=1;i<(int_4)tokens.size();i++) {
+
+   // Decode NTuple name and extension
+   int_4 lc = tokens[i].size();
+   string ntn = tokens[i];
+   string ext = "";
+   int p = ntn.find(',');
+   if(p>=0 && p<lc) {
+     if(p<lc-1) ext = ntn.substr(p+1,lc-p-1);
+     if(p>0) ntn = ntn.substr(0,p); else ntn = "";
+   }
+   // choose the extentsion: given,automatic,none
+   if(ext.size()<1) {
+     char str[8]; sprintf(str,"_%d",numnt);
+     ext = str;
+   } else if(ext[0] == '!') {
+     ext = "";
+   }
+
+   AnyDataObj* mobj = omg.GetObj(ntn);
+   if(mobj==NULL) {
+     cout<<"n_merge_col Error: unknow object "<<ntn<<" ("<<tokens[i]<<")"<<endl;
+     continue;
+   }
+   NTuple* nt1 = dynamic_cast<NTuple*>(mobj);
+   if(nt1==NULL) {
+     cout<<"n_merge_col Error: "<<ntn<<" not a NTuple"<<endl;
+     continue;
+   }
+   if(nt1->NEntry()==0) {
+     cout<<"n_merge_col Error: "<<ntn<<" is empty"<<endl;
+     continue;
+   }
+   if(nt1->NVar()==0) {
+     cout<<"n_merge_col Error: "<<ntn<<" has no variable"<<endl;
+     continue;
+   }
+
+   ntname.push_back(ntn);
+   posfirst.push_back(ipos);
+   if(nt1->NEntry()>(int_4)nentmax) nentmax = nt1->NEntry();
+   for(int iv=0;iv<nt1->NVar();iv++) {
+     string str = nt1->ColumnName(iv) + ext;
+     varname.push_back(str);
+   }
+   numnt++;
+   ipos += nt1->NVar();
+ }
+
+ if(ntname.size()==0) {
+   cout<<"n_merge_col Error: no ntuple found in argument list"<<endl;
+   return;
+ } else cout<<"Number of NTuple found "<<ntname.size()
+            <<", Number of variables "<<varname.size()
+            <<", Max_entries "<<nentmax<<endl;
+
+ // create receiving ntuple
+ int nvar = varname.size();
+ char **ntvn = new char*[nvar];
+ for(int iv=0;iv<nvar;iv++) ntvn[iv] = const_cast<char *>(varname[iv].c_str());
+ NTuple * nt = new NTuple(nvar,ntvn);
+ //for(int i=0;i<(int_4)ntname.size();i++) cout<<ntname[i]<<" , p="<<posfirst[i]<<endl;
+ delete [] ntvn;
+
+ // filling with current ntuple
+ r_8 *xnt = new r_8[nvar];
+ for(int iev=0;iev<(int_4)nentmax;iev++) {
+   for(int i=0;i<nvar;i++) xnt[i]=0.;
+   for(int i=0;i<(int_4)ntname.size();i++) {
+     AnyDataObj* mobj = omg.GetObj(ntname[i]);
+     NTuple* nt1 = dynamic_cast<NTuple*>(mobj);
+     if(iev < nt1->NEntry())  nt1->GetVecD(iev,&xnt[posfirst[i]]);
+   }
+   nt->Fill(xnt);
+ }
+
+ // Ending and saving merging ntuple columns
+ delete [] xnt;
+ cout<<"n_merge_col: ntuple filled with "<<ntname.size()
+     <<" ntuples, "<<nt->NEntry()<<" entries"<<endl;
+ if(nt->NEntry()>0) omg.AddObj(nt,nament); else delete nt;
+
+ return;
+}
+
+/* methode */
+void PAWExecutor::n_assoc_col(vector<string>& tokens)
+{
+ if(tokens.size()<4) {
+   cerr<<"Usage: n/assoc/col ntass[,u] nt_1[,ext] nt_2[,ext] nt_assoc[,icass]"<<endl;
+   return;
+ }
+
+ NamedObjMgr omg;
+
+ // decodage du nom du ntuple final associe
+ // do_merge = 0  :  on remplit toutes les lignes de nt_1 associees ou non
+ //                  lignes associees + non-associees de nt_1
+ //                  -> ntass.NEntry == nt_1.NEntry
+ //          = 1  :  on remplit uniquement les lignes associees
+ //                  lignes associees uniquement
+ //                  -> ntass.NEntry <= min(nt_1.NEntry,nt_2.NEntry)
+ //          = 2  :  on remplit l'union des lignes
+ //                  lignes associees + non-associees de nt_1 + non-associees de nt_2
+ //                  -> ntass.NEntry >= max(nt_1.NEntry,nt_2.NEntry)
+ uint_2 do_merge=0;
+ string ntmerge = tokens[0];
+ int lc = tokens[0].size();
+ int p = tokens[0].find(',');
+ if(p>=0 && p<lc) {
+   ntmerge = ntmerge.substr(0,p);
+   p = tokens[0].find(",u");
+   if(p>=0 && p<lc) do_merge = 2;
+   p = tokens[0].find(",i");
+   if(p>=0 && p<lc) do_merge = 1;
+ }
+ cout<<"n_assoc_col: final ntuple "<<ntmerge<<", do_merge="<<do_merge<<endl;
+
+ // boucle pour decoder et valider les 3 ntuples
+ NTuple *nt[3];
+ string ntname;
+ vector<string> varname;
+ int icass = 0;
+
+ for(int i=0;i<3;i++) {
+
+   // Decode NTuple name and extension
+   ntname = tokens[i+1];
+   int_4 lc = ntname.size();
+   string ext = "";
+   int p = ntname.find(',');
+   if(p>=0 && p<lc) {
+     if(p<lc-1) ext = ntname.substr(p+1,lc-p-1);
+     if(p>0) ntname = ntname.substr(0,p); else ntname = "";
+   }
+   // choose the extension: given,automatic,none
+   if(i==2) {  // numero de colonne avec l'index d'association
+     if(ext[0] == '!') ext = "";
+     if(ext.size()>0) icass = atoi(ext.c_str());
+   } else {
+     if(ext.size()<1) {
+       char str[8]; sprintf(str,"_%d",i);
+       ext = str;
+     } else if(ext[0] == '!') {
+       ext = "";
+     }
+   }
+
+   AnyDataObj* mobj = omg.GetObj(ntname);
+   if(mobj==NULL) {
+     cout<<"n_assoc_col Error: unknow object "<<ntname<<" ("<<tokens[i]<<")"<<endl;
+     return;
+   }
+   nt[i] = dynamic_cast<NTuple*>(mobj);
+   if(nt[i]==NULL) {
+     cout<<"n_assoc_col Error: "<<ntname<<" not a NTuple"<<endl;
+     return;
+   }
+   if(nt[i]->NEntry()==0) {
+     cout<<"n_assoc_col Error: "<<ntname<<" is empty"<<endl;
+     return;
+   }
+   if(nt[i]->NVar()==0) {
+     cout<<"n_assoc_col Error: "<<ntname<<" has no variable"<<endl;
+     return;
+   }
+
+   if(i<2)
+     for(int iv=0;iv<nt[i]->NVar();iv++) {
+       string str = nt[i]->ColumnName(iv) + ext;
+       varname.push_back(str);
+     }
+
+ }
+
+ // Checking size of associated ntuple
+ if(nt[0]->NEntry() != nt[2]->NEntry()) {
+   cout<<"n_assoc_col Error: nentries mismatch "
+       <<" first ntuple"<<"="<<nt[0]->NEntry()
+       <<", assoc ntuple"<<"="<<nt[2]->NEntry()<<endl;
+   return;
+ }
+ if(icass<0 || icass>=nt[2]->NVar()) {
+   cout<<"n_assoc_col Error: bad association column number "
+       <<icass<<" / "<<nt[2]->NVar()<<endl;
+   return;
+ }
+
+ // create receiving ntuple
+ int nvar = varname.size();
+ char **ntvn = new char*[nvar];
+ for(int iv=0;iv<nvar;iv++) ntvn[iv] = const_cast<char *>(varname[iv].c_str());
+ NTuple * ntass = new NTuple(nvar,ntvn);
+ delete [] ntvn;
+
+ // Filling with current ntuple
+ // the first column gives the associated line in nt[1]
+ int_4 nfill[2]={0,0};
+ r_8 *xass = new r_8[nt[2]->NVar()];
+ r_8 *xnt = new r_8[nvar];
+ uint_2 *use2 = NULL;
+ if(do_merge==2) {
+   use2 = new uint_2[nt[1]->NEntry()];
+   for(int i=0;i<nt[1]->NEntry();i++) use2[i] = 0;
+ }
+ for(int iev=0;iev<nt[0]->NEntry();iev++) {
+   nt[2]->GetVecD(iev,xass);
+   int iass = (xass[icass]<0.) ? -1: int(xass[icass]+0.5);
+   bool okass = (iass>=0 && iass<nt[1]->NEntry());
+   if(do_merge==1 && !okass) continue; // pas d'assoc et intersection demandee
+   for(int iv=0;iv<nvar;iv++) xnt[iv]=0.;
+   nt[0]->GetVecD(iev,xnt);
+   if(okass) {
+     nt[1]->GetVecD(iass,&xnt[nt[0]->NVar()]);
+     if(do_merge==2) use2[iass] = 1;
+   } else nfill[0]++;
+   ntass->Fill(xnt);
+ }
+ // Filling with remaining unassociated in nt[1] if requested
+ if(do_merge==2) {
+   for(int iev=0;iev<nt[1]->NEntry();iev++) {
+     if(use2[iev]!=0) continue; // deja rempli
+     for(int iv=0;iv<nvar;iv++) xnt[iv]=0.;
+     nt[1]->GetVecD(iev,&xnt[nt[0]->NVar()]);
+     ntass->Fill(xnt);
+     nfill[1]++;
+   }
+ }
+
+ // Ending and saving merged ntuple
+ delete [] xnt; delete [] xass;
+ if(use2) delete [] use2;
+ cout<<"n_assoc_col: ntuple "<<ntmerge
+     <<" filled with "<<ntass->NEntry()<<" entries"
+     <<", unassoc in nt_1="<<nfill[0]
+     <<", unassoc in nt_2="<<nfill[1]<<endl;
+ omg.AddObj(ntass,ntmerge);
+
+ return;
+}
+
+/* methode */
+void PAWExecutor::n_copy(vector<string>& tokens)
+{
+ if(tokens.size()<2) {
+   cerr<<"Usage: n/copy ntnew nt [vname1 vname2 vname3 ...]"<<endl;
+   return;
+ }
+
+ NamedObjMgr omg;
+
+ // Le NTuple de depart
+ AnyDataObj* mobj = omg.GetObj(tokens[1]);
+ if(mobj==NULL) {
+   cout<<"n_copy Error: unknow object"<<tokens[1]<<endl;
+   return;
+ }
+ NTuple* nt = dynamic_cast<NTuple*>(mobj);
+ if(nt==NULL) {
+   cout<<"n_copy Error: "<<tokens[1]<<" not a NTuple"<<endl;
+   return;
+ }
+ if(nt->NEntry()==0) {
+   cout<<"n_copy Error: "<<tokens[1]<<" is empty"<<endl;
+   return;
+ }
+ if(nt->NVar()==0) {
+   cout<<"n_copy Error: "<<tokens[1]<<" has no variable"<<endl;
+   return;
+ }
+
+ // Les variables a copier
+ int nvar; vector<string> varname; vector<int> ivar;
+ if(tokens.size()==2) {
+   nvar = nt->NVar();
+   for(int i=0;i<nvar;i++) {
+     ivar.push_back(i);
+     varname.push_back(nt->NomIndex(i));
+   }
+ } else {
+   nvar = tokens.size()-2;
+   for(int i=0;i<nvar;i++) {
+     int iv = nt->IndexNom(tokens[i+2].c_str());
+     if(iv<0) {
+       cout<<"n_copy Error: unkown variable "<<tokens[i+2].c_str()<<endl;
+       return;
+     }
+     ivar.push_back(iv);
+     varname.push_back(tokens[i+2]);
+   }
+ }
+ cout<<"coping variables: ";
+ for(int i=0;i<nvar;i++) cout<<" "<<varname[i];
+ cout<<endl;
+
+ // Creation du nouveau NTuple
+ char **ntvn = new char*[nvar];
+ for(int i=0;i<nvar;i++) ntvn[i] = const_cast<char *>(varname[i].c_str());
+ NTuple ntnew(nvar,ntvn);
+ delete [] ntvn;
+
+ // Copie du NTuple
+ r_8 *xnt = new r_8[nt->NVar()];
+ r_8 *xntnew = new r_8[nvar];
+ for(int iev=0;iev<nt->NEntry();iev++) {
+   nt->GetVecD(iev,xnt);
+   for(int i=0;i<nvar;i++) xntnew[i] = xnt[ivar[i]];
+   ntnew.Fill(xntnew);
+ }
+ delete [] xnt; delete [] xntnew;
+
+ // Adding new NTuple
+ omg.AddObj(ntnew,tokens[0]);
+
+ 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::v_sort(vector<string>& tokens)
+// Pour sort in-place d'un vecteur ascendant ou descendant
+{
+ if(tokens.size()<1)
+   {cout<<"Usage: v/sort namevec [+1/-1]"<<endl; return;}
+ NamedObjMgr omg;
+ AnyDataObj* mobj = omg.GetObj(tokens[0]);
+ if(mobj==NULL)
+   {cout<<"PAWExecutor::v_sort Error: unknow object"<<tokens[0]<<endl;
+   return;}
+
+ bool up = true;
+ if(tokens.size()>=2) if(atoi(tokens[1].c_str())<0) up=false;
+
+ {
+ TVector<r_8>* v = dynamic_cast<TVector<r_8>*>(mobj);
+ if(v) {
+   if(v->Size()==0) return;
+   if(up) stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_up_r8);
+     else stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_down_r8);
+   cout<<"median is: "<<0.5*((*v)(v->Size()/2)+(*v)((v->Size()-1)/2))<<endl;
+   return;
+ }
+ }
+
+ {
+ TVector<r_4>* v = dynamic_cast<TVector<r_4>*>(mobj);
+ if(v) {
+   if(v->Size()==0) return;
+   if(up) stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_up_r4);
+     else stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_down_r4);
+   cout<<"median is: "<<0.5*((*v)(v->Size()/2)+(*v)((v->Size()-1)/2))<<endl;
+   return;
+ }
+ }
+
+ {
+ TVector<int_4>* v = dynamic_cast<TVector<int_4>*>(mobj);
+ if(v) {
+   if(v->Size()==0) return;
+   if(up) stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_up_i4);
+     else stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_down_i4);
+   cout<<"median is: "<<0.5*((*v)(v->Size()/2)+(*v)((v->Size()-1)/2))<<endl;
+   return;
+ }
+ }
+
+ {
+ TVector<uint_8>* v = dynamic_cast<TVector<uint_8>*>(mobj);
+ if(v) {
+   if(v->Size()==0) return;
+   if(up) stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_up_u8);
+     else stable_sort(v->Data(), v->Data()+v->Size(), __vector_sort_down_u8);
+   cout<<"median is: "<<0.5*((*v)(v->Size()/2)+(*v)((v->Size()-1)/2))<<endl;
+   return;
+ }
+ }
+
+ cout<<"PAWExecutor::v_sort Error: "<<tokens[0]
+     <<" not a TVector or not a supported TVector<TYPE>"<<endl;
+ return;
+
+}
+
+/* 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,*h3);}
+  else if( oper[0]=='/') {h3->Clone(*h1); h3->DivElt(*h2,*h3,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,*h3);}
+  else if( oper[0]=='/') {h3->Clone(*h1); h3->DivElt(*h2,*h3,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 */
+void PAWExecutor::h_2d_geth(vector<string>& tokens)
+// copy bandx/y, slicex/y or projx/y from an 2D histo into a 1D histo
+{
+ NamedObjMgr omg;
+
+ if(tokens.size()==1) {
+   AnyDataObj* mobj = omg.GetObj(tokens[0]);
+   Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+   if(!h2) return;
+   h2->ShowProj();
+   h2->ShowBand(2);
+   h2->ShowSli(2);
+   return;
+ }
+
+ if(tokens.size()<3)
+   {cout<<"Usage: h/2d/geth h nameh2d [px,py,bx n,by n,sx n,sy n]"<<endl; return;}
+
+ string nameh1 = tokens[0];
+ string nameh2 = tokens[1];
+ string proj   = tokens[2];
+ int_4 nump = (tokens.size()>3)? atoi(tokens[3].c_str()): -1;
+
+ // Decodage Histo2D
+ AnyDataObj* mobj = omg.GetObj(tokens[1]);
+ if(mobj==NULL)
+   {cout<<"PAWExecutor::h_2d_geth Error: unknow object"<<tokens[1]<<endl;
+   return;}
+ Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+ if(!h2)
+   {cout<<"PAWExecutor::h_plot_2d Error: "<<tokens[1]<<" not an Histo2D"<<endl;
+   return;}
+
+ // Remplissage histo 1D avec la projection demandee
+ Histo *h1p;
+ if(proj == "px") {  
+   if((h1p=h2->HProjX())) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowProj();
+ } else if(proj == "py") {
+   if((h1p=h2->HProjY())) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowProj();
+ } else if(proj == "bx"  && nump>=0) {
+   if((h1p=h2->HBandX(nump))) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowBand();
+ } else if(proj == "by"  && nump>=0) {
+   if((h1p=h2->HBandY(nump))) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowBand();
+ } else if(proj == "sx"  && nump>=0) {
+   if((h1p=h2->HSliX(nump))) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowSli();
+ } else if(proj == "sy"  && nump>=0) {
+   if((h1p=h2->HSliY(nump))) {Histo* h=new Histo(*h1p); omg.AddObj(h,nameh1);}
+     else h2->ShowSli();
+ } else {
+   cout<<"PAWExecutor::h_2d_geth Error: Unknown proj name "<<proj
+       <<" or bad projection number "<<nump<<endl;
+ }
+
+ return;
+}
+
+/* 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;
+}
+
+}
+
+/* methode */
+void PAWExecutor::herr_mean_variance(vector<string>& tokens,int var)
+// Pour appliquer ToMean ou FromMean a un HistoErr ou Histo2DErr
+// Pour appliquer ToVariance ou FromVariance a un HistoErr ou Histo2DErr
+{
+  int_4 tks = tokens.size();
+  if(tks<1) {
+    cout<<"Usage: herr_mean_variance namehisterr [+1,-1]"<<endl;
+    return;
+  }
+
+  NamedObjMgr omg;
+  AnyDataObj* mobj = omg.GetObj(tokens[0]);
+  if( mobj==NULL)
+    {cout<<"PAWExecutor::h_copy Error: unknow object "<<tokens[0]<<endl;
+    return;}
+
+  int sens = 1;
+  if(tks>1) sens = atoi(tokens[1].c_str());
+
+  HistoErr   *herr  = dynamic_cast<HistoErr*>(mobj);
+  Histo2DErr *herr2 = dynamic_cast<Histo2DErr*>(mobj);
+
+  if(sens>=0) {
+    if(herr) {if(var==1) herr->ToVariance(); else herr->ToMean();}
+    else if(herr2) {if(var==1) herr2->ToVariance(); else herr2->ToMean();}
+  } else {
+    if(herr) {if(var==1) herr->FromVariance(); else herr->FromMean();}
+    else if(herr2) {if(var==1) herr2->FromVariance(); else herr2->FromMean();}
+  }
+
+  int nmean = 0;
+  if(herr) nmean = herr->NMean();
+  else if(herr2) nmean = herr2->NMean();
+  cout<<tokens[0]<<" : nmean = "<<nmean<<endl;
+
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/pawexecut.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pawexecut.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pawexecut.h	(revision 3445)
@@ -0,0 +1,56 @@
+// 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);
+  virtual bool  IsThreadable(string const & keyw);
+
+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  n_read(vector<string>& tokens);
+  void  n_merge(vector<string>& tokens);
+  void  n_merge_col(vector<string>& tokens);
+  void  n_assoc_col(vector<string>& tokens);
+  void  n_copy(vector<string>& tokens);
+  void  h_integ(vector<string>& tokens);
+  void  v_integ(vector<string>& tokens);
+  void  v_sort(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_2d_geth(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);
+  void  herr_mean_variance(vector<string>& tokens,int var=0);
+  int_4 decodepawstring(string tokens,string& nameobj
+                       ,string& xexp,string& yexp,string& zexp);
+  PIStdImgApp* mApp;
+  static uint_4 autoc_counter_;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/phistwrapper.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/phistwrapper.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/phistwrapper.h	(revision 3445)
@@ -0,0 +1,124 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'emballage (wrapper) d'histos pour trace PI 
+//       C. Magneville / R. Ansari             2007
+// (C)     CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef PHISTOWRAPPER_H
+#define PHISTOWRAPPER_H
+
+#include <string> 
+#include <vector> 
+#include "parradapter.h"
+
+
+//! Wrapper class interface for 1d-histogram like objects , used by PIHisto
+// methodes par defaut dans pihisto.cc
+class P1DHistoWrapper : public P1DArrayAdapter
+{
+public:
+  P1DHistoWrapper(int asz);  // asz: taille du tableau pour P1DArrayAdapter
+  virtual ~P1DHistoWrapper(); 
+
+  virtual int_4 NBins() = 0; 
+  virtual r_8 XMin() = 0; 
+  virtual r_8 XMax() = 0;
+  virtual r_8 BinWidth() = 0; 
+
+  virtual r_8 BinLowEdge(int_4 i) = 0;
+  virtual r_8 BinCenter(int_4 i) = 0;
+  virtual r_8 BinHighEdge(int_4 i) = 0;
+
+  // Renvoie contenu du bin i
+  virtual r_8 Content(int_4 i) = 0;
+  virtual r_8 Error(int_4 i) = 0;
+  virtual r_8 NbEntries(int_4 i) = 0;
+
+  inline  r_8 operator()(int_4 i) 
+  { 
+    r_8 rv = (mRetFg == 2) ? NbEntries(i) : ( (mRetFg == 1) ? Error(i) : Content(i) ) ;
+    return ( rv*mScale+mOff ); 
+  }
+
+  // Implementation de la methode P1DArrayAdapter::Value(int i) 
+  // Identique a l'operateur ()(i)
+  virtual double Value(int i) { return (*this)(i); }
+
+  // Methode de mise a jour du contenu 
+  // avec implementation par defaut - ne faisant rien 
+  virtual void Update() { return; }
+
+  // ajoute des lignes de texte avec les infos statistiques (dans text)
+  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
+  virtual int GetStatInfoAsText(vector<string> &  text );
+
+//   Methode de decodage des options - herite de P1DArrayAdapter
+//   implementation ds le fichier pihisto.cc 
+  virtual int DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   liste des options sous forme text - herite de P1DArrayAdapter (ds pihisto.cc )
+  virtual int OptionToString(vector<string> & opt) const;
+
+protected:
+  r_8 mScale, mOff;   // scaling coefficient, offset coefficient used in operator ()
+  short mRetFg;       // operator() : 0 -> bin content , 1 -> bin error , 2 -> bin nentries
+};
+
+//-----------------------------------------------------------------------------
+
+//! Wrapper class interface for 2d-histogram like objects , used by PIHisto2D
+// methodes par defaut dans pihisto2d.cc
+class P2DHistoWrapper : public P2DArrayAdapter
+{
+public:
+  P2DHistoWrapper(int_4 asx, int_4 asy); // asx,asy: tailles du tableau pour P2DArrayAdapter
+  virtual ~P2DHistoWrapper(); 
+
+  virtual int_4 NBinX() = 0; 
+  virtual int_4 NBinY() = 0; 
+  virtual r_8 XMin() = 0; 
+  virtual r_8 XMax() = 0;
+  virtual r_8 YMin() = 0; 
+  virtual r_8 YMax() = 0;
+  virtual r_8 WBinX() = 0; 
+  virtual r_8 WBinY() = 0; 
+
+  virtual void BinLowEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) = 0;
+  virtual void BinCenter(int_4 i, int_4 j, r_8& xr, r_8& yr) = 0;
+  virtual void BinHighEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) = 0;
+
+  // Renvoie contenu du bin i
+  virtual r_8 Content(int_4 i, int_4 j) = 0;
+  virtual r_8 Error(int_4 i, int_4 j) = 0;
+  virtual r_8 NbEntries(int_4 i, int_4 j) = 0;
+
+  inline  r_8 operator()(int_4 i, int_4 j) 
+  { 
+    r_8 rv = (mRetFg == 2) ? NbEntries(i,j) : ( (mRetFg == 1) ? Error(i,j) : Content(i,j) ) ;
+    return ( rv*mScale+mOff ); 
+  }
+  // Implementation de la methode P2DArrayAdapter::Value(int i, j) 
+  // Identique a l'operateur ()(i)
+  virtual double Value(int i, int j) { return (*this)(i, j); }
+
+  // Methode de mise a jour du contenu 
+  // avec implementation par defaut - ne faisant rien 
+  virtual void Update() { return; }
+
+  // ajoute des lignes de texte avec les infos statistiques (dans text)
+  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
+  virtual int GetStatInfoAsText(vector<string> &  text );
+
+//   Methode de decodage des options - herite de P2DArrayAdapter
+//   l'implementation ds le fichier pihisto2d.cc 
+  virtual int DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   liste des options sous forme text - herite de P2DArrayAdapter (ds pihisto2d.cc )
+  virtual int OptionToString(vector<string> & opt) const;
+
+protected:
+  r_8 mScale, mOff;   // scaling coefficient, offset coefficient used in operator ()
+  short mRetFg;       // operator() : 0 -> bin content , 1 -> bin error , 2 -> bin nentries
+};
+
+
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.cc	(revision 3445)
@@ -0,0 +1,197 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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);
+}
+
+
+
+/* --Methode-- */
+double PI2dVecDrawer::GetDistanceToPoint(double x, double y)
+{
+ if(_nti==NULL) return 1.e+9;
+ if( xK<0 || yK<0 ) return 1.e+9;
+ if( vK<0 || wK<0 ) return 1.e+9;
+
+ double dist = -1.e+18;
+ for(int i=0; i<_nti->NbLines(); i++) {
+   double xp=_nti->GetCell(i,xK);
+   double yp=_nti->GetCell(i,yK);
+   xp = (xp-x)/(XMax()-XMin())/0.5;
+   yp = (yp-y)/(YMax()-YMin())/0.5;
+   xp = xp*xp+yp*yp;
+   if(dist<0. || xp<dist) dist = xp;
+ }
+ dist=sqrt(fabs(dist));
+ cout<<dist<<"PI2dVecDrawer: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
+     <<" NbLines="<<_nti->NbLines()<<endl;
+ cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<endl;
+ cout<<"****** NON teste (CMV) ******"<<endl;
+
+ return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pi2dvec.h	(revision 3445)
@@ -0,0 +1,40 @@
+// 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);
+
+// Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+ 
+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_Nov2007/SophyaPI/PIext/piacmd.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piacmd.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piacmd.cc	(revision 3445)
@@ -0,0 +1,480 @@
+#include "sopnamsp.h"
+#include "piacmd.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.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"
+
+// Les differentes classes CommandExecutor
+#include "basexecut.h"
+#include "graphexecut.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   
+// ------------------------------------------------------------
+
+#define HGRPMSGOFFSET  100000
+
+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, HGRPMSGOFFSET+gid); }
+  inline  void  AddHelpGroup(string const & hgrp, int gid)
+                    { hgrpom->AppendItem(hgrp.c_str(), HGRPMSGOFFSET+gid); }
+  inline  void  ClearHelpList() 
+                    { mNitem=0; hitemlist->DeleteAllItems(); }
+  inline  void	AddHelpItem(const char * hitem) 
+		    { mNitem++;  hitemlist->AppendItem(hitem, 100+mNitem); }
+  inline  void  SetHelpTextLabel(string const & htxt, string const & hlab)
+                    { mTxt->SetText(htxt); mLab->SetLabel(hlab); }
+
+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 >= HGRPMSGOFFSET) && (sender == hgrpom)) {  // Selection de groupe de Help
+  mTxt->SetText("");
+  mLab->SetLabel("");
+  piac->UpdateHelpList(this, um-HGRPMSGOFFSET);
+}
+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(HGRPMSGOFFSET);   // Groupe All
+mTxt->SetText("");
+mLab->SetLabel("");
+piac->UpdateHelpList(this, 0); 
+PIWindow::Show();
+}
+
+
+// ------------------------------------------------------------
+//         Classe PIACmd
+// ------------------------------------------------------------
+
+// static PIACmd* curpiacmd = NULL;
+/* --Methode-- */
+PIACmd::PIACmd(PIStdImgApp* app)
+  : Commander()
+{
+mObjMgr = new NamedObjMgr; 
+mImgApp = app;
+helpwin = new PIAHelpWind(app, this);
+helpwin_initdone = false;
+
+string grp = "PIACmd";
+string gdesc = "piapp interpreter (class PIACmd) additional builtin commands";
+AddHelpGroup(grp, gdesc);
+
+string kw = "exitpiapp";
+string usage = "To end the piapp session ";
+RegisterCommand(kw, usage, NULL, grp);
+kw = "helpwindow";
+usage = "To display the Help window ";
+RegisterCommand(kw, usage, NULL, grp);
+kw = "stop";
+usage = "To stop (break) interpreter (PIACmd/Commander) execution";
+RegisterCommand(kw, usage, NULL, grp);
+
+basexec = new PIABaseExecutor(this, mObjMgr, app);
+graphexec = new PIAGraphicExecutor(this, mObjMgr, 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);
+
+InitializeHelpWindowMenu();
+// <ZThread>  Thread control attributes
+fg_thrstop = false;
+fg_threxe = false; 
+}
+
+/* --Methode-- */
+PIACmd::~PIACmd()
+{
+delete mObjMgr;
+delete helpwin;
+delete cxxexwin;
+delete cxxoptwin;
+delete basexec;
+delete graphexec;
+delete fitexec;
+delete pawexec;
+delete cxxexec;
+}
+
+
+/* --Methode-- */
+void PIACmd::AddInputLine(string const & line)
+{
+  if (line == "stop")  { 
+    StopExecution();
+    return;
+  }
+  mutx_inps.lock();
+  inputlines.push(line);   // Ajout d'un element en fin de queue
+  mutx_inps.unlock();
+  mutx_inps.broadcast();
+}
+
+/* --Methode-- */
+void PIACmd::StopThread()
+{
+  fg_thrstop = true;
+  mutx_inps.broadcast();
+}
+
+/* --Methode-- */
+void PIACmd::run()
+{
+  while (!fg_thrstop) {
+    mutx_inps.lock();
+    while (inputlines.empty()) { 
+      fg_threxe = false;
+      mutx_inps.wait();
+    }
+    string line = inputlines.front();   // On recupere l'element de tete
+    inputlines.pop();    // On supprime l'element de tete
+    fg_threxe = true;
+    mutx_inps.unlock();
+    try {
+      Interpret(line);
+    }
+    catch (PThrowable& pex) {  // Catching SOPHYA exceptions 
+      cerr << "PIACmd::run() SOPHYA exception in call to Interpret(" << line << ")\n"
+           << (string)typeid(pex).name() << " Msg= " << pex.Msg() << endl;
+    }
+    catch (std::exception& sex) {
+      cerr << "PIACmd::run() std::exception in call to Interpret(" << line << ")\n"
+           << (string)typeid(sex).name() << " Msg= " << sex.what() << endl;
+    }
+    catch (...) {
+      cerr << "PIACmd::run() unknown exception (...) in call to Interpret(" 
+           << line << ")" << endl; 
+    }
+  }
+}
+
+/* --Methode-- */
+bool PIACmd::CheckHelpGrp(string& grp, int& gid, string& desc)
+{
+bool fgnewgrp = Commander::CheckHelpGrp(grp, gid, desc);
+if (helpwin_initdone && fgnewgrp) helpwin->AddHelpGroup(grp.c_str(), gid);
+return fgnewgrp;
+}
+
+/* --Methode-- */
+void PIACmd::UpdateHelpList(PIAHelpWind* hw, int gid)
+{
+helpwin->ClearHelpList();
+if (gid == 0) { 
+  string htxt = "All registered commands";
+  string hlab = "All (HelpGroup)";
+  helpwin->SetHelpTextLabel(htxt, hlab);
+}
+else { 
+  CmdHGroup::iterator ith;
+  for(ith = cmdhgrp.begin(); ith != cmdhgrp.end(); ith++) {
+    if ((*ith).second.gid == gid) {
+      string hlab = (*ith).first;
+      hlab += " (HelpGroup)";
+      helpwin->SetHelpTextLabel((*ith).second.desc, hlab);
+      break;
+    }
+  } 
+}
+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::InitializeHelpWindowMenu()
+{
+  helpwin->AddHelpGroup("All", 0);
+  CmdHGroup::iterator it;
+  for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) 
+    helpwin->AddHelpGroup((*it).first, (*it).second.gid);
+  helpwin_initdone = true;
+}
+
+/* Fonction */
+static string GetStringFrStdin(PIACmd* piac)
+{
+PIStdImgApp* piapp = piac->GetImgApp();
+if (piapp) {
+  PIBaseWdg* wdg = piapp->CurrentBaseWdg();
+  if (wdg)  wdg->Refresh();
+}
+char buff[128];
+fgets(buff, 128, stdin);
+buff[127] = '\0';
+return((string)buff);
+}
+
+/* --Methode-- */
+bool PIACmd::GetVarApp(string const & vn, string & vv)
+{
+  vv = "";
+  if (mObjMgr == NULL) return false;
+  vector<string> opts;
+  SplitStringToVString(vn, opts, '.');
+  string nom = opts[0];
+  opts.erase(opts.begin());
+  NObjMgrAdapter* obja = mObjMgr->GetObjAdapter(nom);
+  if (obja == NULL) return false;
+  vv = obja->GetInfoString(opts);
+  return true;
+}
+
+/* --Methode-- */
+int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
+{
+int rc = 0;
+NamedObjMgr omg;
+
+// >>>>>>>>>>> Commande d'interpreteur
+if ( (kw == "helpwindow") && (mImgApp))  { 
+  ZSync zs(mImgApp->getMutex());
+  ShowHelpWindow();
+  zs.NOp();
+  return 0;
+}
+// ----> Sortie d'application
+else if ((kw == "exitpiapp") && (mImgApp)) {
+  mImgApp->Stop();
+  return 0;
+}
+else return Commander::ExecuteCommandLine(kw, tokens, toks);
+return 0;
+}
+
+
+/* --Methode-- */
+void PIACmd::ShowHelpWindow()
+{
+  helpwin->Show();
+}
+
+/* --Methode-- */
+void PIACmd::ShowCxxOptionWindow()
+{
+  cxxoptwin->Show();
+}
+
+/* --Methode-- */
+void PIACmd::ShowCxxExecWindow()
+{
+  cxxexwin->Show();
+}
+
+/* --Methode-- */
+void PIACmd::SetCurrentPrompt(const char* pr)
+{
+  Commander::SetCurrentPrompt(pr);
+  if (mImgApp) { 
+    ZSync zs(mImgApp->getMutex()); zs.NOp(); 
+    mImgApp->GetConsole()->SetPrompt(pr);
+  }
+}
+
+/* --Methode-- */
+void PIACmd::ShowMessage(const char * msg, int att)
+{
+  /*
+  Il faut faire quelque chose pour gerer correctement ca en multithread
+  char va = (att == 0) ? 0 : PIVA_Magenta;
+  if (mImgApp) { 
+    ZSync(mImgApp->getMutex()); zs.NOp(); 
+    mImgApp->GetConsole()->AddStr(msg, va);
+  }
+  */
+Commander::ShowMessage(msg, att);
+}
+
+
+/* --Methode-- */
+SOpExObj::SOpExObj(PIStdImgApp* app)
+{
+  mImgApp = app;
+  fg_thrstop = false;
+  fg_threxe = false;
+}
+
+/* --Methode-- */
+SOpExObj::~SOpExObj()
+{
+}
+
+/* --Methode-- */
+void SOpExObj::AddOpe(string const & line)
+{
+  mutx_inps.lock();
+  inputlines.push(line);   // Ajout d'un element en fin de queue
+  mutx_inps.unlock();
+  mutx_inps.broadcast();
+}
+
+/* --Methode-- */
+void SOpExObj::run()
+{
+  NamedObjMgr omg;
+  while (!fg_thrstop) {
+    mutx_inps.lock();
+    while (inputlines.empty()) { 
+      fg_threxe = false;
+      mutx_inps.wait();
+    }
+    string cmd = inputlines.front().substr(0,3);   // On recupere l'element de tete
+    string nom = inputlines.front().substr(4);   // On recupere l'element de tete
+    inputlines.pop();    // On supprime l'element de tete
+    fg_threxe = true;
+    mutx_inps.unlock();
+    try {
+      if (cmd == "UPD") {  // UpdateObjMgrWindow()
+	int did = atoi(nom.c_str());
+	omg.UpdateObjMgrWindow(did);
+      }
+      else if (cmd == "SCO") {  // set cobj 
+	string ss = "set cobj ";
+	ss += nom;
+	cout << " Defining cobj : " << ss << endl;
+	mImgApp->CmdInterpreter()->AddInputLine(ss);
+      }
+      else if (cmd == "DIS") {  // display obj
+	omg.DisplayObj(nom);
+      }
+      else if (cmd == "PRT") {  // print obj
+	omg.PrintObj(nom);
+      }
+      else if (cmd == "DEL") {  // delete obj
+	omg.DelObj(nom);
+      }
+      else if (cmd == "SAV") {  // saveppf obj
+	if (mImgApp->mPpfout)  omg.SaveObj(nom, *(mImgApp->mPpfout), false);
+      }
+      else cerr << "SOpExObj::run() ERROR CMD= " << cmd << endl; 
+    }
+    catch (PThrowable& pex) {  // Catching SOPHYA exceptions 
+      cerr << "SOpExObj::run() SOPHYA exception CMD=" << cmd << " NOM=" << nom << "\n"
+           << (string)typeid(pex).name() << " Msg= " << pex.Msg() << endl;
+    }
+    catch (std::exception& sex) {
+      cerr << "SOpExObj::run() std::exception CMD=" << cmd << " NOM=" << nom << "\n"
+           << (string)typeid(sex).name() << " Msg= " << sex.what() << endl;
+    }
+    catch (...) {
+      cerr << "SOpExObj::run() unknown exception (...) CMD=" 
+	   << cmd << " NOM=" << nom << endl;
+    }
+  }
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/piacmd.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piacmd.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piacmd.h	(revision 3445)
@@ -0,0 +1,130 @@
+// 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 "commander.h"
+#include <string>
+#include <vector>
+#include <queue>
+#include "zthread.h"
+
+#include "dlftypes.h"
+
+// Forward declaration of some classes ...
+class NamedObjMgr;
+class PIStdImgApp;
+
+class PIAHelpWind;   // Fenetre d'aide en ligne 
+class CxxExecWind;   // Fenetre pour CxxExecutor
+class CxxOptionWind; // Option de CxxExecutor
+
+// ---------------------------------------------------------------------
+// Classe Interpreteur de commande, gestionnaire de module chargeable,
+// et de fonctions dynamiquement linke pour PIStdImgApp
+// Permet de gerer plusieurs Interpreter differents 
+// ---------------------------------------------------------------------
+
+
+class PIACmd : public Commander, public ZThread  {
+public:
+  //  static PIACmd*	GetInterpreter();
+
+			PIACmd(PIStdImgApp* app);
+  virtual		~PIACmd();
+
+  // Thread execution  <ZThread>
+  virtual void          run();
+  void                  AddInputLine(string const & line);
+  void                  StopThread();
+  inline  bool          isRunning(int& ninp) 
+    { ninp = inputlines.size(); return fg_threxe; }
+  // ---- FIN ---- Thread execution  <ZThread>
+
+  void                   ShowHelpWindow();
+  void                   ShowCxxOptionWindow();
+  void                   ShowCxxExecWindow();
+
+    //  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);
+
+// Acces aux objets transforme en string 
+  virtual bool    GetVarApp(string const & vn, string & vv);
+
+protected:
+  virtual int   ExecuteCommandLine(string & kw, vector<string> & tokens, 
+				   string & toks);
+
+  virtual bool	CheckHelpGrp(string& grp, int& gid, string& desc);
+  virtual void	InitializeHelpWindowMenu();
+
+  virtual void  SetCurrentPrompt(const char* pr);
+  virtual void	ShowMessage(const char * msg, int att);
+
+  NamedObjMgr* mObjMgr;
+  PIStdImgApp* mImgApp;
+
+  CmdExecutor* basexec;  // base command executor
+  CmdExecutor* graphexec; // graphic 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_
+ 
+// Fenetre d'aide interactive 
+  PIAHelpWind* helpwin;
+  bool helpwin_initdone;
+// Fenetres d'execution interactive de C++ , options correspondantes
+  CxxExecWind* cxxexwin;
+  CxxOptionWind* cxxoptwin;
+
+// Queue des entrees et controle de thread
+  queue<string> inputlines;
+  bool fg_thrstop;
+  ZMutex mutx_inps;
+  bool fg_threxe;
+
+};
+
+
+// 
+// ---------------------------------------------------------------------
+// Classe d'execution d'operations simples, comme affichage (display)
+// print , del ... issues en particulier de la boucle d'evts 
+// (PIStdImgApp, ObjMgrWind , ...)
+// ---------------------------------------------------------------------
+
+class SOpExObj : public ZThread  {
+public:
+			SOpExObj(PIStdImgApp* app);
+  virtual		~SOpExObj();
+
+  // Thread execution  <ZThread>
+  virtual void          run();
+  void                  AddOpe(string const & line);
+  void                  StopThread();
+
+protected:
+  PIStdImgApp* mImgApp;
+  queue<string> inputlines;
+  ZMutex mutx_inps;
+  bool fg_thrstop;
+  bool fg_threxe;
+};
+
+
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/piafitting.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piafitting.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piafitting.cc	(revision 3445)
@@ -0,0 +1,1674 @@
+//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>
+#include <typeinfo>
+
+#include "sopnamsp.h"
+#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)
+{
+// Flag de controle d'execution depuis la boucle d'evts
+  SetFgEvtLoopFlag(false);
+
+// 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 = "";
+AnyDataObj* mobj = NULL; 
+if ( fg_evtloop )  mobj = mApp->ObjMgr()->GetObj(obj);
+else {
+  NamedObjMgr omg;
+  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;
+
+mAdObj = NULL;
+if ( fg_evtloop )  mAdObj = mApp->ObjMgr()->GetObjAdapter(mNObj); // Ne pas deleter
+else {
+  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;
+
+string nomresfun = "__dummy__";
+
+if(mOpt.okres) {
+  nomresfun = mNObj + "_res";
+  AnyDataObj* ob = mAdObj->FitResidusObj(*mFit);
+  if(ob) { 
+    if ( fg_evtloop )  mApp->ObjMgr()->AddObj(ob,nomresfun);
+    else {
+      NamedObjMgr omg;
+      omg.AddObj(ob,nomresfun);
+    }
+  }
+}
+
+if(mOpt.okfun) {
+  nomresfun = mNObj + "_fun";
+  AnyDataObj* ob = mAdObj->FitFunctionObj(*mFit);
+  if(ob) { 
+    if ( fg_evtloop )  mApp->ObjMgr()->AddObj(ob,nomresfun);
+    else {
+      NamedObjMgr omg;
+      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") {
+  ZSync zs(getMutex());   // On s'assure 
+  SetFgEvtLoopFlag(false);  // l'origine n'est pas la boucle d'evts
+  int rc = DoFit();
+  if(rc>=0) FitFunRes();
+  zs.NOp();
+} else if(kw == "fitlin") {
+  ZSync zs(getMutex());
+  SetFgEvtLoopFlag(false);  // l'origine n'est pas la boucle d'evts
+  LinFit();
+} else if ((kw == "fitw") && (mApp != NULL) ) {
+  ZSync zs(mApp->getMutex());
+  if(FWindFit!=NULL) {delete FWindFit; FWindFit=NULL;}
+  FWindFit = new PIAFitterWind(mApp,this,tokens[1]);
+  FWindFit->Show();
+  zs.NOp();
+}
+
+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)
+{
+
+// Decodage des messages, init et dismiss
+msg = UserMsg(msg);
+if(msg ==777) {
+  //  cout<<"Dismiss"<<endl;
+  //mDap->SetReady();
+  Hide();
+  return;
+}
+
+mFitter->SetFgEvtLoopFlag(true); // On indique que l'origine est la boucle d'evts
+ZSync zs(mFitter->getMutex());   // On s'assure d'une seule execution du code PIAFitting
+
+int lp = (mFitter->mOpt.lp>2)?1:0;
+int npar = mFitter->mNPar;
+// L'objet existe t-il encore?
+if(mDap->ObjMgr()->GetObj(mFitter->mNObj) == NULL) {
+  cout<<"PIAFitterWind::Process Error , Pas d'objet de nom "
+      <<mFitter->mNObj<<endl;
+  mFitter->SetFgEvtLoopFlag(false);  
+  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();
+
+zs.NOp();
+mFitter->SetFgEvtLoopFlag(false);
+return;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/piafitting.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piafitting.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piafitting.h	(revision 3445)
@@ -0,0 +1,117 @@
+// 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"
+#include "zthread.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);
+
+  inline void  SetFgEvtLoopFlag(bool fg=false) { fg_evtloop = fg; }
+  inline ZMutex &   getMutex() { return singlefit_mutex; }
+
+friend class PIAFitterWind;
+
+protected :
+bool fg_evtloop;   // true : appel depuis Boucle d'evts, PIAFitterWind
+// Attributs pour controle de thread
+ZMutex singlefit_mutex;  // Pour empecher l'execution simultanee de deux fits
+
+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_Nov2007/SophyaPI/PIext/piaversion.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piaversion.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piaversion.h	(revision 3445)
@@ -0,0 +1,6 @@
+#ifndef PIAPPVERSION_H_SEEN
+#define PIAPPVERSION_H_SEEN
+
+#define PIAPP_VERSIONNUMBER  4.20
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/pigfd1.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pigfd1.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pigfd1.cc	(revision 3445)
@@ -0,0 +1,114 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#include <stdio.h>
+#include "sopnamsp.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);
+NptDraw = 0;
+}
+
+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;
+NptDraw = 0;
+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;
+  NptDraw++;
+  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;
+}
+
+/* --Methode-- */
+double PIGenFitDat::GetDistanceToPoint(double x, double y)
+{
+ if(!mGFD) return 1.e+9;
+ if(mGFD->NData()<=0) return 1.e+9;
+ if(VarX<0) return 1.e+9;
+
+ const int nessai = 100;
+ long inc = (NptDraw>nessai) ? (long)(NptDraw/nessai)+1 : 1;
+
+ double dist = -1.e+18;
+ long n = 0;
+ for(long i=0; i<mGFD->NData(); i++) {
+   double xp=mGFD->Absc(VarX,i);
+   if(xp<XMin() || xp>XMax()) continue;
+   double yp=mGFD->Val(i);
+   if(yp<YMin() || yp>YMax()) continue;
+   if(n%inc==0) {
+     xp = (xp-x)/(XMax()-XMin())/0.5;
+     yp = (yp-y)/(YMax()-YMin())/0.5;
+     xp = xp*xp+yp*yp;
+     if(dist<0. || xp<dist) dist = xp;
+   }
+   n++;
+ }
+ dist=sqrt(fabs(dist));
+ //cout<<"PIGenFitDat: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
+ //    <<" NData="<<mGFD->NData()<<" inc="<<inc<<endl;
+ //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<" NptDraw="<<NptDraw<<endl;
+
+ return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/pigfd1.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pigfd1.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pigfd1.h	(revision 3445)
@@ -0,0 +1,32 @@
+// 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);
+
+// Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+       
+protected:
+  GeneralFitData* mGFD;
+  bool mAdDO;
+  int VarX;          // numero de variable X ds le GeneralFitData
+  bool ErrX,ErrY;    // Erreur en X et Y ?
+  long NptDraw; // nombre de points effectivement dessines dans la fenetre
+};
+
+#endif
+
Index: /tags/V_Nov2007/SophyaPI/PIext/pigfd2.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pigfd2.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pigfd2.cc	(revision 3445)
@@ -0,0 +1,108 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#include <stdio.h>
+#include "sopnamsp.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_Nov2007/SophyaPI/PIext/pigfd2.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pigfd2.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pigfd2.h	(revision 3445)
@@ -0,0 +1,28 @@
+// 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_Nov2007/SophyaPI/PIext/pihisto.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pihisto.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pihisto.cc	(revision 3445)
@@ -0,0 +1,415 @@
+// Classe traceur d histogramme                 96-99
+//  C. Magneville , R. Ansari               2000-2007
+// (C)  CEA-DAPNIA          LAL-IN2P3/CNRS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <typeinfo>
+
+#include "pihisto.h"
+
+//------ Implementation classe P1DHistoWrapper
+P1DHistoWrapper::P1DHistoWrapper(int_4 asx)
+  :  P1DArrayAdapter(asx) , 
+     mScale(1.) , mOff(0.) , mRetFg(0)
+{
+}
+
+P1DHistoWrapper::~P1DHistoWrapper()
+{
+}
+
+int P1DHistoWrapper::GetStatInfoAsText(vector<string> & /* text */ )
+{
+  return 0;
+}
+
+int P1DHistoWrapper::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  if(opt.size() < 1) return(0); 
+
+  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.substr(0,7) == "hs1") {
+      mScale = 1.;  mOff = 0.; 
+    }
+    else if(opts.substr(0,7) == "hscale=") {
+      mScale = atof(opts.substr(7).c_str());
+    }
+    else if(opts.substr(0,8) == "hoffset=") {
+      mOff = atof(opts.substr(8).c_str());
+    }
+    else if(opts.substr(0,8) == "hbincont") {
+      mRetFg = 0;
+    }    
+    else if(opts.substr(0,7) == "hbinerr") {
+      mRetFg = 1;
+    }    
+    else if(opts.substr(0,7) == "hbinent") {
+      mRetFg = 2;
+    }    
+    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);
+}
+
+int
+P1DHistoWrapper::OptionToString(vector<string> & opt) const
+{
+  char buff[64];
+  sprintf(buff, "hscale=%g", mScale);  opt.push_back(buff);
+  sprintf(buff, "hoffset=%g", mOff);  opt.push_back(buff);
+  if (mRetFg == 2) opt.push_back("hbinent");
+  else if (mRetFg == 1) opt.push_back("hbinerr");
+  else opt.push_back("hbincont");
+
+  return 1;
+}
+
+
+//++
+// Class	PIHisto
+// Lib		PIext
+// include	pihisto.h
+//
+//	Classe traceur d'objet histogramme (classe *P1DHistoWrapper*)
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIHisto(P1DHistoWrapper* histowp, bool ad=false)
+//	Constructeur. Si "ad == true", l'objet "histowp" est détruit par 
+//	le destructeur de l'objet "PIHisto"
+//	Note : "histowp" doit être créé par new si ad==true
+//
+//--
+
+
+PIHisto::PIHisto(P1DHistoWrapper* histowp, bool ad)
+: PIDrawer(), mHistoWp(histowp)
+{
+  mAdDO = ad;     // Flag pour suppression automatique de mHistoWp
+  stats=true;
+  pline=true;
+  error=false;
+  filled=false;
+  spoX=-0.01; spoY=-0.01;
+  SetName("HistoDrw");
+}
+
+PIHisto::~PIHisto()
+{
+  if(mAdDO) delete mHistoWp;
+}
+
+void
+PIHisto::UpdateLimits()
+{
+  if (!mHistoWp)  return;
+  if ( mHistoWp->NBins() < 1 ) {
+    SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), 0., 1.);
+  }
+  double v,hmin,hmax;
+  hmin = hmax = (*mHistoWp)(0);
+  for (int_4 i=1; i<mHistoWp->NBins(); i++) {
+    v = (*mHistoWp)(i);
+    if(v<hmin) hmin = v;
+    if(v>hmax) hmax = v;
+  }
+  if ( isLogScaleY() ) {
+    if ( hmin >= 0.) {
+      if ( hmax <= hmin ) {
+	hmax = hmin*10.;
+	if (hmax <= 0.) hmax = 1.;
+	if (hmin <= 0.) hmin = hmax / 100.; 
+      }
+      else if ( (hmin == 0.) && (hmax > hmin) ) hmin = hmax/1.e6;
+      else hmin /= 1.1;
+    }
+    else if (hmax > 0.) hmax *= 1.1;
+  }
+  else {
+      v = 0.05*(hmax-hmin);
+      hmin -= v;   hmax += v;
+  }
+  if(hmax<=hmin) hmax = hmin+1.;
+    
+  SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), hmin, hmax);
+}
+
+void
+PIHisto::Draw(PIGraphicUC* g, double /*xmin*/, double /*ymin*/, double /*xmax*/, double /*ymax*/)
+{
+  if (axesFlags != kAxesNone) DrawAxes(g);
+
+  if (!mHistoWp)  return;
+  if (mHistoWp->NBins()<=0) return;
+ 
+  mHistoWp->Update();
+
+  // Tracer d'une polyline si demandee
+  bool drawpline=false;
+  if (pline) drawpline=true;
+  // Tracer des marqueurs si demande ou si HProf
+  bool drawmarker=false;
+  if (GetGraphicAtt().GetMarker() != PI_NotDefMarker) drawmarker = true;
+  // Tracer des erreurs ?
+  bool drawerr=false;
+  if (error) drawerr = true;
+  // Fill de l'histo ?
+  bool drawfill=false;
+  if(filled) drawfill=true; else drawfill=false;
+  // Et aussi si on ne demande ni ligne ni marqueur ni erreur ni fill ?
+  if( !drawmarker && !drawfill && !drawerr ) drawpline=true;
+
+  // Remplissage des bins avec la couleur courante (trace en premier)
+  if(drawfill) {
+    for(int i=0; i<mHistoWp->NBins(); i++) {
+      double left   = mHistoWp->BinLowEdge(i);
+      double width  = mHistoWp->BinWidth();
+      double bottom = 0;
+      double height = (*mHistoWp)(i);
+      g->DrawFBox(left,bottom,width,height);
+    }
+  }
+
+  // Trace des marqeurs
+  if(drawmarker) {
+    double x1,y1; 
+    for(int i=0; i<mHistoWp->NBins(); i++) {
+      x1 = mHistoWp->BinCenter(i);
+      y1 = (*mHistoWp)(i);
+      g->DrawMarker(x1,y1);
+    }
+  }
+
+  // Trace des erreurs
+  if(drawerr) {
+    if(GetGraphicAtt().GetLineAtt()==PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
+    double x1,x2,y1,y2;  
+    double bw = mHistoWp->BinWidth();
+    for(int i=0; i<mHistoWp->NBins(); i++) {
+      if(mHistoWp->Error(i)>0.) {
+        // barres d'erreur verticales
+        x1 = x2 = mHistoWp->BinCenter(i);
+        y1 = (*mHistoWp)(i) - mHistoWp->Error(i);
+        y2 = (*mHistoWp)(i) + mHistoWp->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 si demandee
+  if(drawpline) {
+    if(GetGraphicAtt().GetLineAtt()==PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
+    PIGrCoord* x1 = new PIGrCoord[2*mHistoWp->NBins()+2];
+    PIGrCoord* y1 = new PIGrCoord[2*mHistoWp->NBins()+2];
+    double dx = mHistoWp->BinWidth();
+    int npt=0;
+    x1[npt] = mHistoWp->BinLowEdge(0);
+    y1[npt] = 0;
+    npt++;
+    for(int i=0; i<mHistoWp->NBins(); i++) {
+      x1[npt] = mHistoWp->BinLowEdge(i);
+      y1[npt] = (*mHistoWp)(i);
+      npt++;
+      x1[npt] = (double)x1[npt-1] + dx;
+      y1[npt] = y1[npt-1];
+      npt++;
+    }
+    x1[npt] = x1[npt-1];
+    y1[npt] = 0;
+    npt++;
+    g->DrawPolygon(x1,y1,npt,false);
+    delete [] x1; delete [] y1;
+  }
+
+  // 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") stats=true;
+    else if(  opts=="nsta"   || opts=="nstat"
+           || opts=="nostat" || opts=="nostats") stats=false;
+    else if(opts=="err") error=true;
+    else if(opts=="noerr" || opts=="nerr") error=false;
+    else if(opts=="fill") { filled=true; pline=false; }  
+    else if(opts=="nofill" || opts=="nfill") filled=false;
+    else if(opts=="pline") { pline=true; filled=false; }
+    else if(opts=="nopline") pline=false;
+    else if(opts.substr(0,11) == "statposoff=") {
+      double xo=0., yo=0.;
+      sscanf(opts.substr(11).c_str(),"%lf,%lf",&xo, &yo);
+      spoX=xo; spoY=yo;
+    }
+    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;
+
+  // Decodage des options par le histo-wrapper
+  int ndec2 = 0;
+  if ( ( optsz1-ndec1-ndec > 0) && (mHistoWp) ) {
+    ndec2 = mHistoWp->DecodeOptionString(opt, rmdecopt);
+  }
+  return(ndec+ndec1+ndec2);
+}
+
+int
+PIHisto::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+
+ if(stats) opt.push_back("stat"); else opt.push_back("nostat");
+ if(error) opt.push_back("err");  else opt.push_back("noerr");
+ if(filled) opt.push_back("fill"); else opt.push_back("nofill");
+ if(pline) opt.push_back("pline"); else opt.push_back("nopline");
+
+ char str[256]; sprintf(str,"statposoff=%g,%g",spoX,spoY);
+ opt.push_back(str);
+
+ if (mHistoWp) mHistoWp->OptionToString(opt);
+ return 1;
+}
+
+void
+PIHisto::GetOptionsHelpInfo(string& 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 += " pline/nopline: display/do not display as polyline (def= pline) \n";
+info += " err/noerr,nerr: draw/do not draw error bars (def= noerr) \n";
+info += " fill/nofill,nfill: fill/do not fill histo (def= nofill) \n";
+info += " - Use marker attribute (marker=...) to draw markers \n"; 
+info += " statposoff=OffsetX,OffsetY : Position offset for Stats drawing \n";
+info += "      as a fraction of total size \n";
+info += " ---- HistoWrapper options : \n" ;
+info += " hbincont: select bin content as Y value for display (default) \n";
+info += " hbinerr: select bin error as Y value for display \n";
+info += " hbinent: select bin entries as Y value for display \n";
+info += " hscale=value : multiplicative factor for Y value \n" ;
+info += " hoffset=value : additive coefficient for Y value \n" ;
+info += " hs1: set hscale=1 hoffset=0  (default) \n" ;
+// On recupere ensuite la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+return;
+}
+
+void
+PIHisto::DrawStats(PIGraphicUC* g)
+{
+  if (!mHistoWp) 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);
+  vector<string> lines;
+  int nlig = mHistoWp->GetStatInfoAsText(lines);
+  if (nlig < 1) return;
+
+  double cellHeight = nlig*1.2 * cH;
+
+  int idxll = 0;
+  
+  int kl;
+  // on recherche la ligne la plus longue
+  for(kl=1; kl<nlig; kl++)
+    if ( lines[kl].length() > lines[idxll].length() )  idxll = kl;
+
+  double cellWidth =  1.1 * (double)g->CalcStringWidth(lines[idxll].c_str());
+
+  double ofpx = spoX*(XMax()-XMin());
+  double ofpy = spoY*(YMax()-YMin());
+  
+  double xu, yu, cw;
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), -cellWidth);
+  yu = g->DeltaUCY(YMax(), -cellHeight);
+  double recw = XMax()-xu;
+  double rech = YMax()-yu;
+  xu += ofpx;  yu += ofpy;
+  g->DrawBox(xu, yu, recw, rech);
+
+  // 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);
+  xu += ofpx;  yu += ofpy;
+
+  for(kl=0; kl<nlig; kl++) {
+    g->DrawString(xu, yu, lines[kl].c_str() );
+    cw +=  -1.15*cH;
+    yu = g->DeltaUCY(YMax(),cw);  yu += ofpy;
+  }
+                       
+}
+
+/* --Methode-- */
+double
+PIHisto::GetDistanceToPoint(double x, double y)
+{
+ if (!mHistoWp) return 1.e+9;
+
+ double dist = -1.e+18;
+ for(int i=0; i<mHistoWp->NBins(); i++) {
+   double xp=mHistoWp->BinCenter(i);
+   double yp=(*mHistoWp)(i);
+   xp = (xp-x)/(XMax()-XMin())/0.5;
+   yp = (yp-y)/(YMax()-YMin())/0.5;
+   xp = xp*xp+yp*yp;
+   if(dist<0. || xp<dist) dist = xp;
+ }
+ dist=sqrt(fabs(dist));
+ //cout<<dist<<"PIHisto: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
+ //    <<" NBins="<<mHistoWp->NBins()<<endl;
+ //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<endl;
+
+ return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/pihisto.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pihisto.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pihisto.h	(revision 3445)
@@ -0,0 +1,41 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe traceur d histogramme                 96-99
+//            C. Magneville / R. Ansari       2000-2007
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef PIHISTO_H
+#define PIHISTO_H
+
+#include "pidrawer.h"
+#include "phistwrapper.h"
+
+
+class PIHisto : public PIDrawer {
+public:
+                     PIHisto(P1DHistoWrapper* histowp, bool ad=true);
+  virtual           ~PIHisto();
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+
+  inline  P1DHistoWrapper*     HistoWrapper() {return(mHistoWp);}
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual int        OptionToString(vector<string> & opt) const;
+  virtual void       GetOptionsHelpInfo(string& info);
+
+// Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+
+protected:
+  virtual void       DrawStats(PIGraphicUC* g);
+  P1DHistoWrapper*   mHistoWp;
+  bool mAdDO;
+  bool stats;        // if true: draw text with statistical information
+  bool filled;       // if true: fill histo with fg color
+  bool pline;        // if true: draw histogram as polyline 
+  bool error;        // if true: draw error bars
+  double spoX, spoY;  // Stat pos offset par rapport a position defaut
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/pihisto2d.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pihisto2d.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pihisto2d.cc	(revision 3445)
@@ -0,0 +1,1107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pisysdep.h>
+#include PIAPP_H
+
+#include <iostream>
+#include <math.h>
+
+#include "sopnamsp.h"
+#include "pihisto2d.h"
+#include "srandgen.h"
+
+static int dbg = 0;
+
+
+//------ Implementation classe P2DHistoWrapper
+P2DHistoWrapper::P2DHistoWrapper(int_4 asx, int_4 asy) 
+  :  P2DArrayAdapter(asx, asy) , 
+     mScale(1.) , mOff(0.) , mRetFg(0)
+{
+}
+
+P2DHistoWrapper::~P2DHistoWrapper()
+{
+}
+
+int P2DHistoWrapper::GetStatInfoAsText(vector<string> & /* text */ )
+{
+  return 0;
+}
+
+int P2DHistoWrapper::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  if(opt.size() < 1) return(0); 
+
+  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.substr(0,7) == "hs1") {
+      mScale = 1.;  mOff = 0.; 
+    }
+    else if(opts.substr(0,7) == "hscale=") {
+      mScale = atof(opts.substr(7).c_str());
+    }
+    else if(opts.substr(0,8) == "hoffset=") {
+      mOff = atof(opts.substr(8).c_str());
+    }
+    else if(opts.substr(0,8) == "hbincont") {
+      mRetFg = 0;
+    }    
+    else if(opts.substr(0,7) == "hbinerr") {
+      mRetFg = 1;
+    }    
+    else if(opts.substr(0,7) == "hbinent") {
+      mRetFg = 2;
+    }    
+    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);
+}
+
+int
+P2DHistoWrapper::OptionToString(vector<string> & opt) const
+{
+  char buff[64];
+  sprintf(buff, "hscale=%g", mScale);  opt.push_back(buff);
+  sprintf(buff, "hoffset=%g", mOff);  opt.push_back(buff);
+  if (mRetFg == 2) opt.push_back("hbinent");
+  else if (mRetFg == 1) opt.push_back("hbinerr");
+  else opt.push_back("hbincont");
+
+  return 1;
+}
+
+//++
+// 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(P2DHistoWrapper* histowp, bool ad)
+//
+//	Createur d'une classe de dessin pour l'histogramme 2D histo.
+//--
+: PIDrawer(), mHistoWp(histowp), mAdDO(ad), mLogScale(10.), mFPoints(0.5)
+{
+// mAdDO : Flag pour suppression automatique de mHistoWp
+// 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();
+SetStatPosOffset();
+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 && mHistoWp!=NULL) delete mHistoWp;
+}
+
+//++
+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,double 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,double 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(double fmin,double fmax)
+//
+//	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( (mHistoWp) && (mHistoWp->NBinX()>0) && (mHistoWp->NBinY()>0) && (fmin>=fmax) ) {
+  double v,hmin,hmax;
+  hmin = hmax = (*mHistoWp)(0,0);
+  for (int_4 i=0; i<mHistoWp->NBinX(); i++) 
+    for (int_4 j=0; j<mHistoWp->NBinY(); j++) {
+      v = (*mHistoWp)(i, j);
+      if(v<hmin) hmin = v;
+      if(v>hmax) hmax = v;
+    }
+  fmin = hmin;  fmax = hmax;
+}
+
+if(fmin>=fmax) fmax = fmin+1.;
+mHMin = fmin; mHMax = fmax;
+}
+
+//++
+void PIHisto2D::UseFrac(double frmin,double 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,mHistoWp);
+fflush(stdout);
+}
+
+//++
+void PIHisto2D::UpdateLimits()
+//
+//	Definition des tailles graphiques en fonction
+//	des caracteristiques de l'histogramme a dessiner.
+//--
+{
+ if(!mHistoWp) return;
+ SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), mHistoWp->YMin() , mHistoWp->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(!mHistoWp) return;
+if(mHistoWp->NBinX()<=0 || mHistoWp->NBinY()<=0) return;
+
+// Caracteristiques histogramme
+double dx = mHistoWp->WBinX(),dy = mHistoWp->WBinY();
+double p1dx,p1dy;
+g->DGrC2UC(1.,1.,p1dx,p1dy);
+
+// Gamme a representer entre [0,1] mais >=fracmin et scale fracmax
+double fracmin=FMin(), fracmax=FMax();
+double llscale = log10(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)(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<mHistoWp->NBinX(); i++)
+  for(int j=0; j<mHistoWp->NBinY(); j++) {
+
+  r_8 left0,bottom0;
+  mHistoWp->BinLowEdge(i,j,left0,bottom0);
+
+  // Gestion de la dynamique a dessiner
+  double frac = ((*mHistoWp)(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.;
+  double fracred = frac * fracmax;
+
+  // Gestion de la couleur
+  int icol = 0;
+  if (cmap) {
+    icol = int(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(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
+//--
+{
+P2DHistoWrapper* h = HistoWrapper();
+if(h == NULL) return;
+
+int_4 i,j;
+i = floor((x-h->XMin())/h->WBinX()); 
+j = floor((y-h->YMin())/h->WBinY());
+
+if(i>=0 && i<h->NBinX() && j>=0 && j<h->NBinY()) {
+  char str[64];
+  if(fgdiff) {
+    int i0,j0;
+    i0 = floor((x0-h->XMin())/h->WBinX()); 
+    j0 = floor((y0-h->YMin())/h->WBinY());
+    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 (!mHistoWp) 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);
+  vector<string> lines;
+  int nlig = mHistoWp->GetStatInfoAsText(lines);
+  if (nlig < 1) return;
+
+  double cellHeight = nlig*1.2 * cH;
+
+  int idxll = 0;
+  
+  int kl;
+  // on recherche la ligne la plus longue
+  for(kl=1; kl<nlig; kl++)
+    if ( lines[kl].length() > lines[idxll].length() )  idxll = kl;
+
+  double cellWidth =  1.1 * (double)g->CalcStringWidth(lines[idxll].c_str());
+
+
+  double ofpx = spoX*(XMax()-XMin());
+  double ofpy = spoY*(YMax()-YMin());
+
+  double xu, yu, cw;
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), -cellWidth);
+  yu = g->DeltaUCY(YMax(), -cellHeight);
+  double recw = XMax()-xu;
+  double rech = YMax()-yu;
+  xu += ofpx;  yu += ofpy;
+  g->DrawBox(xu, yu, recw, rech);
+
+  // L'ecriture des labels
+  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);
+  xu += ofpx;  yu += ofpy;
+
+  for(kl=0; kl<nlig; kl++) {
+    g->DrawString(xu, yu, lines[kl].c_str() );
+    cw +=  -1.15*cH;
+    yu = g->DeltaUCY(YMax(),cw);  yu += ofpy;
+  }
+
+
+  //  printf("H[%d,%d] Dynamique: [%g,%g] Frac [%g,%g]\n"
+  //        ,mHistoWp->NBinX(),mHistoWp->NBinY(),HMin(),HMax(),FMin(),FMax());
+}
+
+//++
+char PIHisto2D::HPrint2(double 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 = mHistoWp->WBinX(),dy = mHistoWp->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,11) == "statposoff=") {
+      double xo=0., yo=0.;
+      sscanf(opts.substr(11).c_str(),"%lf,%lf",&xo, &yo);
+      SetStatPosOffset(xo, yo);
+    } else if(opts.substr(0,8)=="h2scale=") {
+      unsigned short t=TypScale(); double 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,%lf",&ls);}
+      UseScale(t,ls);
+    } else if(opts.substr(0,7)=="h2disp=") {
+      unsigned short t=TypDisplay(); double 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,%lf",&fpts);}
+      UseDisplay(t,fpts);
+    } else if(opts.substr(0,6)=="h2dyn=") {
+      double hmin=HMin(),hmax=HMax(); size_t q = opts.find(',');
+      sscanf(opts.c_str(),"h2dyn=%lf",&hmin);
+      if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%lf",&hmax);
+      UseDyn(hmin,hmax);
+    } else if(opts.substr(0,7)=="h2frac=") {
+      double fmin=FMin(),fmax=FMax(); size_t q = opts.find(',');
+      sscanf(opts.c_str(),"h2frac=%lf",&fmin);
+      if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%lf",&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;
+
+  // Decodage des options par le histo-wrapper
+  int ndec2 = 0;
+  if ( ( optsz1-ndec1-ndec > 0) && (mHistoWp) ) {
+    ndec2 = mHistoWp->DecodeOptionString(opt, rmdecopt);
+  }
+
+  // Liste des options si demande
+  if(listopt) Print();
+
+  return(ndec+ndec1+ndec2);
+}
+
+int PIHisto2D::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+ char str[256];
+
+ if(stats) opt.push_back("stat"); else opt.push_back("nstat");
+
+ sprintf(str,"statposoff=%f,%f",spoX,spoY);
+ opt.push_back(str);
+
+ if(mTypDisp==0) sprintf(str,"h2disp=var");
+  else if(mTypDisp==1) sprintf(str,"h2disp=pts,%g",mFPoints);
+    else if(mTypDisp==2) sprintf(str,"h2disp=hbk");
+      else if(mTypDisp==3) sprintf(str,"h2disp=img");
+ opt.push_back(str);
+
+ if(mTypScal==0) sprintf(str,"h2scale=lin");
+   else if(mTypScal==1) sprintf(str,"h2disp=log,%g",mLogScale);
+ opt.push_back(str);
+
+ sprintf(str,"h2dyn=%g,%g",mHMin,mHMax);
+ opt.push_back(str);
+
+ sprintf(str,"h2frac=%g,%g",mFracMin,mFracMax);
+ opt.push_back(str);
+
+ if(mRevCmap) opt.push_back("revcmap");
+
+ // Les options du Histo2DWrapper :
+ if(mHistoWp) mHistoWp->OptionToString(opt);
+ return 1;
+}
+
+
+//++
+void PIHisto2D::GetOptionsHelpInfo(string& info)
+//
+//	Help relatif au options
+//--
+{
+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 graphic att. to define color table (ex: grey32,midas_heat,...)\n";
+info += "            (see general graphicatt description)\n";
+info += "- use \"revcmap\" to reverse color table\n";
+info += "- h2frac=[fmin][,fmax]: choose sub-range display [0,1]\n";
+info += " ---- HistoWrapper options : \n" ;
+info += " hbincont: select bin content as Y value for display (default) \n";
+info += " hbinerr: select bin error as Y value for display \n";
+info += " hbinent: select bin entries as Y value for display \n";
+info += " hscale=value : multiplicative factor for Y value \n" ;
+info += " hoffset=value : additive coefficient for Y value \n" ;
+info += " hs1: set hscale=1 hoffset=0  (default) \n" ;
+// On recupere ensuite la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+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,"H2D-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(), "PIUniCol32");
+mCasc[2] = new PIMenu(mOPop[2]->Menu(),"MIDAS-CMap");
+int kcc,nsct1=5,nsct2=9,nsct3=17,nsct4=PIColorMap::NumberStandardColorMaps()-2;
+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<nsct4; kcc++) 
+  mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
+mOPop[2]->AppendPDMenu(mCasc[2]);
+for(kcc=nsct4; 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<3;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(),"%lf %lf",&mHMin,&mHMax);
+  sscanf(mText[1]->GetText().c_str(),"%lf %lf",&mFracMin,&mFracMax);
+  sscanf(mText[2]->GetText().c_str(),"%lf",&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_Nov2007/SophyaPI/PIext/pihisto2d.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pihisto2d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pihisto2d.h	(revision 3445)
@@ -0,0 +1,125 @@
+// 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 "pidrawer.h"
+#include "piscdrawwdg.h"
+
+#include "phistwrapper.h"
+
+////////////////////////////////////////////////////////////////////
+class PIHisto2D : public PIDrawer {
+public:
+  PIHisto2D(P2DHistoWrapper* h2wp, bool ad=false);
+  virtual ~PIHisto2D();
+
+  void UseColors(bool fg=false,CMapId cmap=CMAP_GREYINV32,bool revcmap=false);
+  void UseScale(unsigned short type=0,double logscale=10.);
+  void UseDisplay(unsigned short type=0,double fnpt=0.5);
+  void UseDyn(double hmin=1.,double hmax=-1.);
+  void UseFrac(double frmin=0.1,double 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;}
+  inline  void SetStatPosOffset(double ofx=-0.01, double ofy=-0.01) 
+          {spoX=ofx; spoY=ofy; }
+
+  //  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 int  OptionToString(vector<string> & opt) const;
+  virtual void GetOptionsHelpInfo(string& info);
+
+  // Methodes inline
+  inline P2DHistoWrapper*       HistoWrapper()   {return(mHistoWp);}
+  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 double         FPoints()     {return(mFPoints);}
+  inline double         HMax()        {return(mHMax);}
+  inline double         HMin()        {return(mHMin);}
+  inline double         FMax()        {return(mFracMax);}
+  inline double         FMin()        {return(mFracMin);}
+  inline double         LogScale()    {return(mLogScale);}
+
+protected:
+  int NPixBin(PIGraphicUC* g);
+  char HPrint2(double f);
+
+  P2DHistoWrapper* mHistoWp;
+  bool mAdDO; bool stats;
+  bool mFgCol; CMapId mCmap; bool mRevCmap;
+  unsigned short mTypScal; double mLogScale;
+  unsigned short mTypDisp; double mFPoints;
+  double mHMin,mHMax;
+  double mFracMin,mFracMax;
+  double spoX, spoY; // Stat pos offset par rapport a position defaut
+};
+
+////////////////////////////////////////////////////////////////////
+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[3];
+  PIButton  * mBut[4];
+  PILabel   * mLab[4];
+  PIText    * mText[3];
+  PIScale   * mPScal;
+  PICheckBox* mCkb;
+
+  bool mFgCol; CMapId mCmap; bool mRevCmap;
+  unsigned short mTypScal; double mLogScale;
+  unsigned short mTypDisp; double mFPoints;
+  double mHMin,mHMax;
+  double mFracMin,mFracMax;
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/piinit.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piinit.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piinit.cc	(revision 3445)
@@ -0,0 +1,162 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "piinit.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+
+#include "nomdvladapter.h"
+#include "nomhistadapter.h"
+#include "nomherradapter.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 "datatable.h"
+#include "swppfdtable.h"
+
+#include "nomskymapadapter.h"
+#include "spherethetaphi.h"
+#include "spherehealpix.h"
+#include "localmap.h"
+#include "sphereecp.h"
+
+#include "specrespvector.h"
+#include "gaussfilt.h"
+#include "nomspecrespadapter.h"
+
+#include "piaversion.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 DVList, new NOMAdapter_DVList );
+  serv->RegisterClass(new Histo, new NOMAdapter_Histo );
+  serv->RegisterClass(new HProf, new NOMAdapter_Histo );
+  serv->RegisterClass(new Histo2D, new NOMAdapter_Histo2D );
+
+  serv->RegisterClass(new HistoErr, new NOMAdapter_HistoErr );
+  serv->RegisterClass(new Histo2DErr, new NOMAdapter_Histo2DErr );
+
+  serv->RegisterClass(new NTuple, new NOMAdapter_NTuple );
+
+  serv->RegisterClass(new DataTable, new NOMAdapter_DataTable );
+  serv->RegisterClass(new SwPPFDataTable, new NOMAdapter_DataTable );
+  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<uint_2>, new NOMAdapter_TArray<uint_2> );
+  serv->RegisterClass(new TArray<int_2>, new NOMAdapter_TArray<int_2> );
+  serv->RegisterClass(new TArray<int_4>, new NOMAdapter_TArray<int_4> );
+  serv->RegisterClass(new TArray<int_8>, new NOMAdapter_TArray<int_8> );
+  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<uint_2>, new NOMAdapter_TMatrix<uint_2> );
+  serv->RegisterClass(new TMatrix<uint_2>, new NOMAdapter_TMatrix<uint_2> );
+  serv->RegisterClass(new TVector<int_2>, new NOMAdapter_TMatrix<int_2> );
+  serv->RegisterClass(new TMatrix<int_2>, new NOMAdapter_TMatrix<int_2> );
+  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<int_8>, new NOMAdapter_TMatrix<int_8> );
+  serv->RegisterClass(new TMatrix<int_8>, new NOMAdapter_TMatrix<int_8> );
+  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
+
+  /*  Avril 2007 : Prise en charge des images par NOMAdapter_TMatrix  au lieu de
+      NOMAdapter_Image<T> , deplace ci-dessous dans SANS_EVOLPLANCK */
+  serv->RegisterClass(new Image<uint_2>, new NOMAdapter_TMatrix<uint_2> );
+  serv->RegisterClass(new Image<int_2>, new NOMAdapter_TMatrix<int_2> );
+  serv->RegisterClass(new Image<int_4>, new NOMAdapter_TMatrix<int_4> );
+  serv->RegisterClass(new Image<int_8>, new NOMAdapter_TMatrix<int_8> );
+  serv->RegisterClass(new Image<r_4>, new NOMAdapter_TMatrix<r_4> );
+  serv->RegisterClass(new Image<r_8>, new NOMAdapter_TMatrix<r_8> );
+  serv->RegisterClass(new Image<complex<r_4> >, new NOMAdapter_TMatrix<complex<r_4> > );
+  serv->RegisterClass(new Image<complex<r_8> >, new NOMAdapter_TMatrix<complex<r_8> > );
+
+#ifdef SANS_EVOLPLANCK
+  serv->RegisterClass(new Image<uint_2>, new  NOMAdapter_Image<uint_2> );
+  serv->RegisterClass(new Image<int_2>, new  NOMAdapter_Image<int_2> );
+  serv->RegisterClass(new Image<int_4>, new  NOMAdapter_Image<int_4> );
+  serv->RegisterClass(new Image<r_4>, new  NOMAdapter_Image<r_4> );
+  serv->RegisterClass(new Image<r_8>, new  NOMAdapter_Image<r_8> );
+
+  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 SphereECP<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 SphereECP<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 SphereECP<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 SphereECP<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 SphereECP<complex<double> >, new NOMAdapter_PixelMap<complex<double> > );
+
+  serv->RegisterClass(new GaussianFilter, new NOMAdapter_SpectralResponse );
+  serv->RegisterClass(new SpecRespVec, new NOMAdapter_SpectralResponse );
+
+  SophyaInitiator::RegisterModule("PIext/piapp", PIAPP_VERSIONNUMBER);
+#endif  
+}
+
+PIAppInitiator::~PIAppInitiator()
+{
+  FgInit--;
+/*  if (FgInit == 0)
+    {
+    }  */
+}
+
Index: /tags/V_Nov2007/SophyaPI/PIext/piinit.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/piinit.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/piinit.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIext/pimgadapter.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pimgadapter.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pimgadapter.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIext/pintup3d.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pintup3d.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pintup3d.cc	(revision 3445)
@@ -0,0 +1,366 @@
+// Peida Interactive   -   PI            R. Ansari 97-99
+// Traceur3D (Drawer) pour NTupleInterface  
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include "sopnamsp.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; 
+  aScxy = aScz = true;
+  UseSizeScale(true, 5);
+  UseColorScale(true);
+  ConnectPoints(false);
+  SelectXYZ(NULL, NULL, NULL);
+  SelectWt(NULL);
+  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)
+{
+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);
+
+  ComputeScaleFactor(xmin, xmax, ymin, ymax, zmin, zmax, 
+		     aScxy, aScz, mScy, mScz);
+  
+  // cout << " DEBUG - NTup3D X:" << XMin3() << "-" << XMax3() " s=" << mScx
+  //     <<  " Y:" YMin3() << "-" << YMax3() << " 
+  xmin *= mScx;  xmax *= mScx; 
+  ymin *= mScy;  ymax *= mScy; 
+  zmin *= mScz;  zmax *= 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)/2., 
+            (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, zmax, mScx, mScy, mScz);
+
+  /*
+  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);
+  */
+
+
+//  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.e-19;
+//  Pour tracer des markers avec couleur en fonction de Wt (poids)
+PIColorMap * cmap = NULL;
+double dwc = 1.;
+double nwc = 1.;
+bool revcmap;
+CMapId mcmapid = GetGraphicAtt().GetColMapId(revcmap);
+if( colorScale && (wK >= 0) && (mcmapid != CMAP_OTHER) ) {
+  cmap = new PIColorMap(mcmapid);
+  cmap->ReverseColorIndex(revcmap);
+  nwc = cmap->NCol();
+  dwc = (wMax-wMin)/nwc;
+}
+
+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);
+
+// Taille - couleur de marker en fonction du poids
+  if (wK >= 0) wp = mNT->GetCell(i, wK);
+  if (mrkSzScale && (wK >= 0)) {   // Changement de taille
+    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);
+  }
+// Couleur du marker en fonction du poids
+  if( colorScale && (wK >= 0) && cmap ) {
+    int cid = (int)((wp-wMin)/dwc);
+    if (cid < 0) cid = 0;
+    if (cid >= nwc)  cid = nwc-1;
+    g->SelForeground(*cmap, cid);
+  }
+
+  if ( (i > 0) && connectPts ) // On relie les points ...
+    g3->DrawLine3D(ScaleX(xl), ScaleY(yl), ScaleZ(zl), ScaleX(xp), ScaleY(yp), ScaleZ(zp));
+  nok++;
+  if ( xebK >= 0 ) {
+    xer = mNT->GetCell(i, xebK);
+    g3->DrawLine3D(ScaleX(xp-xer), ScaleY(yp), ScaleZ(zp), ScaleX(xp+xer), ScaleY(yp), ScaleZ(zp) );
+  }
+  if ( yebK >= 0 ) {
+    yer = mNT->GetCell(i, yebK);
+    g3->DrawLine3D(ScaleX(xp), ScaleY(yp-yer), ScaleZ(zp), ScaleX(xp), ScaleY(yp+yer), ScaleZ(zp) );
+  }
+  if ( zebK >= 0 ) {
+    zer = mNT->GetCell(i, zebK);
+    g3->DrawLine3D(ScaleX(xp), ScaleY(yp), ScaleZ(zp-zer), ScaleX(xp), ScaleY(yp), ScaleZ(zp+zer));
+  }
+  // Trace du marker
+  if ((wK >= 0)||(lK < 0)||(mmrk != PI_NotDefMarker))  
+    g3->DrawMarker3D(ScaleX(xp), ScaleY(yp), ScaleZ(zp)); 
+  // Trace eventuel du label
+  if (lK >= 0) g3->DrawString3D(ScaleX(xp), ScaleY(yp), ScaleZ(zp), 
+				mNT->GetCelltoString(i, lK).c_str());
+}
+
+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 : "connectpoints" "noconnectpoints" 
+    ou plus complexes, par exemple "dynamic=-3,3"
+    Rc: La methode renvoie le nombre d'options decodees 
+*/
+
+/* --Methode-- */
+int PINTuple3D::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 = PIDrawer3D::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 == "connectpoints") ConnectPoints(true);
+    else if (opts == "noconnectpoints") ConnectPoints(false);
+    else if (opts == "colorscale") UseColorScale(true);
+    else if (opts == "nocolorscale") UseColorScale(false);
+    else if (opts == "sizescale") UseSizeScale(true);
+    else if (opts == "nosizescale") UseSizeScale(false);
+    else if (opts.substr(0,10) == "sizescale=") { 
+      int nbn = atoi(opts.substr(10).c_str());
+      UseSizeScale(true, nbn);
+    }
+    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);  
+}
+
+int PINTuple3D::OptionToString(vector<string> & opt) const
+{
+ PIDrawer3D::OptionToString(opt);
+
+ if(connectPts) opt.push_back("connectpoints");
+   else opt.push_back("noconnectpoints");
+
+ if(colorScale) opt.push_back("colorscale");
+   else opt.push_back("nocolorscale");
+
+ if(mrkSzScale) {
+   char str[256];
+   if(nWbins>0) {sprintf(str,"sizescale=%d",nWbins); opt.push_back(str);}
+     else opt.push_back("sizescale");
+ } else opt.push_back("nosizescale");
+
+ return 1;
+}
+
+/* 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 PINTuple3D::GetOptionsHelpInfo(string& info)
+{
+info += " ---- PINTuple3D options help info : \n" ;
+info += "  connectpoints: The points are connected by a line \n";
+info += "  noconnectpoints (this is the default) \n";
+info += "  colorscale/nocolorscale (Use color scale for weight) \n";
+info += "  sizescale/sizescale=nbins/nosizescale (Use marker size for weight) \n";
+// On recupere ensuite la chaine info de la classe de base
+PIDrawer3D::GetOptionsHelpInfo(info);
+return;
+}
+
Index: /tags/V_Nov2007/SophyaPI/PIext/pintup3d.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pintup3d.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pintup3d.h	(revision 3445)
@@ -0,0 +1,53 @@
+#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);
+  virtual void       SelectErrBar(const char* erbx=NULL, const char* erby=NULL, const char* erbz=NULL);
+  virtual void       SelectLabel(const char* plabel);
+
+  inline  void       ConnectPoints(bool fg=false) { connectPts = fg; }
+
+  // Gestion de la representation de poids
+  inline  void       UseSizeScale(bool fg=true, int nbins=5)
+    { mrkSzScale = fg; if (nbins>0) nWbins = nbins; }
+  inline  void       UseColorScale(bool fg=true) { colorScale = fg; }
+
+  inline  bool       GetSizeScale(int& nbins) 
+    { nbins = nWbins; return mrkSzScale; }
+  inline  bool       GetColScale() { return colorScale; }
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual int        OptionToString(vector<string> & opt) const;
+//   Texte d'aide des options disponibles
+  virtual void       GetOptionsHelpInfo(string& info);
+       
+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
+  bool mrkSzScale;     // true -> Taille de markers variable suivant poids
+  int nWbins;          // Nombre de bins taille de marker variable
+  bool colorScale;     // true -> Couleur de marker variable suivant poids
+
+  bool connectPts;          // true -> les points sont relies par une ligne
+
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/pintuple.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pintuple.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pintuple.cc	(revision 3445)
@@ -0,0 +1,508 @@
+// Peida Interactive   -   PI        R. Ansari 97-99
+// Traceur (Drawer) pour NTupleInterface  
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include "sopnamsp.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 nom de colonne poids est spécifié,
+//	la taille et/ou la couleur des signes (markers) sera fonction
+//	de la valeur de poids.
+//--
+//++
+// 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 dans ce cas.
+//--
+ 
+/* --Methode-- */
+PINTuple::PINTuple(NTupleInterface* nt, bool ad)
+: PIDrawer()
+{
+  mNT = nt;
+  mAdDO = ad; 
+  SetStats(true);
+  SetStatPosOffset();
+  ConnectPoints(false);
+  UseSizeScale(true, 5);
+  UseColorScale(true);
+  SelectXY(NULL, NULL);
+  SelectWt(NULL);
+  SelectErrBar();
+  SelectLabel(NULL);
+  SelectColorByName(NULL);
+  SelectColorByIndex(NULL);
+  SetName("NTupleDrw");
+  NptDraw = 0;
+
+}
+
+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)
+{
+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::SelectColorByName(const char* pcolnm)
+{
+if (pcolnm == NULL) cnK = -1;
+else {  string name = pcolnm;  cnK = mNT->ColumnIndex(name);  }
+if (cnK >= 0)  ciK = -1;
+}
+
+/* --Methode-- */
+void  PINTuple::SelectColorByIndex(const char* pcolidx)
+{
+if (pcolidx == NULL) ciK = -1;
+else {  string name = pcolidx;  ciK = mNT->ColumnIndex(name);  }
+if (ciK >= 0)  cnK = -1;
+}
+
+
+/* --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-- */
+#define NMXMULTP_LOCAL  30   // Pour multipoint sans new
+void PINTuple::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+double xp,yp,xer,yer,wp;
+double xl,yl;
+long nok;
+int npolyg;
+
+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.e-19;
+
+// La couleur par defaut (pour le trace avec couleur specifie par nom de colonne (06/2007)
+PIColors defcol = GetGraphicAtt().GetColor();
+if (defcol == PI_NotDefColor) defcol = PI_Black;
+
+//  Pour tracer des markers avec couleur en fonction de Wt (poids)
+PIColorMap * cmap = NULL;
+double dwc = 1.;
+int nwc = 1;
+bool revcmap;
+CMapId mcmapid = GetGraphicAtt().GetColMapId(revcmap);
+if( colorScale && (wK >= 0) && (mcmapid != CMAP_OTHER) ) {
+  cmap = new PIColorMap(mcmapid);
+  cmap->ReverseColorIndex(revcmap);
+  nwc = cmap->NCol();
+  dwc = (wMax-wMin)/(double)nwc;
+}
+
+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;
+PIGrCoord xpolyg[NMXMULTP_LOCAL], ypolyg[NMXMULTP_LOCAL];
+npolyg = 0;
+NptDraw = 0;
+
+// Mai 2005: Correction bug trace des lignes avec le pts en dehors de la zone (Reza)
+// flags pour la gestion des points/lignes a tracer
+bool fgokcurpt = true;  // Point courant dans la zone a tracer
+bool fgoklastpt = true;   // Le dernier point etait dans la zone a tracer
+for (long i=0; i<(long)mNT->NbLines(); i++) {
+  xl = xp;  yl = yp; fgoklastpt = fgokcurpt;
+
+  xp = mNT->GetCell(i, xK);
+  yp = mNT->GetCell(i, yK);
+
+  // Comptage du nombre de pts dans la zone graphique du widget
+  if ( !((xp < xmin2) || (xp > xmax2) || (yp < ymin2) || (yp > ymax2)) )  nok++;
+  // Gestion des limites a tracer
+  fgokcurpt = true;
+  if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) ) fgokcurpt = false;
+  else NptDraw++;
+
+// Taille - couleur de marker en fonction du poids
+  if ( fgokcurpt &&(wK >= 0) ) wp = mNT->GetCell(i, wK);
+  if ( fgokcurpt && mrkSzScale && (wK >= 0) ) {  // Changement de taille
+    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);
+  }
+// Couleur du marker en fonction du poids
+  if( fgokcurpt && colorScale && (wK >= 0) && cmap ) {
+    int cid = (int)((wp-wMin)/dwc);
+    if (cid < 0) cid = 0;
+    if (cid >= nwc)  cid = nwc-1;
+    g->SelForeground(*cmap, cid);
+  }
+
+// Si on a specifie un nom de colonne pour la couleur (06/2007) 
+  if ( (cnK >= 0) || (ciK >= 0) ) {
+    PIColors scol = defcol;
+    if (cnK > 0) 
+      scol = PIGraphicAtt::ColNameToColor(mNT->GetCelltoString(i, cnK));
+    else 
+      scol = PIGraphicAtt::ColIndexToColor(mNT->GetCell(i, ciK));
+    if (scol == PI_NotDefColor) scol = defcol;
+    g->SelForeground(scol);
+  }
+
+  // Trace d'une ligne reliant les points
+  if( connectPts ) {
+    // On initialise le polygone avec le dernier point, si ce dernier ok
+    if((npolyg==0) && (i>0) && fgokcurpt) {xpolyg[0]=xl; ypolyg[0]=yl; npolyg=1;}
+    // On ajoute le point courant au polygone - sauf si celui-ci est vide
+    if((npolyg<NMXMULTP_LOCAL) && (npolyg>0))
+      {xpolyg[npolyg]=xp; ypolyg[npolyg]=yp; npolyg++;}
+    // On trace le polygone s'il est plein - ou le point courant en dehors
+    // (point courant en dehors -> discontinuite de la ligne 
+    if( !fgokcurpt || (npolyg==NMXMULTP_LOCAL) )
+      {g->DrawPolygon(xpolyg,ypolyg,npolyg,false); npolyg=0;}
+  }
+
+  // Plus rien a faire si point en dehors -- on s'en va 
+  if (!fgokcurpt)  continue;
+
+  // Trace des erreurs selon X et Y
+  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);
+  }
+
+  // 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());
+
+}
+
+// Fin du trace d'une ligne reliant les points  si necessaire
+if( connectPts && npolyg>1 )
+  {g->DrawPolygon(xpolyg,ypolyg,npolyg,false); npolyg=0;}
+
+if (stats) { // Trace de stats 
+  g->SelForeground(defcol);
+  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=%ld (/%ld)", (long)nok, (long)mNT->NbLines());
+  double cellWidth =   1.1 * (double)g->CalcStringWidth(label);
+  double xu, yu, cw;
+  double ofpx = spoX*(XMax()-XMin());
+  double ofpy = spoY*(YMax()-YMin());
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), - cellWidth);
+  yu = g->DeltaUCY(YMax(), - cellHeight);
+  double recw = XMax()-xu;
+  double rech = YMax()-yu;
+  xu += ofpx;  yu += ofpy;
+  g->DrawBox(xu, yu, recw, rech);
+  // 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);
+  xu += ofpx;  yu += ofpy;
+  g->DrawString(xu,yu,label);
+}
+
+if (cmap) delete cmap;
+return;
+}
+#undef NMXMULTP_LOCAL
+
+/* --Methode-- */
+void PINTuple::AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax)
+{
+if (!mNT) return;
+if ( (xK < 0) || (yK < 0) )  return;
+
+long ncnt = 0;
+double xp,yp;
+char buff[128];
+sprintf(buff,"PINTuple: NLines= %ld  NCol= %ld \n", (long)mNT->NbLines(),  
+	(long)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," %ld points inside selected region \n", (long)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 if(opts.substr(0,11) == "statposoff=") {
+      double xo=0., yo=0.;
+      sscanf(opts.substr(11).c_str(),"%lf,%lf",&xo, &yo);
+      SetStatPosOffset(xo, yo);
+    }
+    else if (opts == "connectpoints") ConnectPoints(true);
+    else if (opts == "noconnectpoints") ConnectPoints(false);
+    else if (opts == "colorscale") UseColorScale(true);
+    else if (opts == "nocolorscale") UseColorScale(false);
+    else if (opts == "sizescale") UseSizeScale(true);
+    else if (opts == "nosizescale") UseSizeScale(false);
+    else if (opts.substr(0,10) == "sizescale=") { 
+      int nbn = atoi(opts.substr(10).c_str());
+      UseSizeScale(true, nbn);
+    }
+
+    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);  
+}
+
+int PINTuple::OptionToString(vector<string> & opt) const
+{
+ PIDrawer::OptionToString(opt);
+
+ char str[256]; 
+
+ if(stats) opt.push_back("stat"); else opt.push_back("nstat");
+
+ sprintf(str,"statposoff=%lf,%lf",spoX,spoY); opt.push_back(str);
+
+ if(connectPts) opt.push_back("connectpoints");
+   else opt.push_back("noconnectpoints");
+
+ if(colorScale) opt.push_back("colorscale");
+   else opt.push_back("nocolorscale");
+
+ if(mrkSzScale) {
+   if(nWbins>0) {sprintf(str,"sizescale=%d",nWbins); opt.push_back(str);}
+     else opt.push_back("sizescale");
+ } else opt.push_back("nosizescale");
+
+ return 1;
+}
+
+/* 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)
+{
+info += " ---- PINTuple options help info : \n" ;
+info += "  sta,stat,stats:            activate   statistic display\n";
+info += "  nsta,nstat,nostat,nostats: deactivate statistic display\n";
+info += "  statposoff=OffsetX,OffsetY : Position offset for Stats drawing \n";
+info += "      as a fraction of total size \n";
+info += "  connectpoints: The points are connected by a line \n";
+info += "  noconnectpoints (this is the default) \n";
+info += "  colorscale/nocolorscale (Use color scale for weight) \n";
+info += "  sizescale/sizescale=nbins/nosizescale (Use marker size for weight) \n";
+info += "   (and usual color/line/marker/... attribute decoding)  \n";
+// On recupere ensuite la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+return;
+}
+
+
+/* --Methode-- */
+double PINTuple::GetDistanceToPoint(double x, double y)
+{
+ if(!mNT) return 1.e+9;
+ if( xK<0 || yK<0 ) return 1.e+9;
+
+ const int nessai = 100;
+ long inc = (NptDraw>nessai) ? (long)(NptDraw/nessai)+1 : 1;
+
+ double dist = -1.e+18;
+ long n = 0;
+ for(long i=0; i<(long)mNT->NbLines(); i++) {
+   double xp=mNT->GetCell(i,xK);
+   if(xp<XMin() || xp>XMax()) continue;
+   double yp=mNT->GetCell(i,yK);
+   if(yp<YMin() || yp>YMax()) continue;
+   if(n%inc==0) {
+     xp = (xp-x)/(XMax()-XMin())/0.5;
+     yp = (yp-y)/(YMax()-YMin())/0.5;
+     xp = xp*xp+yp*yp;
+     if(dist<0. || xp<dist) dist = xp;
+   }
+   n++;
+ }
+ dist=sqrt(fabs(dist));
+ //cout<<"PINTuple: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
+ //    <<" NbLines="<<mNT->NbLines()<<" inc="<<inc<<endl;
+ //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<" NptDraw="<<NptDraw<<endl;
+
+ return dist;
+}
Index: /tags/V_Nov2007/SophyaPI/PIext/pintuple.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pintuple.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pintuple.h	(revision 3445)
@@ -0,0 +1,76 @@
+// 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);
+  virtual void       SelectErrBar(const char* erbx=NULL, const char* erby=NULL);
+  virtual void       SelectLabel(const char* plabel=NULL);
+  virtual void       SelectColorByName(const char* pcolnm=NULL);
+  virtual void       SelectColorByIndex(const char* pcolidx=NULL);
+
+  inline  void       ConnectPoints(bool fg=false) { connectPts = fg; }
+
+  // Gestion de la representation de poids
+  inline  void       UseSizeScale(bool fg=true, int nbins=5)
+    { mrkSzScale = fg; if (nbins>0) nWbins = nbins; }
+  inline  void       UseColorScale(bool fg=true) { colorScale = fg; }
+
+  inline  bool       GetSizeScale(int& nbins) 
+    { nbins = nWbins; return mrkSzScale; }
+  inline  bool       GetColScale() { return colorScale; }
+
+  inline  void       SetStats(bool fg=true) { stats = fg; }
+  inline  void       SetStatPosOffset(double ofx=-0.01, double ofy=-0.01) 
+          {spoX=ofx; spoY=ofy; }
+
+  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);
+  virtual int        OptionToString(vector<string> & opt) const;
+//   Texte d'aide des options disponibles
+  virtual void       GetOptionsHelpInfo(string& info);
+
+// Renvoie une distance au point x,y
+  virtual double     GetDistanceToPoint(double x, double y);
+       
+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)
+  int cnK;             // Index du nom de variable couleur (par nom de couleur)
+  int ciK;             // Index du nom de variable couleur (par index de couleur)
+  double wMin, wMax;   // Valeurs de poids min/max
+  bool mrkSzScale;     // true -> Taille de markers variable suivant poids
+  int nWbins;          // Nombre de bins taille de marker variable
+  bool colorScale;     // true -> Couleur de marker variable suivant poids
+  bool stats;               // true -> indication du nb de points
+  bool connectPts;          // true -> les points sont relies par une ligne
+  double spoX, spoY; // Stat pos offset par rapport a position defaut
+  long NptDraw; // nombre de points effectivement dessines dans la fenetre
+};
+
+#endif
+
+
+
+
Index: /tags/V_Nov2007/SophyaPI/PIext/pipodrw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pipodrw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pipodrw.cc	(revision 3445)
@@ -0,0 +1,111 @@
+//  Adaptateurs et Drawers divers pour Outils PEIDA++
+//                             R. Ansari  06-08/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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;
+  }
+}
+
+
+#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)); 
+}
+
+------- FIN SUPPRESSION */
+
+// ----------------------------------------------------------
+// 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_Nov2007/SophyaPI/PIext/pipodrw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pipodrw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pipodrw.h	(revision 3445)
@@ -0,0 +1,68 @@
+// 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"
+#include "hist2err.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;
+};
+
+
+
+#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_Nov2007/SophyaPI/PIext/pisiadw.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pisiadw.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pisiadw.cc	(revision 3445)
@@ -0,0 +1,346 @@
+#include "sopnamsp.h"
+#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()
+{
+PIWindow::Show();
+SetUnSensitive();
+UpdateList(-1);
+return;
+}
+/* --Methode-- */
+void ObjMgrWind::Hide()
+{
+dap->ObjMgr()->SetObjMgrWindowVisibility(false);
+PIWindow::Hide();
+return;
+}
+
+/* --Methode-- */
+void ObjMgrWind::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+
+if (sender == objlist)  return; // Changement de selection d'objet - on ne fait rien
+  // PIMessage ssg = ModMsg(msg);
+msg = UserMsg(msg);
+if (msg == 90)  {
+  dap->SetReady();
+  this->Hide();
+  return;
+  }
+else if (msg >= 30000) {
+  UpdateList(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;
+
+string cmd;
+switch (msg)
+  {
+  case 10:
+    cmd = "SCO " + nom;
+    break;
+  case 20:
+    cmd = "DIS " + nom;
+    break;
+  case 30:
+    cmd = "PRT " + nom;
+    break;
+  case 40:
+    cmd = "SAV " + nom;
+    break;
+  case 50:
+    cmd = "DEL " + nom;
+    break;
+
+  default:    
+    //    printf("DEBUG/ObjMgrW::Process %d %d \n", (int)msg, (int)ssg); 
+    break;
+  }
+ dap->getSOpExObj()->AddOpe(cmd);    
+return;
+}
+
+/* --Methode-- */
+void ObjMgrWind::UpdateList(int did)
+{
+if (!Visible()) return;
+if ( (did >= 0)&&(did != GetCurDirId()) )  return;
+char buff[48];
+sprintf(buff,"UPD %d",did);
+string cmd = buff;
+dap->getSOpExObj()->AddOpe(cmd); 
+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; }
+
+int nbtags = 0;
+#ifdef SANS_EVOLPLANCK
+nbtags = mPin->NbTags();
+#else 
+nbtags = mPin->NbNameTags();
+#endif
+
+if (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->NbNameTags(); 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_Nov2007/SophyaPI/PIext/pisiadw.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pisiadw.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pisiadw.h	(revision 3445)
@@ -0,0 +1,78 @@
+// 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  Hide();
+  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); }
+  inline  void  SelObjByOid(int oid) 
+                    { objlist->SelectItemMsg(oid); }
+  inline  int   GetCurDirId() { return (dirlist->GetValue()-30000); }
+
+  inline  void  SetCurDir(string & cd) { dirlist->SetValueStr(cd); }
+
+  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_Nov2007/SophyaPI/PIext/pistdimgapp.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pistdimgapp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pistdimgapp.cc	(revision 3445)
@@ -0,0 +1,2441 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.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);
+
+// Pour compter le nombre de display same a la suite
+static int nb_disp_same = 0;
+
+/* ........................................................... */
+/*    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) { 
+    // RZDEL: Normalement, il ne devrait plus y avoir besoin de cette
+    // methode avec le thread separe de l'interpreteur - Reza 27/12/2003 
+    //    _app->ExecuteExtCommand();
+    _app->UpdateStatResourceInfo();
+  }
+}
+
+/* ............................................................. */
+
+
+/* ........................................................... */
+/*                    Classe PIStdImgApp                         */
+/* ........................................................... */
+
+/* --Methode-- */
+PIStdImgApp::PIStdImgApp(bool fgsmall, int narg, char* arg[])
+  : PIApplication(420, (fgsmall)?320:220, narg, arg) , resusg(ResourceUsage::RU_All)
+{
+
+// 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;
+int sfgsz = mFgScSz;
+if (fgsmall) {  // Flag petite taille de fenetre 
+  if (mFgScSz > 1) mFgScSz = 1;
+  msx = 420+mFgScSz*40;
+  msy = 220+mFgScSz*20;
+}
+MainWin()->SetSize(msx, msy);
+
+//------------------------------------------------------
+// On cree un container intermediaire permettant de gerer 
+// le widget zoom, colormap, stats, ...
+
+int bss = 105+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, 5);
+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), 15, 2*bss+20, 30);
+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, 50);
+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), 15, 2*bss+20, 75);
+therm_cpu->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+therm_cpu->SetThreshold(0.75, 0.90);
+lab_thrcmd = new PILabel(statcont, "thrcmdlab", msx-2*(bss+20), 20, 2*bss+20, 95);
+lab_thrcmd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+lab_thrcmd->SetLabel("CommandThread");
+lab_thrcmd->SetForegroundColor(PI_Green);
+lab_thrcmd->SetBorderWidth(1);
+
+fg_exc_cmd = false;
+mCmd = NULL;  // Avant d'appeler UpdateStatResource() si PIACmd non cree
+mSopex = NULL; 
+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 = NORED_OE;
+RedirectStdOutErr(NORED_OE);  // pas de redirect par defaut 
+
+mFgScSz = sfgsz;
+ 
+mObjMgr = new NamedObjMgr(true);
+mCmd = new PIACmd(this);
+mSopex = new SOpExObj(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 = kAxesDflt;
+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());
+mCons->AddStr(buff, PIVA_Blue );
+#else
+string svers;
+SophyaInitiator::GetVersion(svers);
+mCons->AddStr(svers.c_str(), PIVA_Blue );
+#endif
+mCons->AddStr("  ..........................................\n", PIVA_Blue );
+// PrintPeidaVersion();
+
+pfc_fits->SetPath(ImgDir);
+pfc_ppf->SetPath(WorkDir);
+pfc_ps->SetPath(WorkDir);
+
+SetReady();
+fg_glsynlock = false;
+}
+
+/* --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 lab_thrcmd;
+
+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;
+
+}  
+
+/*
+class RunAlarm : public Periodic {
+public:
+  RunAlarm(PIStdImgApp* app) :
+    Periodic(1)
+  { _app = app; SetIntervalms(1); }
+  ~RunAlarm() { }
+  virtual void DoPeriodic()
+  { _app->getMutex().broadcast(); }
+  PIStdImgApp* _app;
+};
+*/
+
+class Reveil : public ZThread {
+public:
+  Reveil(PIStdImgApp* app) :
+    ZThread() 
+  { _app = app; _fgstop = false; _running = false; }
+  virtual ~Reveil() { }
+  inline void Stop() { _fgstop = true; }
+  inline bool IsRunning() { return _running; }
+  virtual void run() 
+  {
+    _running = true;
+    while (!_fgstop) {
+      usleep(2000);
+      _app->LockMutex();
+      bool fgb = false;
+      if (_app->CheckPendingEvents() != 0)  fgb = true;
+      _app->UnlockMutex(fgb);      
+    }
+    _running = false;
+  }
+
+  PIStdImgApp* _app;
+  bool _fgstop;
+  bool _running;
+};
+
+int PIStdImgApp::CheckPendingEvents()
+{
+  return XtAppPending(*_appctx);
+}
+
+void PIStdImgApp::CkEvt_LockMutex()
+{
+  for(int i=0; i<5; i++) {   // On tente 5 fois de vider le buffer d'evenements
+    LockMutex();
+    int nev = CheckPendingEvents();
+    bool fgbr = (nev > 0) ? true : false;
+    UnlockMutex(fgbr);
+    if (nev < 1) break;
+  }
+  LockMutex();
+}
+
+/* --Methode-- */
+void PIStdImgApp::Run()
+{
+XEvent evt;
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+_appctx = appctx;   // Pour CheckPendingEvents()
+// 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 
+
+// Creation et demarrage de l'objet de reveil periodique
+// de la boucle d'evts 
+/* RunAlarm * mru = new RunAlarm(this);
+   mru->Start(); */
+Reveil* mrv = new Reveil(this);
+mrv->start(); 
+// Demarrage du thread de l'interpreteur
+CmdInterpreter()->start();
+// Demarrage du thread de l'executeur de commandes simples 
+getSOpExObj()->start();
+
+
+thr_glsyn.lock(); //  <ZThread> 
+//DEL-DBG int klp = 0;
+while (mStop) {
+  fg_glsynlock = true;
+  int nevtproc = 0;
+  while (XtAppPending(*appctx) != 0) {   // Boucle XtAppPending() 
+    try {
+      XtAppNextEvent(*appctx, &evt);
+      XtDispatchEvent(&evt);
+      // Soumission de la commande exterieur a executer 
+      if (fg_exc_cmd) {
+	fg_exc_cmd = false; 
+	CmdInterpreter()->AddInputLine(exc_command);
+      }
+      nevtproc++;
+      if (nevtproc >= 300)  break;
+    }
+    catch ( PThrowable & exc ) {
+      cerr << "\nPIStdImgApp::Run()/ Exception catched in event loop: \n   " 
+	   << (string)typeid(exc).name() << " Msg= " << exc.Msg() << endl;
+      cerr << "  Trying to continue event loop ... " << endl;
+    }
+    catch ( std::exception & sexc ) {
+      cerr << "\nPIStdImgApp::Run()/ Exception catched in event loop: \n   " 
+	   << (string)typeid(sexc).name() << " what()= " << sexc.what() << endl;
+      cerr << "  Trying to continue event loop ... " << endl;
+    }
+    catch ( ... ) {
+      cerr << "\nPIStdImgApp::Run()/ Unknown Exception (...) catched in event loop ! " << endl;
+      cerr << "  Trying to continue event loop ... " << endl;
+    } 
+  }   // FIN Boucle XtAppPending() 
+  fg_glsynlock = false;
+  //DBG cout << " "DBG-Run:: Going to wait ... " << klp << endl;
+  thr_glsyn.wait();  //  <ZThread> 
+  //DBG cout << "DBG-Run:: Out of wait " << ++klp << endl;  
+    //  usleep(1000);
+}
+
+thr_glsyn.unlock();  //  <ZThread> 
+mrv->Stop();
+// Reza- Dec07 : On attend que le tread Reveil soit arrete avant de le supprimer
+while (mrv->IsRunning())  usleep(2000);
+delete mrv;
+// delete mru;
+return;
+}
+
+/* --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; }
+
+#ifdef SANS_EVOLPLANCK
+  TRY {
+#else
+  try {
+#endif
+
+//   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) && (smm == PIMsg_Cancel) )  // <Cntrl C> appuye sur Console
+  CmdInterpreter()->StopExecution();
+else if ( (msg == 30200 ) && (smm == PIMsg_OK) ){    // Objet PIConsole avec <Return>/<Enter>
+  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);
+    CmdInterpreter()->AddInputLine(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);
+
+#ifdef SANS_EVOLPLANCK
+}  CATCH(merr) { 
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  string es = PeidaExc(merr);
+  cerr << "PIStdImgApp::Process()/  Exception :" << es << " (" << merr << ")" << endl ;
+  SetReady();
+  }
+#else
+  }
+  catch ( PThrowable & exc ) {
+    cerr << "\n PIStdImgApp::Process() SOPHYA Exception :" 
+	 << (string)typeid(exc).name() << "\n Msg= " 
+	 << exc.Msg() << endl;
+    SetReady();
+  }
+  catch ( std::exception & sex ) {
+    cerr << "\n PIStdImgApp::Process() std::exception :" 
+	 << (string)typeid(sex).name() << "\n msg= " 
+	 << sex.what() << endl;
+    SetReady();
+  }
+  catch ( ... ) {
+    cerr << "\n PIStdImgApp::Process()/  Catched unknown (...) Exception " << endl;
+    SetReady();
+  }
+
+#endif
+
+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);  RZDEL
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetBlocked()
+{
+mCons->SetUnSensitive();
+gimv->SetUnSensitive();
+PIApplication::SetBlocked();
+// Attention : Appel XSync specifique X11 -  en attendant multi-thread
+// XSync(PIXDisplay(), False);  RZDEL
+}
+
+class SyncPIS {
+public:
+  explicit SyncPIS(ZMutex & mtx, bool fglock=true, int sigbr=0) 
+  {
+  _mtx = &mtx; _sigbr = sigbr; 
+  _fglock = fglock; 
+  if (_fglock)  mtx.lock(); 
+  }
+  ~SyncPIS() 
+  { 
+    if (_fglock && (_mtx != NULL) ) { 
+      if (_sigbr == 1) _mtx->signal(); 
+      else  if (_sigbr == 2) _mtx->broadcast(); 
+      _mtx->unlock(); 
+    }
+  }
+
+private:
+  ZMutex * _mtx;
+  int _sigbr;
+  bool _fglock;
+  inline	SyncPIS() {_mtx = NULL; _sigbr = 0; _fglock = false; }
+};
+
+
+/* --Methode-- */
+int PIStdImgApp::DispImage(P2DArrayAdapter* nouv, string const & name, string const& sop, 
+			   bool fgimagnav, int oid, bool fglock)
+{
+PIImage* pii=NULL;
+PIImageNavigator* piin=NULL; 
+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);
+  }
+
+// <ZThread> global PIApplication event loop synchronisation
+SyncPIS zs(getMutex(), fglock, 2);
+
+// On decode les options graphiques
+vector<string> opts;
+string wname = name; 
+DispWinEnum dwopt = ParseDisplayOption(sop, opts, wname);
+
+// 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 *)wname.c_str());
+if (fgimagnav) {  // Creation de naviguateur d'image 
+  piin = new PIImageNavigator(win, (char *)wname.c_str(), sx, sy, px,py);
+  piin->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+  piin->Show();
+  piin->ImageWdg()->ShowCursor(true);
+  pii = piin->ImageWdg();
+  piin->SetUserData(NULL, oid);
+  pii->SetUserData(NULL, oid);
+}
+else { // Creation de widget PIImage normal
+  pii = new PIImage(win, (char *)wname.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);
+}
+
+
+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
+
+// 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);
+}
+
+// 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++;
+if (fgimagnav)  mBWList[mBWId] = piin;
+else mBWList[mBWId] = pii;
+// pii->Refresh();
+  pii->Apply(true);
+  //  cmapv->Refresh();  Pas besoin ? , Reza Fev 2005 
+return(mBWId); 
+}
+
+
+/* --Methode-- */
+int PIStdImgApp::DispScDrawer(PIDrawer* scd, string const & name, string const& sop, 
+			      string title, int oid, bool fglock)
+{
+if (scd == NULL)
+  {
+  printf("PIStdImgApp::DispScDrawer_Error  Cannot Add NULL ScDrawer \n");
+  return(-1);
+  }
+
+// <ZThread> global PIApplication event loop synchronisation
+SyncPIS zs(getMutex(), fglock, 2);
+
+// On decode les options graphiques
+vector<string> opts;
+string wname = name;
+DispWinEnum dwopt = ParseDisplayOption(sop, opts, wname);
+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);
+  if (nb_disp_same > 0) {
+    vector<string> ostatpos;
+    int spo = nb_disp_same%4;
+    if (spo == 1) ostatpos.push_back("statposoff=-0.01,-0.26");
+    else if (spo == 2)  ostatpos.push_back("statposoff=-0.36,-0.01");
+    else  ostatpos.push_back("statposoff=-0.36,-0.26");
+    scd->DecodeOptionString(ostatpos, true);
+  }
+  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 *)wname.c_str());
+
+scw = new PIScDrawWdg(win, (char *)wname.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 = wname;  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, bool fglock)
+{
+if (dr3 == NULL)
+  {
+  printf("PIStdImgApp::Disp3DDrawer_Error  Cannot Add NULL 3DDrawer \n");
+  return(-1);
+  }
+
+// <ZThread> global PIApplication event loop synchronisation
+SyncPIS zs(getMutex(), fglock, 2);
+
+// On decode les options graphiques
+vector<string> opts;
+string wname = name;
+DispWinEnum dwopt = ParseDisplayOption(sop, opts, wname);
+
+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);
+  if (nb_disp_same > 1) {
+    vector<string> ostatpos;
+    int spo = nb_disp_same%4;
+    if (spo == 1) ostatpos.push_back("statposoff=-0.01,-0.26");
+    else if (spo == 2)  ostatpos.push_back("statposoff=-0.36,-0.01");
+    else  ostatpos.push_back("statposoff=-0.36,-0.26");
+    dr3->DecodeOptionString(ostatpos, true);
+  }
+
+  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 *)wname.c_str());
+PIDraw3DWdg* wd3 = new PIDraw3DWdg(win, (char *)wname.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 = wname;  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); 
+}
+
+// RZDEL: Normalement, il ne devrait plus y avoir besoin de cette
+// methode avec le thread separe de l'interpreteur - Reza 27/12/2003 
+/* --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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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::AddOval(double xp, double yp, double dx, double dy, 
+			  string const& sop, bool fgfill, bool fgcn)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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->ElAddFOval(xp, yp, dx, dy, gratt, fgcn);
+else elmgr->ElAddOval(xp, yp, dx, dy, 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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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)
+{
+// <ZThread> global PIApplication event loop synchronisation
+ZSync zs(thr_glsyn, 2);  zs.NOp(); 
+
+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) DeleteWidget(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; 
+    DeleteWidget(cwd, false, false);
+    }
+  mGrW->SetZone(nzx, nzy);
+  }
+}
+
+/* --Methode-- */
+void PIStdImgApp::StackWinNext()
+{
+if (mStW)  mStW->DispNext();
+}
+
+/* --Methode-- */
+void PIStdImgApp::SelectLastWidget(string & nom)
+{
+
+  if ( (mLastWdg != NULL) && (mLastWdg->Nom() == nom) ) return;
+  if ( (mCurWdg != NULL) && (mCurWdg->Nom() == nom) ) {
+    mLastWdg = mCurWdg;
+    return;
+  }
+
+  PIWdg* bw = NULL;
+  long wsid = -1;
+  BWMList::iterator it;
+  for(it = mBWList.begin(); it != mBWList.end(); it++) {
+    if ( ((*it).second->Nom() == nom) && ((*it).first > wsid)) { 
+      bw = (*it).second; wsid = (*it).first; 
+    } 
+  }
+  if (bw != NULL) {
+    if (bw->kind() == PIImageNavigator::ClassId) 
+      mLastWdg = dynamic_cast<PIImageNavigator *>(bw)->ImageWdg();
+    else mLastWdg = dynamic_cast<PIBaseWdg *>(bw);
+  }
+  return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::SelectLastWidgetByObjName(string & nom)
+{
+  int oid = ObjMgr()->NameToOId(nom);
+  if (oid < 0) return;
+
+  if ( (mLastWdg != NULL) && (mLastWdg->UserFlag() == oid) ) return;
+  if ( (mCurWdg != NULL) && (mCurWdg->UserFlag() == oid) ) {
+    mLastWdg = mCurWdg;
+    return;
+  }
+
+  PIWdg* bw = NULL;
+  long wsid = -1;
+  BWMList::iterator it;
+  for(it = mBWList.begin(); it != mBWList.end(); it++) {
+    if ( ((*it).second->UserFlag() == oid) && ((*it).first > wsid)) { 
+      bw = (*it).second; wsid = (*it).first; 
+    } 
+  }
+  if (bw != NULL) {
+    if (bw->kind() == PIImageNavigator::ClassId) 
+      mLastWdg = dynamic_cast<PIImageNavigator *>(bw)->ImageWdg();
+    else mLastWdg = dynamic_cast<PIBaseWdg *>(bw);
+  }
+  return;
+}
+
+/* --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; 
+  DeleteWidget(cwd,false,false);
+  }
+delete w;
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::DeleteWidget(PIWdg* 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; }
+PIBaseWdg* bw = NULL;
+if (w->kind() == PIImageNavigator::ClassId) {
+  PIImageNavigator* piin = dynamic_cast<PIImageNavigator *>(w);
+  if (piin) bw = piin->ImageWdg();
+}				 
+else bw = dynamic_cast<PIBaseWdg *>(w);
+if (bw != NULL) {
+  PIDrawer* drw;
+  int k;
+  for(k=0; k<bw->NbDrawers(); k++) {
+    if ((drw = bw->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) || (bw == mCurWdg) ) {  
+  mCurWdg = NULL;
+  if (mFgCWImg) {
+    m[4]->SetSensitivityMsg(10515, false);
+    m[4]->SetSensitivityMsg(10516, false);
+    mFgCWImg = false;
+    }
+  }
+
+if ( (w == mLastWdg) || (bw == mLastWdg) ) mLastWdg = NULL;
+
+PIWdg* pw=NULL;
+pw = (PIWdg*)(w->Parent());
+//DBG printf("DeleteWidget(%lx)-DBG kind = %d - %d %d \n", (long)w, w->kind(), (int)dw, (int)dwin); 
+if (dw)  delete w;
+
+if (dwin && pw) { 
+  PIWindow* pww = dynamic_cast<PIWindow *>(pw);
+  if (pww && (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;
+  PIWdg* wd = (*it).second;
+//DBG cerr << "-DBG- PIStdImgApp::DelWRsId Deleting BaseWidget " << (long)(wd) << endl ; 
+  DeleteWidget(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);
+  //DBG 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->Hide();
+    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); 
+    consolecont->Show();
+    statcont->Show();
+    m[3]->SetStateMsg(10470, true);
+  }
+  else {
+    statcont->Hide();
+    consolecont->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); 
+    consolecont->Show();    
+    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());
+  int nlx = 0;
+  bool fgx = false;
+  if ( CmdInterpreter() ) fgx = CmdInterpreter()->isRunning(nlx);
+  if (!fgx) {
+    lab = "PIACmdThread Idle";
+    lab_thrcmd->SetLabel(lab);
+    lab_thrcmd->SetForegroundColor(PI_Green);
+  }
+  else {
+    sprintf(buff, "PIACmdThread Running - NL=%d" , nlx);
+    lab = buff;
+    lab_thrcmd->SetLabel(lab);
+    if (nlx < 3)     lab_thrcmd->SetForegroundColor(PI_Yellow);
+    else     lab_thrcmd->SetForegroundColor(PI_Red);   
+  }
+}
+
+/* --Methode-- */
+void PIStdImgApp::RedirectStdOutErr(RED_OUTERR_FLG redflg)
+{
+if (redflg == redirecout) return;
+string fnout = ObjMgr()->GetTmpDir() + "/sout.log";
+string fnerr = ObjMgr()->GetTmpDir() + "/serr.log";
+bool drfg = false;
+PIConsole* pcons = NULL;
+switch (redflg) {
+  case NORED_OE :
+    pcons = NULL;
+    break;
+  case CONSRED_OE :
+    pcons = mCons;
+    drfg = false;
+    break;
+  case DOUBLERED_OE:
+    pcons = mCons;
+    drfg = true;
+    break;
+}
+
+char piva =  PIVA_Def;
+RedirectOutStream(pcons, fnout, drfg, piva);
+// ancienne maniere redirect, avec pipe : RedirectOutStream(pcons, piva);
+piva = PIVA_Red;
+RedirectErrStream(pcons, fnerr, drfg, piva);
+// ancienne maniere redirect, avec pipe : RedirectErrStream(pcons, piva);
+ 
+//  m[5]->SetStateMsg(10602, false);
+redirecout = redflg;
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::CatchSignals(bool fgfpe, bool fgsegv)
+{    
+#ifdef SANS_EVOLPLANCK
+PeidaConfigureSignalhandling(fgfpe, fgsegv, true, true);  
+#else
+// On active aussi SIGUSR1 pour stopthr
+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, string& wname)
+{
+  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;
+    else if (token.substr(0,6)=="samew=") {
+      string snom=token.substr(6);
+      SelectLastWidget(snom);
+      rc = Disp_Same;
+    }
+    else if (token.substr(0,6)=="inset=") {
+      double fx1,fx2,fy1,fy2;
+      fx1=fy1=0.4; fx2=fy2=0.6;
+      sscanf(token.substr(6).c_str(),"%lg,%lg,%lg,%lg",&fx1,&fx2,&fy1,&fy2);
+      SetInsetLimits(fx1, fx2, fy1, fy2);
+      rc = Disp_Inset;
+    }
+    else if (token.substr(0,6)=="wname=") {   // specification de nom de widget
+      wname=token.substr(6);
+    }
+    // Option a etre decode par les drawers, etc ...
+    else  opts.push_back(token); 
+  }
+
+  //DBG  cerr << " DBG-Parse-B opts.size()=" << opts.size() << endl;
+  if (rc == Disp_Same) nb_disp_same++;
+  else nb_disp_same = 0;
+  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 :
+      CmdInterpreter()->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 cmd = "readfits ";
+	cmd += pfc_fits->GetFileName();
+	try {
+	  CmdInterpreter()->AddInputLine(cmd);
+	  // CmdInterpreter()->ExecuteCommand(kw, args, toks);
+	}  
+	catch ( PThrowable & exc ) {
+	  cerr << "\n PIStdImgApp::Process()/ Cmd->ExecuteCommand(readfits) Exception :" 
+	       << (string)typeid(exc).name() << " Msg= " 
+	       << exc.Msg() << endl;
+	  cout << endl; 
+	}
+	catch ( ... ) {
+	  cerr << "\n PIStdImgApp::Process()/ Cmd->ExecuteCommand(readfits) Catched Exception ... " << endl;
+	  cout << endl; 
+	}
+      }
+      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 {
+	  CmdInterpreter()->AddInputLine(cmd);
+	  //	  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) {
+      string ssob = "DEL ";
+      ssob += mCurWdg->Nom();
+      getSOpExObj()->AddOpe(ssob);    
+      }
+    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 :
+    CmdInterpreter()->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) DeleteWidget(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:
+    CmdInterpreter()->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", true, false, 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);
+
+string info = "piapp : Interactive analysis program\n";
+char buff[128];
+#ifdef SANS_EVOLPLANCK
+sprintf(buff, "Version: piapp=%g  PI=%g  PEIDA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, (float)PeidaVersion());
+info += buff;
+#else
+string svers;
+SophyaInitiator::GetVersion(svers);
+info += svers;
+sprintf(buff, "\n Version: PI=%g  --  PIext/piapp= %g \n", (double)PI_VERSIONNUMBER, 
+	(double)PIAPP_VERSIONNUMBER);
+info += buff; 
+#endif
+info += "(C) LAL-IN2P3/CNRS  1996-2006\n";
+info += "(C) SPP-DAPNIA/CEA 1996-2006\n";
+#ifndef SANS_EVOLPLANCK
+ info += "Check http://www.sophya.org for more information";
+#endif
+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_Nov2007/SophyaPI/PIext/pistdimgapp.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pistdimgapp.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pistdimgapp.h	(revision 3445)
@@ -0,0 +1,264 @@
+// 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 "zthread.h"
+#include "resusage.h"
+
+
+enum DispWinEnum {Disp_Default, Disp_Next, Disp_Win, Disp_Same, Disp_Stack, Disp_Inset};
+// Flag de redirection stdout/stderr  
+enum RED_OUTERR_FLG { NORED_OE, CONSRED_OE, DOUBLERED_OE };  
+
+
+typedef map<long, PIWindow*, less<long> > WindMList;
+typedef map<long, PIWdg*, less<long> > BWMList;
+typedef map<long, PIDrawer*, less<long> > DrwMList;
+
+class PIStdImgApp : public PIApplication  {
+public:
+     PIStdImgApp(bool fgsmall=false, 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();
+
+  // <ZThread>  Multithread execution 
+  // On redefinit la methode Run pour gestion multithread
+     virtual void   Run();
+     inline ZMutex &   getMutex() { return thr_glsyn; }
+     inline void       LockMutex() { thr_glsyn.lock(); }
+     inline void       UnlockMutex(bool fgbr=false) 
+        { if (fgbr) thr_glsyn.broadcast(); thr_glsyn.unlock(); }
+     inline bool       isGlSyncLocked() { return fg_glsynlock; }
+     int               CheckPendingEvents();
+     void              CkEvt_LockMutex(); // On fait le lock apres verification de traitement des evenements
+
+  // Methodes d'Affichage generique
+     int  DispImage(P2DArrayAdapter* nouv, string const & name, string const & opt, 
+		    bool fgimagnav=false, int oid=0, bool fglock=true);
+     int  DispScDrawer(PIDrawer* scd, string const & name, string const & opt, 
+		       string title="", int oid=0, bool fglock=true);
+     int  Disp3DDrawer(PIDrawer3D* scd, string const & name, string const & opt, 
+		       string title="", int oid=0, bool fglock=true);
+
+  //  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 AddOval(double xp, double yp, double dx, double dy, 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();
+
+  // Pour specifier le widget pour le trace en superpose, en specifiant un nom de widget
+     void SelectLastWidget(string & nom);
+  // Pour specifier le widget pour le trace en superpose, en specifiant un nom d'objet
+     void SelectLastWidgetByObjName(string & nom);
+     
+     void DeleteWindow(PIWindow* w);
+     void DeleteWidget(PIWdg* 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; }
+     inline SOpExObj* getSOpExObj() { return mSopex; }
+
+     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(RED_OUTERR_FLG redflg=CONSRED_OE);
+     inline RED_OUTERR_FLG 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, string& wname);
+     inline DispWinEnum ParseDisplayOption(string const & opt, vector<string>& opts)
+       {
+	 string wname;
+	 return ParseDisplayOption(opt, opts, wname);
+       }
+
+// 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;
+    SOpExObj* mSopex;
+
+    PIMenu* m[7];
+    PIMenu* mc;
+
+    PIContainer* statcont;    // Container pour les widgets zoom, gimv, cmapv ...
+    PIPixmap* zoom;
+    PIPixmap* gimv;
+    PICMapView* cmapv;
+  // Pour afficher des stats et etat thread command
+    PILabel* lab_mem;
+    PIThermometer* therm_mem;
+    PILabel* lab_cpu;
+    PIThermometer* therm_cpu;
+    PILabel* lab_thrcmd;
+
+    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;
+    RED_OUTERR_FLG redirecout;    // flag de redirection vers  mCons, ou NORED ou vers mCons+terminal;
+
+    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;
+  // Attributs pour controle de thread
+    ZMutex thr_glsyn;
+    bool fg_glsynlock;  // true: thr_glsyn locke pour traitement evts
+    XtAppContext * _appctx; // Pour CheckPendingEvents()  $CHECK$ A supprimer si possible ...
+};
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/pistlist.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pistlist.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pistlist.cc	(revision 3445)
@@ -0,0 +1,182 @@
+// Classe traceur de StarList               97-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#include <stdio.h>
+#include "sopnamsp.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_Nov2007/SophyaPI/PIext/pistlist.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pistlist.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pistlist.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIext/pitvmaad.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pitvmaad.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pitvmaad.cc	(revision 3445)
@@ -0,0 +1,130 @@
+//  Adaptateurs pour TMatrix TVector du package Sophya
+//                             R. Ansari  1/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "sopnamsp.h"
+#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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+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< uint_2 >
+#pragma define_template POTVectorAdapter< int_2 >
+#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< uint_2 >
+#pragma define_template POTMatrixAdapter< int_2 >
+#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< uint_2 >;
+template class POTVectorAdapter< int_2 >;
+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< uint_2 >;
+template class POTMatrixAdapter< int_2 >;
+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_Nov2007/SophyaPI/PIext/pitvmaad.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/pitvmaad.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/pitvmaad.h	(revision 3445)
@@ -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_Nov2007/SophyaPI/PIext/servnobjm.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/servnobjm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/servnobjm.cc	(revision 3445)
@@ -0,0 +1,1552 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <typeinfo>
+#include <iostream>
+#include <string>
+#include <list>
+#include <map>
+
+#include "sopnamsp.h"
+#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 "matharr.h"
+#include "pitvmaad.h"
+#endif
+
+#include "ntuple.h"
+#include "cimage.h"
+
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "datatable.h"
+
+#include "piyfxdrw.h"
+#include "pisurfdr.h"
+
+#include "pintuple.h"
+#include "pintup3d.h"
+
+#include "pipodrw.h"
+
+
+
+/* --Methode-- */
+Services2NObjMgr::Services2NObjMgr(string& tmpdir)
+{
+SetTmpDir(tmpdir);
+mImgapp = NULL;
+mOmg = NULL;
+dynlink = NULL;
+}
+  
+/* --Methode-- */
+Services2NObjMgr::~Services2NObjMgr()
+{
+CloseDLL();
+if (mOmg) delete mOmg;
+}
+
+/* --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; 
+
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+
+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; 
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+
+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)
+{
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+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)
+{
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+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;
+
+  MyObjMgr()->AddObj(vpy, nom);
+  if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+  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);
+  MyObjMgr()->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 < 2) npx = 2;
+if (npy < 2) npy = 2;
+//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;
+
+  MyObjMgr()->AddObj(mtx, nom);
+  if ( (dopt == "nodisp") || (dopt == "nodisplay") ) return;
+
+  int rsid = 0;
+  P2DArrayAdapter* arr = new POMatrixAdapter(mtx, false);
+  arr->DefineXYCoordinates(xmin, ymin, dx, dy);
+  if ( (npx <= 200) && (npy <= 200) ) {
+    PISurfaceDrawer* sdr = new PISurfaceDrawer(arr, true, true, true);
+    rsid = mImgapp->Disp3DDrawer(sdr, titre, dopt);
+  }
+  else  rsid = mImgapp->DispImage(arr, titre, dopt);
+  MyObjMgr()->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 = MyObjMgr()->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(MyObjMgr()->HasVar(resultvarname)) MyObjMgr()->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);
+   }
+   MyObjMgr()->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 = MyObjMgr()->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 = MyObjMgr()->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;
+  }
+//DBG nt->Show();
+//DBG 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, bool fgcolidx, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = MyObjMgr()->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]);
+if (fgcolidx) pin->SelectColorByIndex(ntn[2]);  // Use the weight expression as a color index 
+else pin->SelectWt(ntn[2]);
+
+string titre =  nom + ":" + expwt + "_" + expy + "%" + expx ;
+mImgapp->DispScDrawer( (PIDrawer*)pin, titre, dopt);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::DisplayPoints3DW(string& nom,  string& expx, string& expy, string& expz, 
+                                        string& expwt, string& expcut, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = MyObjMgr()->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::DisplayPoints3D() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+char* ntn[4] = {"expx","expy","expz","expw"};
+NTuple* nt = new NTuple(4,ntn);  // Creation NTuple
+
+ComputeExpressions(obja, expx, expy, expz, expwt, expcut, loop, nt, NULL, NULL);
+
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::DisplayPoints3DW() Warning  Zero points satisfy cut !" << endl;
+  delete nt;
+  return;
+  }
+//DBG nt->Show();
+//DBG nt->Print(0,10);
+PINTuple3D* pin = new PINTuple3D(nt, true);
+pin->SelectXYZ(ntn[0], ntn[1], ntn[2]);
+pin->SelectWt(ntn[3]);
+pin->UseColorScale(true);
+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 + " W=" + expwt;
+mImgapp->Disp3DDrawer(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 = MyObjMgr()->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; 
+bool h1_already_exist = false;
+if (nomh1.length() > 0) oh=MyObjMgr()->GetObj(nomh1);
+else nomh1 = "/tmp/projh1d";
+if ( (oh != NULL) && (typeid(*oh) == typeid(Histo)) )  {
+  h1 = (Histo*)oh;
+  h1_already_exist = true;
+  // 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;
+  MyObjMgr()->AddObj(h1, nomh1);
+}
+
+if(!h1_already_exist || dopt.size()>0) MyObjMgr()->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 = MyObjMgr()->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;
+bool h2_already_exist = false;
+if (nomh2.length() > 0)  oh=MyObjMgr()->GetObj(nomh2);
+else nomh2 = "/tmp/projh2d";
+if ( (oh != NULL) && (typeid(*oh) == typeid(Histo2D)) ) {
+  h2 = (Histo2D*)oh;
+  h2_already_exist = true;
+  // 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;
+  MyObjMgr()->AddObj(h2, nomh2);
+}
+
+if(!h2_already_exist || dopt.size()>0) MyObjMgr()->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 = MyObjMgr()->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;
+bool hp_already_exist = false;
+if (nomprof.length() > 0)  oh=MyObjMgr()->GetObj(nomprof);
+else nomprof = "/tmp/projprof";
+if( (oh!=NULL) && (typeid(*oh) == typeid(HProf)) ) {
+  hprof = (HProf*)oh;
+  hp_already_exist = true;
+} 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;
+  MyObjMgr()->AddObj(hprof, nomprof);
+}
+hprof->UpdateHisto();
+
+if(!hp_already_exist || dopt.size()>0) MyObjMgr()->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 = MyObjMgr()->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=MyObjMgr()->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;
+  
+
+MyObjMgr()->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 = MyObjMgr()->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=MyObjMgr()->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;
+  
+
+MyObjMgr()->DisplayObj(nommtx, dopt);
+return;  
+
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ExpressionToVector(string& nom, string& expx, string& expcut, 
+                                          string& nomvec, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = MyObjMgr()->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;
+if (nomvec.size() > 0) {
+  MyObjMgr()->AddObj(vec, nomvec); 
+  MyObjMgr()->DisplayObj(nomvec, dopt);
+}
+else {
+// On calcule et on affiche mean/sigma + min/max 
+  double min, max, mean, sigma;
+  vec->MinMax(min, max);
+  MathArray<r_8> ma;
+  ma.MeanSigma(*vec, mean, sigma);
+  cout << "Size= " << vec->Size() << " Mean= " << mean << "  Sigma= " << sigma 
+       << "  Min= " << min << " Max= " << max << endl;
+  delete vec;
+}
+return;  
+}
+
+/* --Methode-- */
+void Services2NObjMgr::NtFromASCIIFile(string& nom,string& filename,double def_val)
+//	Pour remplir un NTuple/DataTable "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 numeriques sont mises a "def_val" par defaut.
+{
+AnyDataObj* mobj = MyObjMgr()->GetObj(nom);
+if(mobj == NULL) {
+  cout<<"NtFromASCIIFile() Error, object "<<nom<<" not existing"<<endl;
+  return;
+}
+
+NTuple* nt = NULL;
+DataTable* dt = NULL;
+if(typeid(*mobj) == typeid(NTuple))         nt = (NTuple*) mobj;
+else if(typeid(*mobj) == typeid(DataTable)) dt = (DataTable*) mobj;
+
+if(nt==NULL && dt==NULL) {
+  cout<<"NtFromASCIIFile() Error, object "<<nom<<" not an NTuple nor a DataTable"<<endl;
+  return;
+}
+if (!mImgapp)  return; 
+
+if(nt)      nt->FillFromASCIIFile(filename, def_val);
+else if(dt) {
+  ifstream is(filename.c_str());
+  dt->FillFromASCIIFile(is);
+}
+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 = MyObjMgr()->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=MyObjMgr()->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) MyObjMgr()->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 = MyObjMgr()->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;
+  }
+
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+
+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=MyObjMgr()->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];
+
+int i,k;
+for(i=0; i<10; i++) xnt[i] = 0.;
+
+int_8 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_8)objnt->NbLines()) k2 = objnt->NbLines();
+if (dk <= 0) dk = 1;
+
+try  {
+  double* xn;
+  int_8 kstart = k1, kend = k2;
+  for(k=kstart; k<kend; k+=dk)    {
+    xn = objnt->GetLineD(k);
+    if (f((int_8_exprf)k, xn, xnt, xnt+1, xnt+2, xnt+3, (int_8_exprf)kstart,(int_8_exprf) kend) != 0) {
+      if (nt)  nt->Fill(xnt);
+      }
+    }
+ }
+#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();
+
+if (fgnnt) MyObjMgr()->AddObj(nt, nomnt);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PrepareNTExpressionCFile(string & nom, string const & fname, 
+                                                string const & funcname)
+{
+NObjMgrAdapter* obja=NULL;
+obja = MyObjMgr()->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_exprf;\n", fip);
+fputs("int_8_exprf BitCmp64(double v,int_8_exprf flg)\n", fip);
+fputs("{return ((int_8_exprf)((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("/* Angle conversions   */\n", fip);
+fputs("double deg2rad(double x) { return (x*M_PI/180.); } \n", fip);
+fputs("double rad2deg(double x) { return (x*180./M_PI); } \n", fip);
+fputs("/* Theta(0..Pi, phi(0..2Pi) conversion to Molleweide X,Y   */\n", fip);
+fputs("double tetphi2mollX(double teta, double phi) { \n", fip);
+fputs(" if (phi<=M_PI) return(180.-sin(acos(2*teta/M_PI-1.))*((M_PI-phi)*180./M_PI)); \n", fip);
+fputs(" else return(180.+sin(acos(2.*teta/M_PI-1.))*((phi-M_PI)*180./M_PI)); } \n", fip);
+fputs("double tetphi2mollY(double teta) { \n", fip);
+fputs(" return (90.-(teta*180./M_PI)); } \n\n", fip);
+fputs("/* Longitude(0..360), Latitude(-90..90) conversion to Molleweide X,Y   */\n", fip);
+fputs("double longlat2mollX(double lng, double lat) { \n", fip);
+fputs(" if (lng<=180.) return(180.-sin(acos(lat/90.))*(180.-lng)); \n", fip);
+fputs(" else return(180.+sin(acos(lat/90.))*(lng-180.)); } \n", fip);
+fputs("double longlat2mollY(double lat) { return lat; } \n\n\n", fip);
+
+fputs("/* NTupleInterface Variable declaration - Generated by piapp    */\n", fip);
+fputs("/*    -- Services2NObjMgr::PrepareNTExpressionCFile()  --       */ \n", fip);
+fputs("/* _nl line number or sequential index : _nstart <= _nl < _nend */ \n\n", fip);
+fprintf(fip,"int %s(int_8_exprf _nl, double* _xnti_, double* _rx_, double* _ry_, double* _rz_, \n", 
+        funcname.c_str());
+fprintf(fip,"       double* _rt_, int_8_exprf _nstart, int_8_exprf _nend) \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 = MyObjMgr()->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;
+MyObjMgr()->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);
+MyObjMgr()->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_");
+
+// Pour synchronisation d'execution simultanee
+ZSync zs(mutx_dynlink);  zs.NOp(); 
+
+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];
+
+int_8 k;
+for(k=0; k<10; k++) xnt[k] = 0.;
+int_8 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_8)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((int_8_exprf)k,xn, xnt, xnt+1, xnt+2, xnt+3) != 0) {
+      if (nt) nt->Fill(xnt);
+      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_exprf;\n", fip);
+fputs("int_8_exprf BitCmp64(double v,int_8_exprf flg)\n", fip);
+fputs("{return ((int_8_exprf)((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("/* Angle conversions   */\n", fip);
+fputs("double deg2rad(double x) { return (x*M_PI/180.); } \n", fip);
+fputs("double rad2deg(double x) { return (x*180./M_PI); } \n", fip);
+fputs("/* Theta(0..Pi, phi(0..2Pi) conversion to Molleweide X,Y   */\n", fip);
+fputs("double tetphi2mollX(double teta, double phi) { \n", fip);
+fputs(" if (phi<=M_PI) return(180.-sin(acos(2*teta/M_PI-1.))*((M_PI-phi)*180./M_PI)); \n", fip);
+fputs(" else return(180.+sin(acos(2.*teta/M_PI-1.))*((phi-M_PI)*180./M_PI)); } \n", fip);
+fputs("double tetphi2mollY(double teta) { \n", fip);
+fputs(" return (90.-(teta*180./M_PI)); } \n\n", fip);
+fputs("/* Longitude(0..360), Latitude(-90..90) conversion to Molleweide X,Y   */\n", fip);
+fputs("double longlat2mollX(double lng, double lat) { \n", fip);
+fputs(" if (lng<=180.) return(180.-sin(acos(lat/90.))*(180.-lng)); \n", fip);
+fputs(" else return(180.+sin(acos(lat/90.))*(lng-180.)); } \n", fip);
+fputs("double longlat2mollY(double lat) { return lat; } \n\n\n", fip);
+
+fputs("int expf_pia_dl_func(int_8_exprf _nl, 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_8& i1, int_8& i2, int_8& 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 = atol(loop.c_str()); return; }
+i1 = atol(loop.substr(0, p).c_str());
+string aa = loop.substr(p+1);
+p = aa.find(':');
+if (p < aa.length() ) { 
+  i2 = atol(aa.substr(0,p).c_str());
+  di = atol(aa.substr(p+1).c_str());
+  }
+else i2 = atol(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_HistoErr : 
+    return("HistoErr");
+  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_Nov2007/SophyaPI/PIext/servnobjm.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/servnobjm.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/servnobjm.h	(revision 3445)
@@ -0,0 +1,153 @@
+// 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 "nobjmgr.h"
+#include "pdlmgr.h"
+#include "dlftypes.h"
+#include "anydataobj.h"
+
+#include "zthread.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 PIStdImgApp;
+class NObjMgrAdapter;
+
+class Services2NObjMgr {
+public:
+         	Services2NObjMgr(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);
+  inline NamedObjMgr*   MyObjMgr() 
+  { 
+    if (mOmg == NULL) mOmg = new NamedObjMgr; 
+    return mOmg; 
+  }
+// 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, 
+					 bool fgcolidx=false, string dopt="", string loop="");
+  virtual void          DisplayPoints3DW(string & nom, string& expx, string& expy, string& expz, 
+					 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_8& i1, int_8& i2, int_8& 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
+  // Mutex de controle de thread pour dynamic-link 
+  ZMutex mutx_dynlink;
+
+  PIStdImgApp* mImgapp;
+  NamedObjMgr* mOmg;
+
+  
+};
+
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/shlibs.name
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/shlibs.name	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/shlibs.name	(revision 3445)
@@ -0,0 +1,1 @@
+libPI.so
Index: /tags/V_Nov2007/SophyaPI/PIext/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/smakefile	(revision 3445)
@@ -0,0 +1,2824 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+all: $(SOPHYALIBP)libPIext.a
+ 
+clean:
+	 rm -f $(SOPHYAOBJP)basexecut.o $(SOPHYAOBJP)contmodex.o $(SOPHYAOBJP)cxxexecutor.o $(SOPHYAOBJP)cxxexecwin.o $(SOPHYAOBJP)flowmodex.o $(SOPHYAOBJP)graphexecut.o $(SOPHYAOBJP)nobjmgr.o $(SOPHYAOBJP)nomdvladapter.o $(SOPHYAOBJP)nomgadapter.o $(SOPHYAOBJP)nomgfdadapter.o $(SOPHYAOBJP)nomherradapter.o $(SOPHYAOBJP)nomhistadapter.o $(SOPHYAOBJP)nomimagadapter.o $(SOPHYAOBJP)nommatvecadapter.o $(SOPHYAOBJP)nomskymapadapter.o $(SOPHYAOBJP)nomspecrespadapter.o $(SOPHYAOBJP)nomstladapter.o $(SOPHYAOBJP)nomtarradapter.o $(SOPHYAOBJP)nomtmatvecadapter.o $(SOPHYAOBJP)pawexecut.o $(SOPHYAOBJP)pi2dvec.o $(SOPHYAOBJP)piacmd.o $(SOPHYAOBJP)piafitting.o $(SOPHYAOBJP)pigfd1.o $(SOPHYAOBJP)pigfd2.o $(SOPHYAOBJP)pihisto.o $(SOPHYAOBJP)pihisto2d.o $(SOPHYAOBJP)piinit.o $(SOPHYAOBJP)pintup3d.o $(SOPHYAOBJP)pintuple.o $(SOPHYAOBJP)pipodrw.o $(SOPHYAOBJP)pisiadw.o $(SOPHYAOBJP)pistdimgapp.o $(SOPHYAOBJP)pistlist.o $(SOPHYAOBJP)pitvmaad.o $(SOPHYAOBJP)servnobjm.o $(SOPHYAOBJP)userfitfunex.o
+	rm -f $(SOPHYALIBP)libPIext.a
+ 
+$(SOPHYALIBP)libPIext.a : $(SOPHYAOBJP)basexecut.o $(SOPHYAOBJP)contmodex.o $(SOPHYAOBJP)cxxexecutor.o $(SOPHYAOBJP)cxxexecwin.o $(SOPHYAOBJP)flowmodex.o $(SOPHYAOBJP)graphexecut.o $(SOPHYAOBJP)nobjmgr.o $(SOPHYAOBJP)nomdvladapter.o $(SOPHYAOBJP)nomgadapter.o $(SOPHYAOBJP)nomgfdadapter.o $(SOPHYAOBJP)nomherradapter.o $(SOPHYAOBJP)nomhistadapter.o $(SOPHYAOBJP)nomimagadapter.o $(SOPHYAOBJP)nomskymapadapter.o $(SOPHYAOBJP)nomspecrespadapter.o $(SOPHYAOBJP)nomtarradapter.o $(SOPHYAOBJP)nomtmatvecadapter.o $(SOPHYAOBJP)pawexecut.o $(SOPHYAOBJP)pi2dvec.o $(SOPHYAOBJP)piacmd.o $(SOPHYAOBJP)piafitting.o $(SOPHYAOBJP)pigfd1.o $(SOPHYAOBJP)pigfd2.o $(SOPHYAOBJP)pihisto2d.o $(SOPHYAOBJP)pihisto.o $(SOPHYAOBJP)piinit.o $(SOPHYAOBJP)pintup3d.o $(SOPHYAOBJP)pintuple.o $(SOPHYAOBJP)pipodrw.o $(SOPHYAOBJP)pisiadw.o $(SOPHYAOBJP)pistdimgapp.o $(SOPHYAOBJP)pitvmaad.o $(SOPHYAOBJP)servnobjm.o
+	$(AR) $(ARFLAGS) $@ $? 
+	touch $(SOPHYAINCP)/SophyaConfInfo/libPI.objlist
+ 
+$(SOPHYAOBJP)basexecut.o: basexecut.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmd.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h basexecut.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)strutilxx.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  nomgadapter.h $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  basexecut.cc
+ 
+$(SOPHYAOBJP)contmodex.o: contmodex.cc $(SOPHYAINCP)sopnamsp.h \
+  contmodex.h $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)pigncont.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)gp_contour.h \
+  $(SOPHYAINCP)gp_types.h \
+  $(SOPHYAINCP)gpc_misc.h \
+  $(SOPHYAINCP)gp_dynarray.h \
+  $(SOPHYAINCP)gp_graph3d.h \
+  $(SOPHYAINCP)gp_alloc.h \
+  $(SOPHYAINCP)pidrawer.h nomgadapter.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  contmodex.cc
+ 
+$(SOPHYAOBJP)cxxexecutor.o: cxxexecutor.cc \
+  $(SOPHYAINCP)sopnamsp.h cxxexecutor.h \
+  $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)cxxcmplnk.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxexecutor.cc
+ 
+$(SOPHYAOBJP)cxxexecwin.o: cxxexecwin.cc \
+  $(SOPHYAINCP)sopnamsp.h cxxexecutor.h \
+  $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h cxxexecwin.h \
+  $(SOPHYAINCP)pisysdep.h pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxexecwin.cc
+ 
+$(SOPHYAOBJP)flowmodex.o: flowmodex.cc $(SOPHYAINCP)sopnamsp.h \
+  flowmodex.h $(SOPHYAINCP)machdefs.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pi2dvec.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)pidrawer.h nomgadapter.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  flowmodex.cc
+ 
+$(SOPHYAOBJP)graphexecut.o: graphexecut.cc \
+  $(SOPHYAINCP)sopnamsp.h piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h graphexecut.h \
+  $(SOPHYAINCP)strutilxx.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pibargraph.h \
+  $(SOPHYAINCP)pitxtdrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  graphexecut.cc
+ 
+$(SOPHYAOBJP)nobjmgr.o: nobjmgr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)datatypes.h \
+  $(SOPHYAINCP)machdefs.h nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)tvector.h pitvmaad.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pisurfdr.h pipodrw.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hist2err.h pintuple.h pintup3d.h \
+  $(SOPHYAINCP)pi3ddrw.h pigfd1.h \
+  $(SOPHYAINCP)generaldata.h pigfd2.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nobjmgr.cc
+ 
+$(SOPHYAOBJP)nomdvladapter.o: nomdvladapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomdvladapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)dvlist.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomdvladapter.cc
+ 
+$(SOPHYAOBJP)nomgadapter.o: nomgadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomgadapter.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomgadapter.cc
+ 
+$(SOPHYAOBJP)nomgfdadapter.o: nomgfdadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomgfdadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pipodrw.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomgfdadapter.cc
+ 
+$(SOPHYAOBJP)nomherradapter.o: nomherradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomherradapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h pihisto.h \
+  phistwrapper.h pihisto2d.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h sohiswrap.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)pexceptions.h pipodrw.h \
+  servnobjm.h nobjmgr.h $(SOPHYAINCP)dvlist.h \
+  dlftypes.h $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)strutilxx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomherradapter.cc
+ 
+$(SOPHYAOBJP)nomhistadapter.o: nomhistadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomhistadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h pihisto.h \
+  phistwrapper.h sohiswrap.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)pexceptions.h pihisto2d.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h pipodrw.h servnobjm.h \
+  nobjmgr.h $(SOPHYAINCP)dvlist.h dlftypes.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomhistadapter.cc
+ 
+$(SOPHYAOBJP)nomimagadapter.o: nomimagadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomimagadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h pimgadapter.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomimagadapter.cc
+ 
+$(SOPHYAOBJP)nomskymapadapter.o: nomskymapadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomskymapadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h pitvmaad.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)complexios.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomskymapadapter.cc
+ 
+$(SOPHYAOBJP)nomspecrespadapter.o: nomspecrespadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h nomspecrespadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)gaussfilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomspecrespadapter.cc
+ 
+$(SOPHYAOBJP)nomtarradapter.o: nomtarradapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h nomtarradapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)tvector.h pitvmaad.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)fioarr.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomtarradapter.cc
+ 
+$(SOPHYAOBJP)nomtmatvecadapter.o: nomtmatvecadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h nomtmatvecadapter.h \
+  nomgadapter.h $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pidrawer.h pitvmaad.h \
+  $(SOPHYAINCP)cimage.h pimgadapter.h \
+  $(SOPHYAINCP)fioarr.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  nomtmatvecadapter.cc
+ 
+$(SOPHYAOBJP)pawexecut.o: pawexecut.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h pawexecut.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h nobjmgr.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h pihisto.h \
+  phistwrapper.h $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pawexecut.cc
+ 
+$(SOPHYAOBJP)pi2dvec.o: pi2dvec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)nbtri.h pi2dvec.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pi2dvec.cc
+ 
+$(SOPHYAOBJP)piacmd.o: piacmd.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmd.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h dlftypes.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)srandgen.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h basexecut.h \
+  graphexecut.h piafitting.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tvector.h pawexecut.h \
+  cxxexecutor.h cxxexecwin.h contmodex.h flowmodex.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piacmd.cc
+ 
+$(SOPHYAOBJP)piafitting.o: piafitting.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)nbtri.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)fct1dfit.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)fct2dfit.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)objfitter.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h piafitting.h \
+  $(SOPHYAINCP)machdefs.h nomgadapter.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)pdlmgr.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h nobjmgr.h \
+  $(SOPHYAINCP)dvlist.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h nomhistadapter.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h nomgfdadapter.h \
+  nomimagadapter.h nomtmatvecadapter.h \
+  $(SOPHYAINCP)generaldata.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piafitting.cc
+ 
+$(SOPHYAOBJP)pigfd1.o: pigfd1.cc $(SOPHYAINCP)sopnamsp.h \
+  pigfd1.h $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigfd1.cc
+ 
+$(SOPHYAOBJP)pigfd2.o: pigfd2.cc $(SOPHYAINCP)sopnamsp.h \
+  pigfd2.h $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pigraph3d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pigfd2.cc
+ 
+$(SOPHYAOBJP)pihisto.o: pihisto.cc pihisto.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h phistwrapper.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pihisto.cc
+ 
+$(SOPHYAOBJP)pihisto2d.o: pihisto2d.cc $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)sopnamsp.h pihisto2d.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pieldrw.h phistwrapper.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pihisto2d.cc
+ 
+$(SOPHYAOBJP)piinit.o: piinit.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h piinit.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h nomdvladapter.h \
+  nomgadapter.h $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h nomhistadapter.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h nomherradapter.h \
+  $(SOPHYAINCP)histerr.h \
+  $(SOPHYAINCP)hist2err.h nomgfdadapter.h \
+  nomimagadapter.h $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h nomtmatvecadapter.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)generaldata.h nomtarradapter.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h nomskymapadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)gaussfilt.h nomspecrespadapter.h \
+  $(SOPHYAINCP)specresp.h piaversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piinit.cc
+ 
+$(SOPHYAOBJP)pintup3d.o: pintup3d.cc $(SOPHYAINCP)sopnamsp.h \
+  pintup3d.h $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pigraph3d.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pintup3d.cc
+ 
+$(SOPHYAOBJP)pintuple.o: pintuple.cc $(SOPHYAINCP)sopnamsp.h \
+  pintuple.h $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pintuple.cc
+ 
+$(SOPHYAOBJP)pipodrw.o: pipodrw.cc $(SOPHYAINCP)sopnamsp.h \
+  pipodrw.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)hist2err.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)generalfunc.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pipodrw.cc
+ 
+$(SOPHYAOBJP)pisiadw.o: pisiadw.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)smathconst.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pisiadw.cc
+ 
+$(SOPHYAOBJP)pistdimgapp.o: pistdimgapp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)psighand.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h dlftypes.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)piimgtools.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)pidrwtools.h \
+  $(SOPHYAINCP)piaxestools.h \
+  $(SOPHYAINCP)piscdrawwdg.h piinit.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)piversion.h piaversion.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pistdimgapp.cc
+ 
+$(SOPHYAOBJP)pitvmaad.o: pitvmaad.cc $(SOPHYAINCP)sopnamsp.h \
+  pitvmaad.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pitvmaad.cc
+ 
+$(SOPHYAOBJP)servnobjm.o: servnobjm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)strutil.h nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h dlftypes.h servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fct1dfit.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)fct2dfit.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)matharr.h pitvmaad.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)piyfxdrw.h \
+  $(SOPHYAINCP)pisurfdr.h pintuple.h pintup3d.h \
+  $(SOPHYAINCP)pi3ddrw.h pipodrw.h \
+  $(SOPHYAINCP)hist2err.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  servnobjm.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/PIext/sohiswrap.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/sohiswrap.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/sohiswrap.h	(revision 3445)
@@ -0,0 +1,233 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classes d'emballage (wrapper) d'histos SOPHYA/HiStats
+// pour trace par PIHisto 
+//       C. Magneville / R. Ansari             2007
+// (C)     CEA-DAPNIA            LAL-IN2P3/CNRS
+
+#ifndef SOHISWRAP_H
+#define SOHISWRAP_H
+
+#include "histos.h"
+#include "hisprof.h"
+#include "histerr.h"
+
+#include "histos2.h"
+#include "hist2err.h"
+
+#include "pexceptions.h"
+
+#include "phistwrapper.h"
+
+namespace SOPHYA {
+ 
+//! Wrapper class for SOPHYA::Histo  , SOPHYA::HProf , for use by PIHisto 
+class HistoWrapper : public P1DHistoWrapper
+{
+public:
+  HistoWrapper(Histo* h, bool ad=true) 
+    : P1DHistoWrapper(h->NBins())
+  {
+    if (h == NULL) throw NullPtrError("HistoWrapper(Histo* h = NULL)");
+    mHis = h;
+    mHpr = dynamic_cast<HProf*>(h);
+    mAD = ad;
+    DefineXCoordinate(h->XMin(), h->BinWidth()); // Pour P1DArrayAdapter
+  }
+  ~HistoWrapper() { if (mAD) delete mHis; }
+
+  virtual int_4 NBins() { return mHis->NBins(); }
+  virtual r_8 XMin() { return mHis->XMin() ; } 
+  virtual r_8 XMax() { return mHis->XMax() ; } 
+  virtual r_8 BinWidth() { return mHis->BinWidth() ; } 
+
+  virtual r_8 BinLowEdge(int_4 i) { return mHis->BinLowEdge(i) ; }
+  virtual r_8 BinCenter(int_4 i) { return mHis->BinCenter(i) ; }
+  virtual r_8 BinHighEdge(int_4 i) { return mHis->BinHighEdge(i) ; }
+
+  virtual r_8 Content(int_4 i) { return (*mHis)(i) ; }
+  virtual r_8 Error(int_4 i) { return mHis->Error(i) ; }
+  virtual r_8 NbEntries(int_4 i) { if(mHpr) return mHpr->SumW(i); else return 0.; }
+
+  virtual void Update() { mHis->UpdateHisto(); }
+
+  // ajoute des lignes de texte avec les infos statistiques 
+  virtual int GetStatInfoAsText(vector<string> & text) 
+  {
+    char label[64];
+    string s;
+    sprintf(label, "N= %-g",mHis->NData());
+    s = label;   text.push_back(s);
+    sprintf(label, "m= %-g",mHis->Mean());
+    s = label;   text.push_back(s);
+    sprintf(label, "s= %-g",mHis->Sigma());
+    s = label;   text.push_back(s);
+    return 3;
+  }
+
+  // pointeur sur l'objet histo
+  inline Histo* getHisto() { return mHis; }
+
+protected:
+  Histo* mHis;
+  HProf* mHpr;
+  bool mAD;
+};
+
+
+//! Wrapper class for SOPHYA::HistoErr  for use by PIHisto 
+class HistoErrWrapper : public P1DHistoWrapper 
+{
+public:
+  HistoErrWrapper(HistoErr* h, bool ad=false) 
+    : P1DHistoWrapper(h->NBins())
+  {
+    if (h == NULL) throw NullPtrError("HistoErrWrapper(HistoErr* h = NULL)");
+    mHis = h;  mAD = ad;
+    DefineXCoordinate(h->XMin(), h->BinWidth()); // Pour P1DArrayAdapter
+  }
+  ~HistoErrWrapper() { if (mAD) delete mHis; }
+
+  virtual int_4 NBins() { return mHis->NBins(); }
+  virtual r_8 XMin() { return mHis->XMin() ; } 
+  virtual r_8 XMax() { return mHis->XMax() ; } 
+  virtual r_8 BinWidth() { return mHis->BinWidth() ; } 
+
+  virtual r_8 BinLowEdge(int_4 i) { return mHis->BinLowEdge(i) ; }
+  virtual r_8 BinCenter(int_4 i) { return mHis->BinCenter(i) ; }
+  virtual r_8 BinHighEdge(int_4 i) { return mHis->BinHighEdge(i) ; }
+
+  virtual r_8 Content(int_4 i) { return (*mHis)(i) ; }
+  virtual r_8 Error(int_4 i) { return mHis->Error(i) ; }
+  virtual r_8 NbEntries(int_4 i) { return mHis->NEntBin(i) ; }
+
+  // ajoute des lignes de texte avec les infos statistiques 
+  virtual int GetStatInfoAsText(vector<string> & text) 
+  {
+    char label[64]; string s;
+
+    sprintf(label, "NMean= %d",mHis->NMean());
+    s = label; text.push_back(s);
+
+    return 1;
+  }
+
+  // pointeur sur l'objet histo
+  inline HistoErr* getHistoErr() { return mHis; }
+
+protected:
+  HistoErr* mHis;
+  bool mAD;
+};
+
+
+//! Wrapper class for SOPHYA::Histo2D   for use by PIHisto2D 
+class Histo2DWrapper : public P2DHistoWrapper
+{
+public:
+  Histo2DWrapper(Histo2D* h, bool ad=true) 
+    : P2DHistoWrapper(h->NBinX(), h->NBinY())
+  {
+    if (h == NULL) throw NullPtrError("Histo2DWrapper(Histo2D* h = NULL)");
+    mHis = h;  mAD = ad;
+    DefineXYCoordinates(h->XMin(), h->YMin(), h->WBinX(), h->WBinY() ); // pour P2DArrayAdapter
+  }
+
+  virtual ~Histo2DWrapper() { if (mAD) delete mHis; }
+
+  virtual int_4 NBinX() { return mHis->NBinX(); }
+  virtual int_4 NBinY() { return mHis->NBinY(); }
+  virtual r_8 XMin() { return mHis->XMin() ; } 
+  virtual r_8 XMax() { return mHis->XMax() ; } 
+  virtual r_8 YMin() { return mHis->YMin() ; } 
+  virtual r_8 YMax() { return mHis->YMax() ; } 
+  virtual r_8 WBinX() { return mHis->WBinX() ; } 
+  virtual r_8 WBinY() { return mHis->WBinY() ; } 
+
+  virtual void BinLowEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
+    { mHis->BinLowEdge(i, j, xr, yr); return; }
+  virtual void BinCenter(int_4 i, int_4 j, r_8& xr, r_8& yr)
+    { mHis->BinCenter(i, j, xr, yr); return; }
+  virtual void BinHighEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
+    { mHis->BinHighEdge(i, j, xr, yr); return; }
+
+  // Renvoie contenu du bin i
+  virtual r_8 Content(int_4 i, int_4 j) { return (*mHis)(i,j) ; }
+  virtual r_8 Error(int_4 i, int_4 j) { return mHis->Error(i,j) ; }
+  virtual r_8 NbEntries(int_4 i, int_4 j) { return 0.; }
+
+  // ajoute des lignes de texte avec les infos statistiques (dans text)
+  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
+  virtual int GetStatInfoAsText(vector<string> &  text )
+  {
+    char label[64];
+    string s;
+    sprintf(label,"N= %-g", mHis->NData());
+    s = label;   text.push_back(s);
+    return 1;
+  }
+
+  inline Histo2D* getHisto2D() { return mHis; }
+
+protected:
+  Histo2D* mHis;
+  bool mAD;
+};
+
+
+
+//! Wrapper class for SOPHYA::Histo2DErr   for use by PIHisto2D 
+class Histo2DErrWrapper : public P2DHistoWrapper
+{
+public:
+  Histo2DErrWrapper(Histo2DErr* h, bool ad=true) 
+    : P2DHistoWrapper(h->NBinX(), h->NBinY())
+  {
+    if (h == NULL) throw NullPtrError("Histo2DErrWrapper(Histo2DErr* h = NULL)");
+    mHis = h;    mAD = ad;
+    DefineXYCoordinates(h->XMin(), h->YMin(), h->WBinX(), h->WBinY() ); // pour P2DArrayAdapter
+  }
+
+  virtual ~Histo2DErrWrapper() { if (mAD) delete mHis; }
+
+  virtual int_4 NBinX() { return mHis->NBinX(); }
+  virtual int_4 NBinY() { return mHis->NBinY(); }
+  virtual r_8 XMin() { return mHis->XMin() ; } 
+  virtual r_8 XMax() { return mHis->XMax() ; } 
+  virtual r_8 YMin() { return mHis->YMin() ; } 
+  virtual r_8 YMax() { return mHis->YMax() ; } 
+  virtual r_8 WBinX() { return mHis->WBinX() ; } 
+  virtual r_8 WBinY() { return mHis->WBinY() ; } 
+
+  virtual void BinLowEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
+    { mHis->BinLowEdge(i, j, xr, yr); return; }
+  virtual void BinCenter(int_4 i, int_4 j, r_8& xr, r_8& yr)
+    { mHis->BinCenter(i, j, xr, yr); return; }
+  virtual void BinHighEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
+    { mHis->BinHighEdge(i, j, xr, yr); return; }
+
+  // Renvoie contenu du bin i
+  virtual r_8 Content(int_4 i, int_4 j) { return (*mHis)(i,j) ; }
+  virtual r_8 Error(int_4 i, int_4 j) { return mHis->Error(i,j) ; }
+  virtual r_8 NbEntries(int_4 i, int_4 j) { return mHis->NEntBin(i,j) ; }
+
+  // ajoute des lignes de texte avec les infos statistiques (dans text)
+  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
+  virtual int GetStatInfoAsText(vector<string> &  text )
+  {
+    char label[64];
+    string s;
+    sprintf(label,"NMean= %d", mHis->NMean());
+    text.push_back(label);
+    return 1;
+  }
+
+  inline Histo2DErr* getHisto2DErr() { return mHis; }
+
+protected:
+  Histo2DErr* mHis;
+  bool mAD;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Nov2007/SophyaPI/PIext/userfitfunex.c
===================================================================
--- /tags/V_Nov2007/SophyaPI/PIext/userfitfunex.c	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/PIext/userfitfunex.c	(revision 3445)
@@ -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_Nov2007/SophyaPI/ProgPI/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/Makefile	(revision 3445)
@@ -0,0 +1,651 @@
+include ../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)spiapp
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+ 
+spiapp: $(SOPHYAEXEP)spiapp
+	echo $@ " done"
+$(SOPHYAEXEP)spiapp: $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)fitsbtadapter.o: fitsbtadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fbtntintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)nomhistadapter.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbtadapter.cc
+ 
+$(SOPHYAOBJP)piacmdrdr.o: piacmdrdr.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmdrdr.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piacmdrdr.cc
+ 
+$(SOPHYAOBJP)piapp.o: piapp.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piacmd.h piacmdrdr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)piversion.h \
+  $(SOPHYAINCP)piaversion.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapp.cc
+ 
+$(SOPHYAOBJP)skymapmodule.o: skymapmodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)slinparbuff.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)lambdaBuilder.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapmodule.cc
+ 
+$(SOPHYAOBJP)sopiamodule.o: sopiamodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pitvmaad.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)nomskymapadapter.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopiamodule.cc
+ 
+$(SOPHYAOBJP)w2ps.o: w2ps.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  w2ps.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/ProgPI/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/Makefile.mgr	(revision 3445)
@@ -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 -L/sw/lib -lXm -L/usr/X11R6/lib -lXt -lX11 -framework Accelerate
+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_Nov2007/SophyaPI/ProgPI/fitsbtadapter.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/fitsbtadapter.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/fitsbtadapter.cc	(revision 3445)
@@ -0,0 +1,310 @@
+/* Interface Fits BINARY/ASCII Table     cmv 21/05/2001 */
+/*    Ajout commandes generique lecture/ecriture FITS   */
+/*                           Reza , Jan 2006            */
+
+
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <typeinfo>
+#include <iostream>
+#include <string.h>
+#include <string>
+
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+#include "fbtntintf.h"
+
+#include "nomhistadapter.h"
+#include "swfitsdtable.h"
+
+#include "fitsmanager.h"
+#include "fitshandler.h"
+#include "fiosinit.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, int lev=0);
+  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, int lev)
+{
+mFBT->Print(os, lev);
+}
+
+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()
+{
+FitsIOServerInit();  // On s'assure de l'initialisation du module FitsIOServer
+
+NamedObjMgr omg;
+PIACmd * mpiac = omg.GetImgApp()->CmdInterpreter();
+
+// On enregistre l'adaptateur
+Services2NObjMgr* serv = omg.GetServiceObj();
+serv->RegisterClass(new FitsBTNtuIntf, new NOMAdapter_FitsBT);
+// ainsi que pour l'adaptateur de SwFitsDataTable
+serv->RegisterClass(new SwFitsDataTable, new NOMAdapter_DataTable );
+
+// 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)";
+usage += "\n See also  scanfits writefits readfits ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "scanfits";
+usage = "scanfits: scan fits files and print information on each HDU\n" ;
+usage += "Usage: scanfits FileName [slev=0...3]\n";
+usage += "slev=1,3: header keywords , slev=2,3: try to read each HDU\n";
+usage += "See also: readfits writefits fitsadapt ";
+mpiac->RegisterCommand(kw, usage, this, hgrp); 
+
+kw = "writefits";
+usage = "writefits: Write objects to a fits file \n" ;
+usage += "Usage: writefits nameobj/pattern FileName \n";
+usage += "See also: scanfits readfits fitsadapt ";
+mpiac->RegisterCommand(kw, usage, this, hgrp); 
+
+kw = "savefits";
+usage = "savefits: alias for writefits \n" ;
+mpiac->RegisterCommand(kw, usage, this, hgrp); 
+
+kw = "readfits";
+usage = "readfits: Read one or all HDU's of a fits file \n" ;
+usage += "Usage: readfits FileName [num_hdu] \n";
+usage += " num_hdu=1,..,NbHDU (uses FitsManager) \n";
+usage += "See also  scanfits writefits fitsadapt swfitstable ";
+mpiac->RegisterCommand(kw, usage, this, hgrp); 
+
+kw = "openfits";
+usage = "openfits: alias for readfits \n" ;
+mpiac->RegisterCommand(kw, usage, this, hgrp); 
+
+kw = "swfitstable";
+usage = "swfitstable: Creates/read an SwFitsDataTable from a fits file\n" ;
+usage += "   SwFitsDataTable is a table which uses the BINARY-TBL\n";
+usage += "   of the fits file as swap space - useful for large tables\n";
+usage += "Usage: swfitstable FileName [num_hdu=2] [segsize=512]\n";
+usage += "See also: readfits scanfits";
+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);
+ }
+else if (kw == "scanfits") {
+  if(tokens.size() < 1)  {
+    cout<<"Usage: scanfits FileName [slev] "<<endl;
+    return 1;
+  }
+  int slev = 0;
+  if(tokens.size() > 1)  slev = atoi(tokens[1].c_str());
+  FitsManager::ScanFile(tokens[0], slev); 
+  return 0;
+}
+else if (kw == "swfitstable") {
+  if(tokens.size() < 1)  {
+    cout<<"Usage: swfitstable FileName [num_hdu=2] [segsize=512]"<<endl;
+    return 1;
+  }
+  int numhdu = 2;
+  if(tokens.size() > 1)  numhdu = atoi(tokens[1].c_str());
+  int segsize = 512;
+  if(tokens.size() > 2)  segsize = atoi(tokens[2].c_str());
+  SwFitsDataTable* swfd = new SwFitsDataTable(tokens[0], numhdu, segsize);
+  if (swfd != NULL) {
+    string nom = omg.GetServiceObj()->FileName2Name(tokens[0]);
+    omg.AddObj(swfd, nom, false);
+    cout << "swfitstable: SwFitsDataTable object" << nom << " from" 
+	 << tokens[0] << " HDU=" << numhdu << endl;
+  }    
+  return 0;
+}
+else if ((kw == "writefits") || (kw == "savefits")) {
+  if(tokens.size() < 2)  {
+    cout<<"Usage: writefits nameobj/pattern FileName "<<endl;
+    return 1;
+  }
+  vector<string> noms;
+  omg.GetObjList(tokens[0], noms);
+  if (noms.size() < 1) {
+    cout<<"writefits/Error: no object with this name "<<endl;
+    return 2;
+  }
+  cout << "writefits: Opening/Creating fits file " << tokens[1] << endl;
+  FitsInOutFile fos(tokens[1], FitsInOutFile::Fits_Create);
+  for(int kk=0; kk<noms.size(); kk++) {
+    AnyDataObj* co = omg.GetObj(noms[kk]);
+    if (co == NULL) continue;
+    fos.SetNextExtensionName(noms[kk]);
+    try {
+      FitsManager::Write(fos, *co);
+      cout << "writefits: Object " << noms[kk] << " written to HDU No " << fos.CurrentHDU() << endl;  
+    }
+    catch (NotFoundExc & exc) {
+      cout << "writefits/Error writing object " << noms[kk] << " -> " << exc.Msg() << endl;
+    }
+  }
+  return 0;
+}
+else if ((kw == "readfits") || (kw == "openfits")) {
+  if(tokens.size() < 1)  {
+    cout<<"Usage: readfits FileName [num_hdu]"<<endl;
+    return 1;
+  }
+  cout << "readfits: Opening  fits file " << tokens[0];
+  FitsInOutFile fis(tokens[0], FitsInOutFile::Fits_RO);
+  int k1 = 1;
+  int k2 = fis.NbHDUs();
+  if (fis.CurrentHDU() > 1) k1 = k2 = fis.CurrentHDU(); 
+  bool fgshdu = false;
+  if (tokens.size() > 1) {  // Numero de HDU specifie
+    k2 = k1 = atoi(tokens[1].c_str());
+    fgshdu = true;
+    cout << " - HDU Num " << k1 << endl;
+  }
+  else cout << " - HDU's " << k1 << "-" << k2 << endl;
+
+  string bnom = omg.GetServiceObj()->FileName2Name(tokens[0]);
+  string nom = bnom;
+  char bun[16];
+  int kon = 0;
+  for(int k=k1; k<=k2; k++) {
+    try {
+      if (fgshdu) fis.MoveAbsToHDU(k);
+      FitsHandlerInterface* fhi = FitsManager::Read(fis);
+      AnyDataObj* obj = fhi->DataObj();
+      if (obj) {
+       kon++;
+       if (kon > 1)  { 
+	 sprintf(bun, "%d", kon);
+	 nom = bnom + bun;
+       }
+       omg.AddObj(obj, nom, false);
+       cout << "readfits: " << (string)typeid(*obj).name()
+	    << "  read From HDU " << k << " ->" << nom << endl;
+      }
+      else delete fhi; 
+      //Reza, Jan 2006: Sinon, le fhi ne sera jamais supprime, tant pis 
+      // Il ne prend pas beaucoup de place, une fois que son objet est delete
+    }
+    catch (NotFoundExc & exc) {
+      cout << "readfits/Error - HDU=" << k+1 << " : " << exc.Msg() << endl;
+    }
+    if (k<k2) fis.MoveToNextHDU();
+  }
+  return 0;  
+}
+ 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_Nov2007/SophyaPI/ProgPI/makefile_wgrdl
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/makefile_wgrdl	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/makefile_wgrdl	(revision 3445)
@@ -0,0 +1,615 @@
+include ../BuildMgr/sophyamake.inc
+
+#####  makefile to build piapp linked with GNU readline library 
+#####   
+PROGS = $(SOPHYAEXEP)spiapp
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+ 
+### GNU-readline : libray path and name (-lreadline -lhistory)
+spiapp: $(SOPHYAEXEP)spiapp
+	echo $@ " done"
+$(SOPHYAEXEP)spiapp: $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o $(SOPHYAALLSLBLIST) -L/usr/local/lib -lreadline -lhistory -lcurses
+ 
+$(SOPHYAOBJP)fitsbtadapter.o: fitsbtadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fbtntintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbtadapter.cc
+ 
+### GNU-readline : flag WITH_GNUREADLINE and include file path readline/readline.h readline/history.h
+$(SOPHYAOBJP)piacmdrdr.o: piacmdrdr.cc \
+  $(SOPHYAINCP)sopnamsp.h piacmdrdr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -I/usr/local/include -DWITH_GNUREADLINE -o $@  piacmdrdr.cc
+ 
+$(SOPHYAOBJP)piapp.o: piapp.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h piacmdrdr.h \
+  $(SOPHYAINCP)piversion.h \
+  $(SOPHYAINCP)piaversion.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapp.cc
+ 
+$(SOPHYAOBJP)skymapmodule.o: skymapmodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)slinparbuff.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)nbrandom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)lambdaBuilder.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapmodule.cc
+ 
+$(SOPHYAOBJP)sopiamodule.o: sopiamodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pitvmaad.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)nomskymapadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopiamodule.cc
+ 
+$(SOPHYAOBJP)w2ps.o: w2ps.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  w2ps.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.cc	(revision 3445)
@@ -0,0 +1,83 @@
+#include "sopnamsp.h"
+#include "piacmdrdr.h"
+#include <iostream> 
+#include <unistd.h> 
+#include <stdio.h> 
+
+#ifdef WITH_GNUREADLINE
+#include "readline/readline.h"
+#include "readline/history.h"
+
+PIACmdReader::PIACmdReader(PIStdImgApp* imgapp)
+{
+  cout << " PIACmdReader::PIACmdReader() Using GNU readline library " << endl;
+  if (imgapp) _imgapp = imgapp;
+  else throw NullPtrError("PIACmdReader::PIACmdReader(NULL) ! ");
+}
+
+void PIACmdReader::run()
+{
+  char * line = NULL;
+  bool fgok = true;
+  char prompt[128];
+  int nc = 0;
+  while (fgok) {
+    usleep(100000);
+    sprintf(prompt,"piapp[%d] ", nc);
+    line = readline(prompt);
+    if (!line) continue;
+    else if (line[0] != '\0') {
+      nc++;
+      if (strcmp(line,"history") == 0) {
+	cout << " ===> Command history ... " << endl;
+	HIST_ENTRY **list;
+	int i;
+	list = history_list ();
+	if (list)
+	  for (int i = 0; list[i]; i++)
+	    cout << i << "- " << list[i]->line << endl;
+      }       
+      else { 
+	printf("[%d] %s\n", nc-1, line);
+	string s = line;
+	_imgapp->CmdInterpreter()->AddInputLine(s);
+	add_history (line);
+      }
+    }
+    free(line); 
+  }
+}
+#else
+//  ------ SANS GNU readline --------
+PIACmdReader::PIACmdReader(PIStdImgApp* imgapp)
+{
+  cout << " PIACmdReader::PIACmdReader() Using fgets() - without GNU readline " << endl;
+  if (imgapp) _imgapp = imgapp;
+  else throw NullPtrError("PIACmdReader::PIACmdReader(NULL) ! ");
+}
+
+void PIACmdReader::run()
+{
+  char line[1024];
+  bool fgok = true;
+  int nc = 0;
+  while (fgok) {
+    usleep(100000);
+    printf("piapp[%d] ", nc);
+    line[0] = '\0';
+    char* rs = fgets(line, 1024, stdin);
+    if (rs == NULL) continue;
+    int l = strlen(line);
+    if (l < 1)  continue; 
+    if ( (line[l-1] == '\n') || (line[l-1] == '\r') )  line[l-1] = '\0';
+    if (line[0] != '\0') {
+      printf("[%d] %s\n", nc, line);
+      nc++;
+      string s = line;
+      _imgapp->CmdInterpreter()->AddInputLine(s);
+    }
+  }
+}
+
+#endif
+
Index: /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.h
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/piacmdrdr.h	(revision 3445)
@@ -0,0 +1,23 @@
+// This may look like C code, but it is really -*- C++ -*-
+// piapp command reader using GNU readline library  
+//               R. Ansari  2006
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIACMDRDR_H_SEEN
+#define PIACMDRDR_H_SEEN
+
+#include "machdefs.h"
+#include "zthread.h"
+#include "pistdimgapp.h"
+
+namespace SOPHYA {
+class PIACmdReader : public ZThread {
+public:
+  PIACmdReader(PIStdImgApp* imgapp);
+  virtual void run();
+protected:
+  PIStdImgApp* _imgapp;
+};
+}  // namespace SOPHYA 
+
+#endif 
Index: /tags/V_Nov2007/SophyaPI/ProgPI/piapp.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/piapp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/piapp.cc	(revision 3445)
@@ -0,0 +1,327 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "sopnamsp.h"
+#include "pistdimgapp.h"
+#include "piacmd.h"
+#include "piacmdrdr.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 spiapp: Starts the piapp interactive data analysis program.
+
+  This interactive data analysis program uses the SOPHYA libray, 
+  the PI GUI library. It has multiple execution threads and a 
+  c-shell inspired command execution interpreter. 
+  See the piapp user manual for more information.
+  The SOPHYA piapp executable is called \b spiapp.
+
+  \verbatim
+  csh> spiapp -h
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version 2.1 Revision 0 (V_Nov2007) -- Nov 24 2007 13:08:58 cxx 
+
+ piapp: Interactive data analysis and visualisation program 
+ Usage: piapp [-nored] [-doublered] [-termread] [-term] 
+              [-hidezswin] [-small] [-nosig] [-nosigfpe] [-nosigsegv] 
+              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] 
+  -nored : Don't redirect stdout/stderr to piapp console
+  -doublered : Redirect stdout/stderr to piapp console AND the terminal
+  -termread : Read commands on terminal (stdin)
+  -term : equivalent to -nored -termread -small 
+  -hidezswin : Hide Zoom/Stat/ColMap window 
+  -small : Create small size main piapp window 
+  -nosig : Don't catch SigFPE, SigSEGV 
+  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV 
+  -tmpdir TmpDirectory: defines TMDIR for temporary files 
+  -help2tex: Create a LaTeX help file (piahelp.tex)
+  -exec file [args] : Execute command file (last option)
+
+  \endverbatim
+ 
+*/
+
+int Usage(bool fgerr)
+{
+  if (fgerr) { 
+    cout << " piapp : Argument Error ! piapp -h for Usage" << endl; 
+    return 1;
+  }
+  else {
+    cout << "\n piapp: Interactive data analysis and visualisation program \n"
+	 << " Usage: piapp [-nored] [-doublered] [-termread] [-term] \n"
+	 << "              [-hidezswin] [-small] [-nosig] [-nosigfpe] [-nosigsegv] \n"
+	 << "              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] \n"
+	 << "  -nored : Don't redirect stdout/stderr to piapp console\n"
+         << "  -doublered : Redirect stdout/stderr to piapp console AND the terminal \n"
+	 << "  -termread : Read commands on terminal (stdin)\n"
+	 << "  -term : equivalent to -nored -termread -small \n"
+	 << "  -hidezswin : Hide Zoom/Stat/ColMap window \n"
+	 << "  -small : Create small size main piapp window \n"
+	 << "  -nosig : Don't catch SigFPE, SigSEGV \n"
+         << "  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV \n"
+	 << "  -tmpdir TmpDirectory: defines TMDIR for temporary files \n"
+	 << "  -help2tex: Create a LaTeX help file (piahelp.tex)\n"
+	 << "  -exec file [args] : Execute command file (last option)\n"
+	 << endl;
+    return 0;
+  }
+}
+
+/*  ================================ MAIN() =================================  */
+
+int main(int narg, char *arg[])
+{
+int ofa;
+bool fgfpe, fgsegv, fghidezsw, fgexec, fgsmall, fgtermrd;
+RED_OUTERR_FLG fgred = CONSRED_OE;
+
+SkyTInitiator skyinit;
+   
+InitTim();
+
+if(narg>1) 
+  for(int jh=1;jh<narg;jh++) if(strcmp(arg[jh],"-h") == 0) return Usage(false);
+
+ofa = 1;
+fgred = CONSRED_OE;
+fgfpe = fgsegv = true;
+fghidezsw = false;
+fgexec = false;
+bool fgtmp = false;
+fgsmall = false;
+ fgtermrd = 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=NORED_OE; 
+  else if (strcmp(arg[ka],"-doublered") == 0)   fgred=DOUBLERED_OE; 
+  else if (strcmp(arg[ka],"-nosig") == 0)   fgfpe=fgsegv=false; 
+  else if (strcmp(arg[ka],"-termread") == 0)   fgtermrd=true; 
+  else if (strcmp(arg[ka],"-term") == 0)  
+    { fgred=NORED_OE;  fgtermrd=true; fgsmall=true; }
+  else if (strcmp(arg[ka],"-nosigfpe") == 0)   fgfpe=false; 
+  else if (strcmp(arg[ka],"-nosigsegv") == 0)   fgsegv=false; 
+  else if (strcmp(arg[ka],"-small") == 0)     fgsmall=true; 
+  else if (strcmp(arg[ka],"-hidezswin") == 0)   fghidezsw=true; 
+  else if (strcmp(arg[ka],"-help2tex") == 0) { fgtexh=true; fgred=NORED_OE; }
+  else if (strcmp(arg[ka],"-tmpdir") == 0) {
+    if (ka == narg-1) return 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");
+
+SophyaInitiator::PrintVersion(true);  // SOPHYA version and module list 
+
+// Reza , Jan07
+// On cree l'objet PIApplication avant de faire mkdir TmpDir
+// En cas de pb X11 , il n'y a pas de repertoire PIATmpxxx qui traine apres
+
+PIStdImgApp * app = new PIStdImgApp(fgsmall, narg, arg);
+// cout << " DBG-2 " <<  app->ObjMgr()->GetTmpDir() << endl;
+
+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);
+}
+
+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
+app->RedirectStdOutErr(fgred);
+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);
+}
+
+// Creation du lecteur de commande sur terminal (avec GNU readline)
+PIACmdReader cmdrdr(app);
+if (fgtermrd) cmdrdr.start();
+
+int rc = 0;
+bool cont = true;
+char rep; // ans[32]
+int excnt = 0;
+while(cont) {
+  rc = 0;   cont = false;
+  app->SetReady();
+  app->RedirectStdOutErr(fgred);
+  try {
+    app->Run();
+  }
+  catch(PThrowable exc) {  // Catching SOPHYA exceptions 
+    app->Stop();
+    app->RedirectStdOutErr(NORED_OE);  
+    //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(NORED_OE);  
+    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(NORED_OE);  
+cout << "\n ------------------------------------------------ \n"
+     << " piapp: Exiting - Cleaning up ... " << endl;
+
+// -- ca fait planter sur linux -- Reza 04/2006 if (fgtermrd) cmdrdr.cancel();
+
+// 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_Nov2007/SophyaPI/ProgPI/programs
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/programs	(revision 3445)
@@ -0,0 +1,1 @@
+spiapp piapp.o piacmdrdr.o sopiamodule.o fitsbtadapter.o w2ps.o skymapmodule.o
Index: /tags/V_Nov2007/SophyaPI/ProgPI/skymapmodule.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/skymapmodule.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/skymapmodule.cc	(revision 3445)
@@ -0,0 +1,1512 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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 Resol2SizeIndex(vector<string>& tokens);
+  void SizeIndex2Resol(vector<string>& tokens);
+  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 gdesc = "4 Pi spherical, local maps manipulation commands \n";
+gdesc += "and spherical harmonics analysis Ylm. \n This is mainly "; 
+gdesc += "Based on SOPHYA SkyMap and Samba modules. ";
+mpiac->AddHelpGroup(hgrp, gdesc);
+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 = "resol2szidx";
+usage = "Compute SizeIndex value (=nside for HEALPix) for a";
+usage += "\n given resolution, (resol in arcminutes)";
+usage += "\n Usage: resol2szidx resol";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+kw = "szidx2resol";
+usage = "Compute resolution for a given SizeIndex (=nside for HEALPix)";
+usage += "\n Usage: szidx2resol szidx_m";
+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 == "resol2szidx") {
+  if(tokens.size()<1) {
+    cout<<"Usage: resol2szidx resol"<<endl;
+    return(0);
+  }
+  Resol2SizeIndex(tokens);
+} else if(kw == "szidx2resol") {
+  if(tokens.size()<1) {
+    cout<<"Usage: szidx2resol szidx_m"<<endl;
+    return(0);
+  }
+  SizeIndex2Resol(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::Resol2SizeIndex(vector<string>& tokens)
+{
+ double resamin = atof(tokens[0].c_str());
+ double resrad = Angle(resamin,Angle::ArcMin).ToRadian();
+ int_4 mh = SphereHEALPix<r_4>::ResolToSizeIndex(resrad);
+ int_4 mt = SphereThetaPhi<r_4>::ResolToSizeIndex(resrad);
+ cout << "Resol2SizeIndex: Resol= " << resamin << " arcmin ->" 
+      << resrad << " radian  NPix ~= " << 4.*M_PI/(resrad*resrad) 
+      << " \n  ===> nside=m_HEALPix= " << mh << "  m_ThetaPhi= " << mt << endl;
+ return;
+}
+
+void skymapmoduleExecutor::SizeIndex2Resol(vector<string>& tokens)
+{
+ int_4 m = atoi(tokens[0].c_str());
+ double resh = SphereHEALPix<r_4>::SizeIndexToResol(m);
+ double rest = SphereThetaPhi<r_4>::SizeIndexToResol(m);
+ cout << "SizeIndex2Resol: SizeIndex (m)= " << m
+      << "\n HEALPix:  " << Angle(resh).ToArcMin() << " arcmin "
+      << " NPix= " << 12*m*m 
+      << "\n ThetaPhi: " << Angle(rest).ToArcMin() << " arcmin "
+      << " NPix ~= " <<  (int_4)(4.*M_PI/(rest*rest)) << endl;
+ return;
+}
+
+/* --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<<" sigma^2="<<sum2*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_Nov2007/SophyaPI/ProgPI/skymapmodule.pic
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/skymapmodule.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/skymapmodule.pic	(revision 3445)
@@ -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_Nov2007/SophyaPI/ProgPI/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/smakefile	(revision 3445)
@@ -0,0 +1,651 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)spiapp
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+ 
+spiapp: $(SOPHYAEXEP)spiapp
+	echo $@ " done"
+$(SOPHYAEXEP)spiapp: $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)fitsbtadapter.o: fitsbtadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fbtntintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)nomhistadapter.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)hisprof.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbtadapter.cc
+ 
+$(SOPHYAOBJP)piacmdrdr.o: piacmdrdr.cc $(SOPHYAINCP)sopnamsp.h \
+  piacmdrdr.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piacmdrdr.cc
+ 
+$(SOPHYAOBJP)piapp.o: piapp.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)piacmd.h piacmdrdr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)piversion.h \
+  $(SOPHYAINCP)piaversion.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapp.cc
+ 
+$(SOPHYAOBJP)skymapmodule.o: skymapmodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)slinparbuff.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)lambdaBuilder.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapmodule.cc
+ 
+$(SOPHYAOBJP)sopiamodule.o: sopiamodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pitvmaad.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)nomskymapadapter.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopiamodule.cc
+ 
+$(SOPHYAOBJP)w2ps.o: w2ps.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  w2ps.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/ProgPI/smakefile_wgrdl
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/smakefile_wgrdl	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/smakefile_wgrdl	(revision 3445)
@@ -0,0 +1,615 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+#####  makefile to build piapp linked with GNU readline library 
+#####   
+PROGS = $(SOPHYAEXEP)spiapp
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+ 
+### GNU-readline : libray path and name (-lreadline -lhistory)
+spiapp: $(SOPHYAEXEP)spiapp
+	echo $@ " done"
+$(SOPHYAEXEP)spiapp: $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)piapp.o $(SOPHYAOBJP)piacmdrdr.o $(SOPHYAOBJP)sopiamodule.o $(SOPHYAOBJP)fitsbtadapter.o $(SOPHYAOBJP)w2ps.o $(SOPHYAOBJP)skymapmodule.o $(SOPHYAALLSLBLIST) -L/usr/local/lib -lreadline -lhistory -lcurses
+ 
+$(SOPHYAOBJP)fitsbtadapter.o: fitsbtadapter.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)fbtntintf.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  fitsbtadapter.cc
+ 
+### GNU-readline : flag WITH_GNUREADLINE and include file path readline/readline.h readline/history.h
+$(SOPHYAOBJP)piacmdrdr.o: piacmdrdr.cc \
+  $(SOPHYAINCP)sopnamsp.h piacmdrdr.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -I/usr/local/include -DWITH_GNUREADLINE -o $@  piacmdrdr.cc
+ 
+$(SOPHYAOBJP)piapp.o: piapp.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h piacmdrdr.h \
+  $(SOPHYAINCP)piversion.h \
+  $(SOPHYAINCP)piaversion.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)ntupintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  piapp.cc
+ 
+$(SOPHYAOBJP)skymapmodule.o: skymapmodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)slinparbuff.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)nbrandom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)lambdaBuilder.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymapmodule.cc
+ 
+$(SOPHYAOBJP)sopiamodule.o: sopiamodule.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)servnobjm.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)pitvmaad.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)piscdrawwdg.h \
+  $(SOPHYAINCP)nomgadapter.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)nomskymapadapter.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sopiamodule.cc
+ 
+$(SOPHYAOBJP)w2ps.o: w2ps.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)piacmd.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)dlftypes.h \
+  $(SOPHYAINCP)nobjmgr.h \
+  $(SOPHYAINCP)pistdimgapp.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)pioptmenux.h \
+  $(SOPHYAINCP)pioptmenugen.h \
+  $(SOPHYAINCP)pifilechox.h \
+  $(SOPHYAINCP)pifilechogen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)piimage.h \
+  $(SOPHYAINCP)parradapter.h \
+  $(SOPHYAINCP)lut.h \
+  $(SOPHYAINCP)pieldrw.h \
+  $(SOPHYAINCP)pidrawer.h \
+  $(SOPHYAINCP)pigratt.h \
+  $(SOPHYAINCP)piaxes.h \
+  $(SOPHYAINCP)pipixmapx.h \
+  $(SOPHYAINCP)pipixmapgen.h \
+  $(SOPHYAINCP)picmapview.h \
+  $(SOPHYAINCP)pi3dwdg.h \
+  $(SOPHYAINCP)pi3ddrw.h \
+  $(SOPHYAINCP)pigraph3d.h \
+  $(SOPHYAINCP)pisiadw.h \
+  $(SOPHYAINCP)pilistx.h \
+  $(SOPHYAINCP)pilistgen.h \
+  $(SOPHYAINCP)pistzwin.h \
+  $(SOPHYAINCP)pitherm.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  w2ps.cc
+ 
Index: /tags/V_Nov2007/SophyaPI/ProgPI/sopiamodule.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/sopiamodule.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/sopiamodule.cc	(revision 3445)
@@ -0,0 +1,659 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <ctype.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"
+#include "nomskymapadapter.h"
+
+extern "C" {
+void sopiamodule_init();
+void sopiamodule_end();
+}
+
+// --- fonctions pour faire FFT
+void SophyaFFT_forw(string& nom, string& nomout, string dopt);
+void SophyaFFT_back(string& nom, string& nomout, string dopt, bool forcez8=false);
+// void SophyaFFT_crefilter(string& nomvec, string& nomfilter, string func, string dopt);
+void SophyaFFT_filter(string& nom, string& filt, string& outvec, string dopt, bool fgvec=false);
+
+//--- fonctions pour trace d'ellipse d'erreur
+int  diag_ellipse(double s1, double s2, double c, 
+		  double &a, double &b, double& tet, double& phi, int prt=0);
+
+void ellipse2vec(double a, double b, double tet, Vector& evx, Vector& evy, 
+		 double scale=1., int nbpoints=101);
+
+//--- Declaration du CmdExecutor du module
+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.);
+}
+// Cette fonction calcule les parametres de l'ellipse des erreurs
+// a,b 1/2 grand, petit axe ; tet : Angle du grand axe / Ox 
+// A partir de s1 = Sigma_1^2 , s2 = Sigma_2^2 , c = Covar_1_2 = Sigma_1 x Sigma_2 x Rho 
+
+//---------------------------------------------------------------------------
+//--- Fonctions de trace d'ellipses d'erreur 
+//---------------------------------------------------------------------------
+
+/* Nouvelle-Fonction */
+int  diag_ellipse(double s1, double s2, double c, 
+		  double &a, double &b, double& tet, double& phi, int prt)
+{
+  int rc = 0;
+  // On calcule les valeurs propres de la matrice 
+  // | s1  c  |
+  // | c   s2 |
+  a = b = 0.;  // Demi axes de l'ellipse
+  tet = 0.;     // Cos theta de l'angle de l'axe de l'ellipse
+  phi = 0.;
+  double det = (s1-s2)*(s1-s2) + 4*c*c;
+  if (det < 0.) {
+    if (prt > 0) 
+      cout << "ERREUR : diag_ellipse, ERREUR det = " << det << " <0. s1=" 
+	   << s1 << " s2=" << s2 << " c=" << c << endl;
+    return 99;
+  }
+  // les deux valeurs propres l1, l2
+  double l1 = 0.5*((s1+s2)+sqrt(det));
+  double l2 = 0.5*((s1+s2)-sqrt(det));
+  if (l1 < 0.) {
+    if (prt > 1) 
+      cout << "diag_ellipse/Warning l1 < 0. -> a = -sqrt(l1)" << endl; 
+    a = -sqrt(-l1);
+    rc += 2;
+  }
+  else   a = sqrt(l1);
+  if (l2 < 0.) {
+    if (prt > 1) 
+      cout << "diag_ellipse/Warning l2 < 0. -> b = -sqrt(l2)" << endl; 
+    b = -sqrt(-l2);
+    rc += 4;
+  }
+  else b = sqrt(l2);
+  
+  if (fabs(c) > 1.e-9)  tet = atan2((l1-s1), c);
+  else {
+    if (prt > 2) 
+      cout << "diag_ellipse/Warning c (Correlation) = 0. -> Tet=0 " << endl; 
+  }
+  // Calcul de tan(2 phi)
+  double t2phi = 0.;
+  if (fabs(s1-s2) > 1.e-9) {
+    t2phi = 2.*c/(s1-s2);
+    phi = atan(t2phi)/2.;
+  }
+  else {
+    if (prt > 3) 
+      cout << "diag_ellipse/Warning fabs(s1-s2)=" << fabs(s1-s2)
+	   << " -> Phi=Pi/4 ... " << endl; 
+    phi = 0.25*M_PI;
+  }
+  if (prt > 0) 
+    cout << "diag_ellipse/Info: s1=" << s1 << " s2=" << s2 
+	 << " c=" << c << " ---> l1=" << l1 << " l2=" << l2 
+	 << "\n a= " << a << " b=" << b << " Theta= " << tet 
+	 << "( " << tet*2/M_PI << " xPi/2)  Phi= " << phi 
+	 << "( " << phi*2/M_PI << " x Pi/2) " << endl;
+  return rc;
+}
+
+/* Nouvelle-Fonction */
+void ellipse2vec(double a, double b, double tet, Vector& evx, Vector& evy, 
+		 double scale, int nbpoints)
+{
+  a *= scale;
+  b *= scale;
+  
+  int npt = nbpoints;
+  double pas = M_PI*2./(npt-1);
+  evx.SetSize(npt+1);
+  evy.SetSize(npt+1);
+  for(int i=0; i<=npt; i++) {
+    double t = i*pas;
+    double xr = a*cos(t);
+    double yr = b*sin(t);
+    double ar = atan2(yr, xr);
+    double r = sqrt(xr*xr+yr*yr);
+    evx(i) = r*cos(ar+tet);
+    evy(i) = r*sin(ar+tet);
+  }
+  return;
+}
+
+//---------------------------------------------------------------------------
+//--- Classe sopiamoduleExecutor
+//---------------------------------------------------------------------------
+/* --Methode-- */
+sopiamoduleExecutor::sopiamoduleExecutor()
+{
+
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+string kw,usage;
+// ------------- Help group FFT 
+string hgrp = "FFT";
+
+kw = "fftforw";
+usage = "FFT on a vector -> computes forward Fourier transform";
+usage += "\n Usage: fftforw vecSig vecSpec [graphic_att] ";
+usage += "\n vecSpec = FFTForward(vecSig) ";
+usage += "\n vecSig: Input data vector of type r_8 or complex<r_8> ";
+usage += "\n vecSpec: Output data vector of type complex<r_8> ";
+usage += "\n See also : fftback fftfilter fftfuncfilter ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "fftback";
+usage = "FFT on a vector -> computes backward Fourier transform ";
+usage += "\n Usage: fftback vecSpec vecSig [graphic_att] [C/Z] ";
+usage += "\n vecSig = FFTBackward(vecSpec) ";
+usage += "\n vecSpec: Input data vector of type complex<r_8> ";
+usage += "\n vecSig:  Output Data vector of type r_8 (default) ";
+usage += "\n    or complex<r_8> if C/Z specified or ";
+usage += "\n    vecSpec computed by fftforw on a complex vector";
+usage += "\n See also : fftforw fftfilter fftfuncfilter ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "fftfilter";
+usage = "Filter (multiply) vecSpec (vector complex<r_8>) by Filter (vector<r_8>)";
+usage += "\n Usage: fftfilter vecSpec FilterVec vecFiltSpec [graphic_att] ";
+usage += "\n   vecFiltSpec(i) = vecSpec(i) * complex(FilterVec(i),0) ";
+usage += "\n See also : fftforw fftbackw fftfuncfilter ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "fftfuncfilter";
+usage = "Filter (multiply) vecSpec (vector complex<r_8>) by FilterFunc(i) ";
+usage += "\n Usage: fftfilter vecSpec FilterFunc vecFiltSpec [graphic_att] ";
+usage += "\n   vecFiltSpec(i) = vecSpec(i) * complex(FilterFunc(i),0) ";
+usage += "\n See also : fftforw fftbackw fftfilter ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+//--------------------------
+hgrp = "SophyaCmd";
+
+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);
+
+kw = "setprjmoldefval";
+usage = "Set default value for Molleweide projection of spherical maps (outside maps)";
+usage += "\n Usage: setprjmoldefval OutOfMapValue ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+//--- Trace d'ellipse d'erreur
+hgrp = "SophyaCmd";
+kw = "errorellipse";
+usage = " Error ellipse plotter \n";
+usage += "Usage: errellipse [-fill] xc yc sx2 sy2 cov [scale=1] [gr_opt] [npt=128] \n"; 
+usage = "   Adds an error ellipse, specified by its center (xc,yc) \n";
+usage += "  and error matrix (covariance) parameters  SigX^2,SigY^2,Covar \n" ;
+usage += "  A global scaling parameters scale , graphic attributes and \n";
+usage += "   nomber of points can optionnaly be specified\n";
+usage += "  if the -fill flag specified, plots a filled ellipse \n" ;
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+}
+
+/* --Methode-- */
+sopiamoduleExecutor::~sopiamoduleExecutor()
+{
+}
+
+/* --Methode-- */
+int sopiamoduleExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+
+if (kw == "powerspec" || kw == "fftforw") {
+  if (tokens.size() < 2) {
+    cout << "Usage: fftforw vecSig vecSpec [graphic_att] " << endl;
+    return(0);
+    }
+  if (tokens.size() < 3)  tokens.push_back((string)"");
+  SophyaFFT_forw(tokens[0], tokens[1], tokens[2]);
+}
+else if (kw == "fftback") {
+  if (tokens.size() < 2) {
+    cout << "Usage: fftback vecSpec vecSig [graphic_att] [C/Z]" << endl;
+    return(0);
+    }
+  bool forcez8 = false;
+  if (tokens.size() > 3) {
+    char fcz8 = tolower(tokens[3][0]);
+    if ( (fcz8 == 'c') || (fcz8 == 'z') ) forcez8 = true;
+  }
+  if (tokens.size() < 3)  tokens.push_back((string)"");
+  SophyaFFT_back(tokens[0], tokens[1], tokens[2], forcez8);
+}
+else if ( (kw == "fftfilter") || (kw == "fftfuncfilter") ) {
+  if (tokens.size() < 3) {
+    cout << "Usage: fftfilter/fftfuncfilter vecSpec Filter vecFiltSpec [graphic_att]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 4)  tokens.push_back((string)"");
+  bool fgvec = false;
+  if (kw == "fftfilter") fgvec = true; 
+  SophyaFFT_filter(tokens[0], tokens[1], tokens[2], tokens[3], fgvec);
+}
+
+else if (kw == "prjmoldefval") {
+  if (tokens.size() < 1) {
+    cout << "Usage: prjmoldefval OutOfMapValue" << endl;
+    return(0);
+    }
+  Set_Project_Mol_DefVal(atof(tokens[0].c_str()) );
+}
+// Grille de coordonnees en projection molleweide
+else if (kw == "mollgrid") {
+   NamedObjMgr omg;
+   MollweideGridDrawer * mollgrid = NULL;
+   string dopt="";
+   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, 360., 180., 180., 0.);
+   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); 
+}
+// Trace d'ellipse d'erreur 
+else if (kw == "errorellipse") {
+  if ((tokens.size()<5) || ((tokens.size()>0)&&(tokens[0]=="-fill")&&(tokens.size()<6))) {
+    cout << "Usage: errorellipse [-fill] xc yc sx2 sy2 cov [scale=1 gropt npt=128]" << endl;
+    return(1);
+  }
+  bool fgfill = false;
+  unsigned int offtok = 0;
+  if (tokens[0] == "-fill") {
+    offtok = 1;  fgfill = true;
+  }
+  double xc = atof(tokens[0+offtok].c_str());
+  double yc = atof(tokens[1+offtok].c_str());
+  double sx = atof(tokens[2+offtok].c_str());
+  double sy = atof(tokens[3+offtok].c_str());
+  double cov = atof(tokens[4+offtok].c_str());
+  double scale = 1.;
+  if (tokens.size() > (5+offtok)) scale = atof(tokens[5+offtok].c_str());
+  string gropt;
+  if (tokens.size() > (6+offtok)) gropt = tokens[6+offtok];
+  int npt = 128;
+  if (tokens.size() > (7+offtok)) npt = atoi(tokens[7+offtok].c_str());
+
+  double a,b,tet,phi;
+  diag_ellipse(sx, sy, cov, a, b, tet, phi, 1);
+  Vector evx, evy;
+  ellipse2vec(a,b,tet,evx, evy, scale, npt+1);
+  vector<double> vx, vy;
+  for(int k=0; k<evx.Size(); k++) {
+    vx.push_back(evx(k)+xc);
+    vy.push_back(evy(k)+yc);
+  }
+  NamedObjMgr omg;
+  omg.GetImgApp()->AddPoly(vx, vy, gropt, fgfill, false);
+}
+
+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;
+}
+
+
+/*  Nouvelle-Fonction */
+void SophyaFFT_forw(string& nom, string& nomout, string dopt)
+{
+//Timer tm("powerspec");
+NamedObjMgr omg;
+AnyDataObj* obj=omg.GetObj(nom);
+if (obj == NULL) {
+  cout<<"SophyaFFT_forw() Error , Pas d'objet de nom "<<nom<<endl;
+  return;
+}
+
+TVector<r_8>* vin = dynamic_cast<TVector<r_8> *>(obj);
+TVector< complex<r_8> >* vinc = dynamic_cast<TVector< complex<r_8> >*>(obj);
+if (vin == NULL && vinc == NULL) {
+  cout<<"SophyaFFT_forw() Error , Objet n'est pas un vecteur r_8 ou complex<r_8>"<<endl;
+  return;
+}
+TVector< complex<r_8> > * vout = new TVector< complex<r_8> >  ;
+FFTPackServer ffts;
+if(vin!=NULL) {
+  cout<<"SophyaFFT_forw() - Computing FFT of TVector<r_8> of size "<<vin->NElts()<< endl;
+  ffts.FFTForward(*vin, *vout);
+  cout<<"...Output TVector<complex<r_8>> of size: "<<vout->NElts()<<endl;
+  vout->Info()["FFTTYPE"]="F:R8->Z8";
+} else {
+  cout<<"SophyaFFT_forw() - Computing FFT of vector TVector<complex<r_8>> of size "<<vinc->NElts()<< endl;
+  ffts.FFTForward(*vinc, *vout);
+  cout<<"...Output TVector<complex<r_8>> of size: "<<vout->NElts()<<endl;
+  vout->Info()["FFTTYPE"] = "F:Z8->Z8";
+}
+// cout << " SophyaFFT - FFT done " << endl;
+ // tm.Split(" FFT done ");
+
+omg.AddObj(vout, nomout);
+omg.DisplayObj(nomout, dopt);
+return;
+
+}
+
+
+/*  Nouvelle-Fonction */
+void SophyaFFT_back(string& nom, string& nomout, string dopt, bool forcez8)
+{
+  //Timer tm("powerspec");
+NamedObjMgr omg;
+AnyDataObj* obj=omg.GetObj(nom);
+if (obj == NULL) {
+  cout << "SophyaFFT_back() Error , Pas d'objet de nom " << nom << endl;
+  return;
+}
+
+TVector< complex<r_8> >* vinc = dynamic_cast<TVector< complex<r_8> >*>(obj);
+if (vinc == NULL) {
+  cout << "SophyaFFT_back() Error , Objet n'est pas un vecteur complex<r_8>" <<  endl;
+  return;
+  }
+
+TVector< r_8 > * vout = NULL;
+TVector< complex<r_8> > * voutc = NULL;
+
+if (forcez8 || (vinc->Info().GetS("FFTTYPE") == "F:Z8->Z8") ) {
+  voutc = new TVector< complex<r_8> >;
+} 
+else {
+  vout = new TVector< r_8 >;
+}
+
+FFTPackServer ffts;
+cout << "SophyaFFT_back() - Computing Backward FFT of vector size " << vinc->NElts() << endl;
+if(vout!=NULL) {
+  ffts.FFTBackward(*vinc, *vout);
+  cout<<"...Output TVector<r_8> of size: "<<vout->NElts()<<endl;
+  vout->Info()["FFTTYPE"]="B:Z8->R8";
+  omg.AddObj(vout, nomout);
+} else {
+  ffts.FFTBackward(*vinc, *voutc);
+  cout<<"...Output TVector<complex<r_8>> of size: "<<voutc->NElts()<<endl;
+  voutc->Info()["FFTTYPE"]="B:Z8->Z8";
+  omg.AddObj(voutc, nomout);
+}
+
+omg.DisplayObj(nomout, dopt);
+return;
+}
+
+/*  Nouvelle-Fonction */
+void SophyaFFT_crefilter(string& nomvec, string& nomfilter, string func, string dopt)
+{
+NamedObjMgr omg;
+AnyDataObj* obj=omg.GetObj(nomvec);
+if(obj == NULL) {
+  cout<<"SophyaFFT_crefilter() Error , Pas d'objet de nom "<<nomvec<<endl;
+  return;
+}
+
+TVector< complex<r_8> >* vfft = dynamic_cast<TVector< complex<r_8> >*>(obj);
+if(vfft == NULL) {
+  cout<<"SophyaFFT_crefilter() Error , Objet "<<nomvec<<" n'est pas un Tvector<complex<r_8>>"<< endl;
+  return;
+}
+sa_size_t n = vfft->Size();
+if(n<=0) return;
+
+cout<<"Creating filter "<<nomfilter<<"("<<n<<") from vec "<<nomvec<<" with fun "<<func<<endl;
+omg.GetServiceObj()->PlotFunc(func,nomfilter,0.,(double)n,n,dopt); 
+}
+
+/*  Nouvelle-Fonction */
+void SophyaFFT_filter(string& nom, string& filt, string& outvec, string dopt, bool fgvec)
+{
+NamedObjMgr omg;
+AnyDataObj* obj=omg.GetObj(nom);
+if(obj == NULL) {
+  cout<<"SophyaFFT_filter() Error , Pas d'objet de nom "<<nom<<endl;
+  return;
+}
+TVector< complex<r_8> >* vfft = dynamic_cast<TVector< complex<r_8> >*>(obj);
+if(vfft == NULL) {
+  cout<<"SophyaFFT_filter() Error , Objet "<<nom<<" n'est pas un Tvector<complex<r_8>>"<< endl;
+  return;
+}
+int n = vfft->Size();
+if(n<=0) {
+  cout<<"SophyaFFT_filter() Error , vector size = 0 " << endl;
+  return;
+}
+
+string nomfilter = "/autoc/fft_filter";
+if (fgvec) {
+  nomfilter = filt; 
+  cout<<"SophyaFFT_filter(): using vector " << filt << " for filtering spectrum ..." << endl;   
+}
+else {
+  cout<<"SophyaFFT_filter(): Creating filter vector "<<nomfilter
+      <<" from function " << filt << endl; 
+  string fcrdopt = "nodisp";
+  omg.GetServiceObj()->PlotFunc(filt, nomfilter, 0., (double)n, n, fcrdopt); 
+}
+AnyDataObj* objfilter=omg.GetObj(nomfilter);
+if(objfilter == NULL) {
+  cout<<"SophyaFFT_filter() Error , Pas d'objet de nom "<<nomfilter<<endl;
+  return;
+}
+
+TVector<r_8>* vfilter = dynamic_cast<TVector<r_8>*>(objfilter);
+if(vfft == NULL) {
+  cout<<"SophyaFFT_filter() Error , Objet "<<nomfilter<<" n'est pas un Tvector<r_8>"<<endl;
+  return;
+}
+
+n = (vfilter->Size()<vfft->Size()) ? vfilter->Size(): vfft->Size();
+
+cout<<" SophyaFFT_filter(): filtering from 0 to "<<n<<endl;
+TVector< complex<r_8> > * filtfft = new TVector< complex<r_8> >(*vfft, false);
+for(int i=0;i<n;i++) (*filtfft)(i) *= (*vfilter)(i);
+
+cout<<"SophyaFFT_filter(): Adding obj: " << outvec << endl;   
+omg.AddObj(filtfft, outvec);
+omg.DisplayObj(outvec, dopt);
+return;
+}
Index: /tags/V_Nov2007/SophyaPI/ProgPI/usedlibs
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/usedlibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/usedlibs	(revision 3445)
@@ -0,0 +1,9 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+FitsIOServer
+PI
+PIext
Index: /tags/V_Nov2007/SophyaPI/ProgPI/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/usedslibs	(revision 3445)
@@ -0,0 +1,3 @@
+PI
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaPI/ProgPI/w2ps.cc
===================================================================
--- /tags/V_Nov2007/SophyaPI/ProgPI/w2ps.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaPI/ProgPI/w2ps.cc	(revision 3445)
@@ -0,0 +1,218 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#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);
+  }
+  sapp->CkEvt_LockMutex();
+  if (sapp->CurrentWindow() == NULL) {
+    sapp->UnlockMutex(); 
+    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) {
+      sapp->UnlockMutex();
+      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;
+  }
+  sapp->UnlockMutex();
+}
+else if ( (kw == "imagcmap2ps") || (kw == "imagcmap2eps") ) {
+  PIStdImgApp*  sapp = omg.GetImgApp();
+  if (sapp == NULL) {
+    cout << " W2PSModuleExecutor::Execute() No PIStdImgApp !" << endl;
+    return(0);
+  }
+  PIImage* curpimg = NULL;
+  sapp->CkEvt_LockMutex();
+  if (sapp->CurrentBaseWdg()) 
+    curpimg = dynamic_cast<PIImage *>(sapp->CurrentBaseWdg());
+  if (curpimg == NULL) {
+    sapp->UnlockMutex();
+    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) {
+      sapp->UnlockMutex();
+      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.);
+
+  sapp->UnlockMutex();
+  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_Nov2007/SophyaProg/Examples/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/Makefile	(revision 3445)
@@ -0,0 +1,16 @@
+#  ------------------ SOPHYA -------------------------
+#    Makefile for compiling and linking C++ programs 
+#    with SOPHYA
+#  The SOPHYABASE environment variable should be defined  
+
+include $(SOPHYABASE)/include/sophyamake.inc
+
+all : ex1
+
+clean : 
+	rm ex1.o ex1
+
+ex1 : ex1.o 
+	$(CXXLINK) -o ex1 ex1.o $(SOPHYASLBLIST)
+ex1.o : ex1.cc
+	$(CXXCOMPILE) -c -o ex1.o ex1.cc
Index: /tags/V_Nov2007/SophyaProg/Examples/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/Makefile.mgr	(revision 3445)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYADEVREP)/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_Nov2007/SophyaProg/Examples/MyPPF/README
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/MyPPF/README	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/MyPPF/README	(revision 3445)
@@ -0,0 +1,77 @@
+Example to illustrate how to make a class persistent
+using SOPHYA PPF services 
+-----------------------------------------------
+   (C) LAL-IN2P3/CNRS   (C) DAPNIA-SPP/CEA 
+               R. Ansari , 2007 
+-----------------------------------------------
+
+0/ Content : 
+   - vfs.h : Declaration of the Vfs class Vfs . This is the class 
+             which we want to make persistent using SOPHYA PPF services
+   - vfs.cc : the Vfs class implementation AND its PPF handler ObjFileIO<Vfs>
+   - tvfs.cc : the test main program
+   - makefile : compiles tvfs.cc and vfs.cc and links them to build tvfs
+
+
+1/ The class should inherit from the SOPHYA::AnyDataObj class. 
+   In the example here, we want to make the class Vfs persistent
+class Vfs : public SOPHYA::AnyDataObj {
+ ... 
+}
+
+2/ A PPF handler should be implemented . The PPF handler class 
+should inherit from SOPHYA::PPersist . The pure virtual methods 
+of PPersist class (DataObj() , SetDataObj() , ReadSelf(), WriteSelf()
+has to be implemented. 
+
+class PPFHandlerVfs : public SOPHYA::PPersist {
+public:
+  virtual SOPHYA::AnyDataObj* DataObj();
+  virtual void       SetDataObj(SOPHYA::AnyDataObj &);
+protected: 
+  virtual void       ReadSelf(SOPHYA::PInPersist&);
+  virtual void       WriteSelf(SOPHYA::POutPersist&) const;
+}
+
+
+It is possible to use the template class SOPHYA::ObjFileIO<T>, and 
+specialize it for the tharget class (here SOPHYA::ObjFileIO<Vfs>), 
+by defining the two methods :
+  SOPHYA::ObjFileIO<Vfs>::ReadSelf(SOPHYA::PInPersist&)
+  SOPHYA::ObjFileIO<Vfs>::WriteSelf(SOPHYA::POutPersist&) const
+
+3/ If it is NOT possible to have the target class inherit from AnyDataObj, 
+a wrapper class should be used. The same class can play the role of wrapper
+AND the PPF handler. 
+  (See the PPF handler / wrapper class for STL vectors :
+   SOPHYA::PPFWrapperSTLVector<T> in file BaseTools/ppfwrapstlv.h )
+
+
+4/ Implement the ReadSelf() and WriteSelf() methods of the PPF handler.
+All the I/O services from the following classes can be used : 
+  - PPFBinaryIOStrem , PPFBinaryInputStream , PInPersist
+  - PPFBinaryIOStrem , PPFBinaryOutputStream , POutPersist
+Writing and reading of the embeded objects for which a handler has been registered 
+can simply be performed by : 
+  POutPersist::PutObject()   PInPersist::GetObject()
+
+==> The services associated with nametags (PPFBinaryOutputStream::WriteNameTag() 
+    PPFBinaryInputStream::GotoNameTag() ... ) are NOT intented to be used in 
+    WriteSelf() , ReadSelf()
+
+
+5/ The new PPF handler, as well as the list of classes it can handle has to be
+registered prior to use PPF read/write for the target classes. This must be 
+performed during the initialization phase, for example at the beginning of the 
+main() program. Another possibility is to use a module initializer 
+(See SophyaInitiator class in file BaseTools/sophyainit.h ) 
+and declare a static instance of the class (Note that this works only if 
+the system loader handles correcly the call of constructor 
+for the statically declared objects)
+
+The registration can be performed using the CPP macros defined in BaseTools/ppersist.h
+
+  // First, register the PPF handler ObjFileIO<Vfs> 
+  PPRegister(ObjFileIO<Vfs>);
+  // Register the list of classes which can be handled by ObjFileIO<Vfs> 
+  DObjRegister(ObjFileIO<Vfs>, Vfs);
Index: /tags/V_Nov2007/SophyaProg/Examples/MyPPF/makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/MyPPF/makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/MyPPF/makefile	(revision 3445)
@@ -0,0 +1,18 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+all : tvfs
+
+clean :
+	rm -f tvfs tvfs.o vfs.o tvfs.ppf
+
+
+tvfs : tvfs.o vfs.o
+	$(CXXLINK) -o tvfs tvfs.o vfs.o $(SOPHYASLBLIST)
+
+tvfs.o : tvfs.cc
+	$(CXXCOMPILE) -o tvfs.o tvfs.cc
+
+vfs.o : vfs.cc
+	$(CXXCOMPILE) -o vfs.o vfs.cc
+
+
Index: /tags/V_Nov2007/SophyaProg/Examples/MyPPF/tvfs.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/MyPPF/tvfs.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/MyPPF/tvfs.cc	(revision 3445)
@@ -0,0 +1,70 @@
+#include "machdefs.h"
+
+#include <iostream>
+
+#include "pexceptions.h"
+#include "vfs.h"
+
+//------------------------------------------------------
+// An example to illustrate how to make a class 
+//  persistent using the SOPHYA PPF services
+// (C) LAL-IN2P3/CNRS   (C) DAPNIA-SPP/CEA 
+// ----------------------------------------------------
+
+using namespace SOPHYA;   
+
+//--- The main program ----
+
+int main(int narg, char* arg[])
+{
+  
+  cout << " --------- tvfs.cc  test of class Vfs and ObjFileIO<Vfs>  ---------- "
+       << endl;
+  
+  // We have to register the PPersist handler for our class Vfs
+  // This should be performed at initialization
+  // The following two lines (CPP macros) do the job :
+
+  // First, register the PPF handler ObjFileIO<Vfs> 
+  PPRegister(ObjFileIO<Vfs>);
+  // Register the list of classes which can be handled by ObjFileIO<Vfs> 
+  DObjRegister(ObjFileIO<Vfs>, Vfs);
+
+
+  try {
+    Vfs xa(5);
+    xa.Set(0, 0., "Zero");
+    xa.Set(1, 1., "Un");
+    xa.Set(2, 2., "Deux");
+    xa.Set(3, 3., "Trois");
+    xa.Set(4, 4., "Quatre");
+    cout << xa ;
+    {
+    // We save our objet ito a POutPersist flow
+      POutPersist po("tvfs.ppf");
+      po << xa;
+    }
+    {
+    // We try to read in the saved Vfs xa object
+      Vfs xb;
+      cout << " Vfs xb before reading : \n " << xb << endl;
+      PInPersist pi("tvfs.ppf");
+      pi >> xb;
+      cout << " After reading pi >> xb : \n " << xb << endl;
+    }
+    
+  }
+
+  catch (PThrowable & pex) {
+    cerr << " tvfs.cc/Error - Exception catched " << (string)typeid(pex).name()
+	 << " - Msg= " << pex.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " tx.cc/Error - Exception (...) catched " << endl;
+    }
+      
+  cout << " ----------- End of tx.cc  ------------- " << endl;
+
+  return(0);
+ 
+}
Index: /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.cc	(revision 3445)
@@ -0,0 +1,95 @@
+#include "vfs.h"
+#include "pexceptions.h"
+#include "fiondblock.h"  // To use NDataBlock PPF services
+
+/* Vfs class constructor */
+Vfs::Vfs(int sz) 
+    : mFVal(sz)
+{
+  for(int k=0; k<sz; k++)
+    mSVal.push_back("");
+}
+
+void Vfs::Set(int k, r_4 fv, string const  sv)
+{
+  if ((k < 0) || (k>= (int)mFVal.Size())) 
+    throw SOPHYA::RangeCheckError("Vfs::Set() Out of range index!");
+  mFVal(k) = fv;
+  mSVal[k] = sv;  
+}
+
+r_4 Vfs::GetF(int k)
+{
+  if ((k < 0) || (k>= (int)mFVal.Size())) 
+    throw SOPHYA::RangeCheckError("Vfs::GetF() Out of range index!");
+  return mFVal(k);
+}
+
+string Vfs::GetS(int k)
+{
+  if ((k < 0) || (k>= (int)mFVal.Size())) 
+    throw SOPHYA::RangeCheckError("Vfs::GetS() Out of range index!");
+  return mSVal[k];
+}
+
+void Vfs::Print(ostream& os) const
+{
+  os << "Vfs::Print() - Size= " << mFVal.Size() << endl;
+  for(int k=0; k<(int)mFVal.Size(); k++)
+    os << "K=" << k << " FVal= " << mFVal(k) << " SVal=" << mSVal[k] << endl;
+  os << endl;  
+}
+
+//-----------------------------------------------------------------------
+//  The PPF handler : ObjFileIO<T> is in namespace SOPHYA , 
+//  We declare ObjFileIO<Vfs> in the SOPHYA namespace ...
+//  Only, the WriteSelf() and ReadSelf() methods have to be provided
+//-----------------------------------------------------------------------
+
+namespace SOPHYA {
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<Vfs>::WriteSelf(POutPersist& s) const
+{
+//  On ecrit 2 uint_4 .... 
+//  0: Numero de version,  2 : reserve
+  uint_4 itab[2];
+  itab[0] = 1;  // Numero de version a 1
+  itab[1] = 0;  // Reserved for future use
+  s.Put(itab, 2); 
+  s << dobj->mFVal;  // We write the float data block 
+// We write now the string vector , as a series of strings 
+  for(int k=0; k<(int)dobj->mFVal.Size(); k++)
+      s.PutStr(dobj->mSVal[k]);
+}
+
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void ObjFileIO<Vfs>::ReadSelf(PInPersist& s)
+{
+// We read in the same order as the write
+    // First the two integer containing the version numer
+  uint_4 itab[2];
+  s.Get(itab, 2); 
+// next, we read in the float data vector 
+  s >> dobj->mFVal;  
+// We resest the  vector<string> dobj->mSVal
+  dobj->mSVal.clear();
+// We read in the mFVal.Size() and keep them in dobj->mSVal
+  string buff; 
+  for(int k=0; k<(int)dobj->mFVal.Size(); k++) {
+    s.GetStr(buff);  
+    dobj->mSVal.push_back(buff);
+  }  
+}
+
+// We force the instanciation of the template class ObjFileIO<Vfs>
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Vfs>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Vfs>;
+#endif
+
+} // End of namespace SOPHYA 
+
Index: /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.h
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/MyPPF/vfs.h	(revision 3445)
@@ -0,0 +1,58 @@
+#ifndef VFS_H_SEEN
+#define VFS_H_SEEN
+
+#include "machdefs.h"
+
+#include <string>
+#include <vector>
+
+#include "ndatablock.h"
+#include "objfio.h"
+
+//------------------------------------------------------
+// An example to illustrate how to make a class 
+//  persistent using the SOPHYA PPF services
+// (C) LAL-IN2P3/CNRS   (C) DAPNIA-SPP/CEA 
+// ----------------------------------------------------
+
+// A simple class to hold pairs(float, string)
+// we want to make this class persistent using SOPHYA PPF services
+
+class Vfs : public SOPHYA::AnyDataObj {
+public:
+// We need a default constructor , if we want to use the ObjFileIO<Vfs> class
+            Vfs(int sz=10);
+  virtual   ~Vfs() { };
+
+// Setting element k
+  void      Set(int k, r_4 fv, string const sv);
+// Accessing float part of element k
+  r_4       GetF(int k);
+// Accessing string part of element k
+  string    GetS(int k);
+// display/print object content
+  void      Print(ostream& os) const ; 
+//  For persistence handling
+  friend class SOPHYA::ObjFileIO<Vfs> ;
+ private:
+	  SOPHYA::NDataBlock<r_4> mFVal;
+	  vector<string> mSVal;	  	  
+};
+
+// For easy printing of Vfs through cout << x ;
+inline ostream& operator << (ostream& s, Vfs const & x)
+  {  x.Print(s);  return(s);  }
+
+/* Writes the object in the POutPersist stream  os */
+inline SOPHYA::POutPersist& operator << (SOPHYA::POutPersist& os, Vfs & obj)
+{ SOPHYA::ObjFileIO<Vfs> fio(&obj);  fio.Write(os);  return(os); }
+/* Reads the object from the PInPersist stream  is */
+inline SOPHYA::PInPersist& operator >> (SOPHYA::PInPersist& is, Vfs & obj)
+{ SOPHYA::ObjFileIO<Vfs> fio(&obj);  fio.Read(is);  return(is); }
+
+
+#endif
+
+
+
+
Index: /tags/V_Nov2007/SophyaProg/Examples/README
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/README	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/README	(revision 3445)
@@ -0,0 +1,50 @@
+#   Programmes exemple pour l'utilisation de Sophya
+
+
+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.h
+   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
+
+7) Repertoire MyPPF/
+   Exemple de gestionnaire (handler) PPersist
Index: /tags/V_Nov2007/SophyaProg/Examples/apc.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/apc.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/apc.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/apcxx.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/apcxx.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/apcxx.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/apcxx_cstyle.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/apcxx_cstyle.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/apcxx_cstyle.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/arr1.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/arr1.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/arr1.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/arrrd.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/arrrd.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/arrrd.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/arrwrt.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/arrwrt.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/arrwrt.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/auto_makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/auto_makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/auto_makefile	(revision 3445)
@@ -0,0 +1,30 @@
+#  ------------------ SOPHYA -------------------------
+#    Makefile for 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 
+
+
+include $(SOPHYABASE)/include/sophyamake.inc
+
+
+
+%:%.cc
+%:%.o
+%.o:%.cc
+
+.PRECIOUS: % %.o
+
+
+#  --- Compilation and linking rules
+%:%.o
+	$(CXXLINK)  -o $@ $< $(SOPHYAEXTSLBLIST)
+
+%.o:%.cc
+	$(CXXCOMPILE) -c -o $@ $<
+
+
Index: /tags/V_Nov2007/SophyaProg/Examples/cksphylm.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/cksphylm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/cksphylm.cc	(revision 3445)
@@ -0,0 +1,40 @@
+#define TC r_8
+
+int lmax = 255;
+int l0 = 140;
+TVector< TC > clin(lmax+1);
+for(int l=0; l<lmax; l++) {
+  double xx = (l-l0)/10.;
+  clin(l) = 3.e-2 -1.e-4*l + 0.1*exp(-xx*xx);
+}
+
+KeepObj(clin);
+// Compute map from spectra
+SphericalTransformServer< TC > ylmserver;
+int mtp = 200;  // Pixelisation theta-phi
+SphereThetaPhi< TC > map(mtp);
+PrtTim("-->Appel GenerateFromCl");
+ylmserver.GenerateFromCl(map, mtp,  clin, 0.);
+
+KeepObj(map);
+
+Alm< TC > alm;
+PrtTim("-->Appel DecomposeToAlm");
+ylmserver.DecomposeToAlm(map, alm,  lmax, 0., 0);
+
+cout << alm ; 
+
+TVector< TC > clfalm = alm.powerSpectrum();
+
+KeepObj(clfalm);
+PrtTim("-->Appel DecomposeToCl");
+Vector clfm = ylmserver.DecomposeToCl(map, lmax,  0.);
+KeepObj(clfm);
+
+SphereThetaPhi< TC > map2(mtp);
+PrtTim("-->Appel GenerateFromAlm");
+ylmserver.GenerateFromAlm(map2, mtp, alm);
+KeepObj(map2); 
+PrtTim("-->Calcul mapdiff");
+SphereThetaPhi< TC > mapdiff = map-map2;
+KeepObj(mapdiff);
Index: /tags/V_Nov2007/SophyaProg/Examples/cksphylm.pic
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/cksphylm.pic	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/cksphylm.pic	(revision 3445)
@@ -0,0 +1,73 @@
+### Script pour comparer et verifier la nouvelle version de calcul
+## des transforme en Ylm (optimise ds LambdaLMBuilder) et l'ancienne
+##  Reza, Mai 2006
+
+traceon
+timingon
+#  Creation d'une carte a partir d'un c(l) et calcul transforme inverse
+#  Choix de type de cartes -> ThetaPhi
+settypemap T
+LMAX = 511
+# lmax+1
+CLSIZE = $LMAX+1
+# Param. pixelisation Theta,Phi 
+M_TP = 400
+# Une courbe de C(l)
+newvec vcl $CLSIZE 1./(x+10.)*(1+sin(x*M_PI/50)) 
+# SynFast : C(l) -> map 
+cl2map vcl map $M_TP
+# AnaFast : map -> alm
+echo "---> map2alm map mtxalm $LMAX 1"
+map2alm map mtxalm $LMAX 1
+echo "---> alm2map mtxalm mapfalm $M_TP"
+alm2map mtxalm mapfalm $M_TP
+print map 
+disp map
+
+#  On sauve la carte et alm ds un fichier
+#  A faire sur la version de reference du programme/SOPHYA (ancien)
+savelist mapfalm mtxalm map vcl cksamba.ppf 
+
+###  VERIFICATION 
+delobjs *   
+# Lecture du fichier cree ci-dessus (avec la version de reference)
+openppf cksamba.ppf 
+#  Choix de type de cartes -> ThetaPhi 
+settypemap T
+#  Fabrication carte a partir des alm du fichier
+echo "---> alm2map mtxalm mapfalm2 $M_TP"
+alm2map mtxalm mapfalm2 $M_TP
+print map 
+print mapfalm2 
+#  Calcul des alm sur la carte du fichier
+map2alm map mtxalm2 $LMAX 1
+
+#  Ce bout de code ne peut etre execute qu'avec les dernieres modifs du 2 juin 2006
+c++import Samba SkyMap
+c++exec \ 
+  TMatrix< complex<r_8> > diffalm = mtxalm-mtxalm2; \
+  KeepObj(diffalm); \
+  SphereThetaPhi<r_8> diffmap = mapfalm-mapfalm2; \
+  KeepObj(diffmap); 
+
+zone 1 2 
+disp diffmap 'lut=lin,-0.001,0.001'
+disp diffalm 'lut=lin,0.,0.05'
+
+expmeansig diffmap val
+expmeansig diffalm mod
+
+saveobjs * cksambaA.ppf 
+
+
+#### Pour verifier en version r_8 et r_4
+## Modifier le type dans le fichier cksphylm.cc
+c++import Samba SkyMap
+delobjs *
+c++execfrf cksphylm.cc 
+zone 1 
+disp clin
+disp clfm 'same red'
+sleep 4
+disp mapdiff
+expmeansig mapdiff val
Index: /tags/V_Nov2007/SophyaProg/Examples/ex1.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/ex1.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/ex1.cc	(revision 3445)
@@ -0,0 +1,78 @@
+#include "dvlist.h"
+#include "ndatablock.h"
+#include "fiondblock.h"
+#include "sophyainit.h"
+
+#include "sopnamsp.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_Nov2007/SophyaProg/Examples/ex_makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/ex_makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/ex_makefile	(revision 3445)
@@ -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 $(SOPHYABASEREP)/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_Nov2007/SophyaProg/Examples/fft.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/fft.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/fft.icc	(revision 3445)
@@ -0,0 +1,17 @@
+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); 
+DisplayObj(in, "");
+DisplayObj(out, "red");
+
+
+
+
Index: /tags/V_Nov2007/SophyaProg/Examples/myf_fft.h
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/myf_fft.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/myf_fft.h	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/sphylm.h
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/sphylm.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/sphylm.h	(revision 3445)
@@ -0,0 +1,2 @@
+#include "skymap.h"
+#include "samba.h"
Index: /tags/V_Nov2007/SophyaProg/Examples/sphylm.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/sphylm.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/sphylm.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/Examples/tvm.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Examples/tvm.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Examples/tvm.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/HowToUse
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/HowToUse	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/HowToUse	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/Makefile	(revision 3445)
@@ -0,0 +1,438 @@
+include ../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)skymixer $(SOPHYAEXEP)extractRS $(SOPHYAEXEP)tgrsr $(SOPHYAEXEP)tgsky $(SOPHYAEXEP)easyTest $(SOPHYAEXEP)Sph2Sph
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)Sph2Sph.o $(SOPHYAOBJP)easyTest.o $(SOPHYAOBJP)tgsky.o $(SOPHYAOBJP)tgrsr.o $(SOPHYAOBJP)extractRS.o $(SOPHYAOBJP)skymixer.o
+ 
+skymixer: $(SOPHYAEXEP)skymixer
+	echo $@ " done"
+$(SOPHYAEXEP)skymixer: $(SOPHYAOBJP)skymixer.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)skymixer.o $(SOPHYAEXTSLBLIST)
+ 
+extractRS: $(SOPHYAEXEP)extractRS
+	echo $@ " done"
+$(SOPHYAEXEP)extractRS: $(SOPHYAOBJP)extractRS.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extractRS.o $(SOPHYAEXTSLBLIST)
+ 
+tgrsr: $(SOPHYAEXEP)tgrsr
+	echo $@ " done"
+$(SOPHYAEXEP)tgrsr: $(SOPHYAOBJP)tgrsr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tgrsr.o $(SOPHYAEXTSLBLIST)
+ 
+tgsky: $(SOPHYAEXEP)tgsky
+	echo $@ " done"
+$(SOPHYAEXEP)tgsky: $(SOPHYAOBJP)tgsky.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tgsky.o $(SOPHYAEXTSLBLIST)
+ 
+easyTest: $(SOPHYAEXEP)easyTest
+	echo $@ " done"
+$(SOPHYAEXEP)easyTest: $(SOPHYAOBJP)easyTest.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)easyTest.o $(SOPHYAEXTSLBLIST)
+ 
+Sph2Sph: $(SOPHYAEXEP)Sph2Sph
+	echo $@ " done"
+$(SOPHYAEXEP)Sph2Sph: $(SOPHYAOBJP)Sph2Sph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)Sph2Sph.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)Sph2Sph.o: Sph2Sph.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  Sph2Sph.cc
+ 
+$(SOPHYAOBJP)easyTest.o: easyTest.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)trianglefilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  easyTest.cc
+ 
+$(SOPHYAOBJP)extractRS.o: extractRS.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extractRS.cc
+ 
+$(SOPHYAOBJP)skymixer.o: skymixer.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymixer.cc
+ 
+$(SOPHYAOBJP)tgrsr.o: tgrsr.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tgrsr.cc
+ 
+$(SOPHYAOBJP)tgsky.o: tgsky.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tgsky.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PMixer/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/RSextract.d
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/RSextract.d	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/RSextract.d	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/Sph2Sph.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/Sph2Sph.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/Sph2Sph.cc	(revision 3445)
@@ -0,0 +1,61 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/PMixer/easyTest.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/easyTest.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/easyTest.cc	(revision 3445)
@@ -0,0 +1,190 @@
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaProg/PMixer/extractRS.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/extractRS.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/extractRS.cc	(revision 3445)
@@ -0,0 +1,455 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/PMixer/howto.d
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/howto.d	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/howto.d	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/makefile_sunmpa
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/makefile_sunmpa	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/makefile_sunmpa	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/makeprog
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/makeprog	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/makeprog	(revision 3445)
@@ -0,0 +1,49 @@
+MODULECXXREPNAME := SkyT
+# MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYADEVREP)/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_Nov2007/SophyaProg/PMixer/pmixer.h
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/pmixer.h	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/pmixer.h	(revision 3445)
@@ -0,0 +1,37 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <fstream>
+#include <iostream>
+#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_Nov2007/SophyaProg/PMixer/programs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/programs	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/skm.d
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/skm.d	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/skm.d	(revision 3445)
@@ -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_Nov2007/SophyaProg/PMixer/skymixer.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/skymixer.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/skymixer.cc	(revision 3445)
@@ -0,0 +1,1070 @@
+#include "sopnamsp.h"
+#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((int)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((int)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_Nov2007/SophyaProg/PMixer/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/smakefile	(revision 3445)
@@ -0,0 +1,438 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)skymixer $(SOPHYAEXEP)extractRS $(SOPHYAEXEP)tgrsr $(SOPHYAEXEP)tgsky $(SOPHYAEXEP)easyTest $(SOPHYAEXEP)Sph2Sph
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)Sph2Sph.o $(SOPHYAOBJP)easyTest.o $(SOPHYAOBJP)tgsky.o $(SOPHYAOBJP)tgrsr.o $(SOPHYAOBJP)extractRS.o $(SOPHYAOBJP)skymixer.o
+ 
+skymixer: $(SOPHYAEXEP)skymixer
+	echo $@ " done"
+$(SOPHYAEXEP)skymixer: $(SOPHYAOBJP)skymixer.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)skymixer.o $(SOPHYAEXTSLBLIST)
+ 
+extractRS: $(SOPHYAEXEP)extractRS
+	echo $@ " done"
+$(SOPHYAEXEP)extractRS: $(SOPHYAOBJP)extractRS.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extractRS.o $(SOPHYAEXTSLBLIST)
+ 
+tgrsr: $(SOPHYAEXEP)tgrsr
+	echo $@ " done"
+$(SOPHYAEXEP)tgrsr: $(SOPHYAOBJP)tgrsr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tgrsr.o $(SOPHYAEXTSLBLIST)
+ 
+tgsky: $(SOPHYAEXEP)tgsky
+	echo $@ " done"
+$(SOPHYAEXEP)tgsky: $(SOPHYAOBJP)tgsky.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tgsky.o $(SOPHYAEXTSLBLIST)
+ 
+easyTest: $(SOPHYAEXEP)easyTest
+	echo $@ " done"
+$(SOPHYAEXEP)easyTest: $(SOPHYAOBJP)easyTest.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)easyTest.o $(SOPHYAEXTSLBLIST)
+ 
+Sph2Sph: $(SOPHYAEXEP)Sph2Sph
+	echo $@ " done"
+$(SOPHYAEXEP)Sph2Sph: $(SOPHYAOBJP)Sph2Sph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)Sph2Sph.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)Sph2Sph.o: Sph2Sph.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  Sph2Sph.cc
+ 
+$(SOPHYAOBJP)easyTest.o: easyTest.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)trianglefilt.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  easyTest.cc
+ 
+$(SOPHYAOBJP)extractRS.o: extractRS.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extractRS.cc
+ 
+$(SOPHYAOBJP)skymixer.o: skymixer.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  skymixer.cc
+ 
+$(SOPHYAOBJP)tgrsr.o: tgrsr.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tgrsr.cc
+ 
+$(SOPHYAOBJP)tgsky.o: tgsky.cc $(SOPHYAINCP)sopnamsp.h \
+  pmixer.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)datacards.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)radspecvector.h \
+  $(SOPHYAINCP)radspec.h \
+  $(SOPHYAINCP)specresp.h \
+  $(SOPHYAINCP)blackbody.h \
+  $(SOPHYAINCP)convtools.h \
+  $(SOPHYAINCP)derivblackbody.h \
+  $(SOPHYAINCP)nupower.h \
+  $(SOPHYAINCP)squarefilt.h \
+  $(SOPHYAINCP)trianglefilt.h \
+  $(SOPHYAINCP)specrespvector.h \
+  $(SOPHYAINCP)gaussfilt.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)mapoperation.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tgsky.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PMixer/tgrsr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/tgrsr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/tgrsr.cc	(revision 3445)
@@ -0,0 +1,169 @@
+#include <typeinfo>
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/PMixer/tgsky.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/tgsky.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/tgsky.cc	(revision 3445)
@@ -0,0 +1,137 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/PMixer/usedlibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/usedlibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/usedlibs	(revision 3445)
@@ -0,0 +1,6 @@
+SysTools
+NTools
+Samba
+SkyMap
+SkyT
+FitsIOServer
Index: /tags/V_Nov2007/SophyaProg/PMixer/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PMixer/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PMixer/usedslibs	(revision 3445)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaProg/PrgMap/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/Makefile	(revision 3445)
@@ -0,0 +1,429 @@
+include ../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)cl2map $(SOPHYAEXEP)map2cl $(SOPHYAEXEP)prjsmap $(SOPHYAEXEP)cremskfrsph $(SOPHYAEXEP)extrapsph $(SOPHYAEXEP)extrap2sph
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)extrap2sph.o $(SOPHYAOBJP)extrapsph.o $(SOPHYAOBJP)cremskfrsph.o $(SOPHYAOBJP)prjsmap.o $(SOPHYAOBJP)map2cl.o $(SOPHYAOBJP)cl2map.o
+ 
+cl2map: $(SOPHYAEXEP)cl2map
+	echo $@ " done"
+$(SOPHYAEXEP)cl2map: $(SOPHYAOBJP)cl2map.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)cl2map.o $(SOPHYAEXTSLBLIST)
+ 
+map2cl: $(SOPHYAEXEP)map2cl
+	echo $@ " done"
+$(SOPHYAEXEP)map2cl: $(SOPHYAOBJP)map2cl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)map2cl.o $(SOPHYAEXTSLBLIST)
+ 
+prjsmap: $(SOPHYAEXEP)prjsmap
+	echo $@ " done"
+$(SOPHYAEXEP)prjsmap: $(SOPHYAOBJP)prjsmap.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)prjsmap.o $(SOPHYAEXTSLBLIST)
+ 
+cremskfrsph: $(SOPHYAEXEP)cremskfrsph
+	echo $@ " done"
+$(SOPHYAEXEP)cremskfrsph: $(SOPHYAOBJP)cremskfrsph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)cremskfrsph.o $(SOPHYAEXTSLBLIST)
+ 
+extrapsph: $(SOPHYAEXEP)extrapsph
+	echo $@ " done"
+$(SOPHYAEXEP)extrapsph: $(SOPHYAOBJP)extrapsph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extrapsph.o $(SOPHYAEXTSLBLIST)
+ 
+extrap2sph: $(SOPHYAEXEP)extrap2sph
+	echo $@ " done"
+$(SOPHYAEXEP)extrap2sph: $(SOPHYAOBJP)extrap2sph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extrap2sph.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)cl2map.o: cl2map.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cl2map.cc
+ 
+$(SOPHYAOBJP)cremskfrsph.o: cremskfrsph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cremskfrsph.cc
+ 
+$(SOPHYAOBJP)extrap2sph.o: extrap2sph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extrap2sph.cc
+ 
+$(SOPHYAOBJP)extrapsph.o: extrapsph.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extrapsph.cc
+ 
+$(SOPHYAOBJP)map2cl.o: map2cl.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  map2cl.cc
+ 
+$(SOPHYAOBJP)prjsmap.o: prjsmap.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  prjsmap.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PrgMap/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaProg/PrgMap/cl2map.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/cl2map.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/cl2map.cc	(revision 3445)
@@ -0,0 +1,214 @@
+#include "sopnamsp.h"
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream>
+
+#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.
+  <UL>
+  <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 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_Nov2007/SophyaProg/PrgMap/cremskfrsph.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/cremskfrsph.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/cremskfrsph.cc	(revision 3445)
@@ -0,0 +1,147 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream>
+#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_Nov2007/SophyaProg/PrgMap/extrap2sph.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/extrap2sph.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/extrap2sph.cc	(revision 3445)
@@ -0,0 +1,196 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream>
+#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_Nov2007/SophyaProg/PrgMap/extrapsph.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/extrapsph.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/extrapsph.cc	(revision 3445)
@@ -0,0 +1,179 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream>
+#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_Nov2007/SophyaProg/PrgMap/map2cl.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/map2cl.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/map2cl.cc	(revision 3445)
@@ -0,0 +1,226 @@
+#include "sopnamsp.h"
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream>
+
+#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_Nov2007/SophyaProg/PrgMap/msksphere.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/msksphere.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/msksphere.cc	(revision 3445)
@@ -0,0 +1,141 @@
+// Creation d'une sphere de masquee a partir d'une sphere de masques
+//         cmv 15/6/01
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream>
+#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_Nov2007/SophyaProg/PrgMap/prjsmap.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/prjsmap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/prjsmap.cc	(revision 3445)
@@ -0,0 +1,341 @@
+#include "sopnamsp.h"
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream>
+
+#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_Nov2007/SophyaProg/PrgMap/programs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/programs	(revision 3445)
@@ -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_Nov2007/SophyaProg/PrgMap/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/smakefile	(revision 3445)
@@ -0,0 +1,429 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)cl2map $(SOPHYAEXEP)map2cl $(SOPHYAEXEP)prjsmap $(SOPHYAEXEP)cremskfrsph $(SOPHYAEXEP)extrapsph $(SOPHYAEXEP)extrap2sph
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)extrap2sph.o $(SOPHYAOBJP)extrapsph.o $(SOPHYAOBJP)cremskfrsph.o $(SOPHYAOBJP)prjsmap.o $(SOPHYAOBJP)map2cl.o $(SOPHYAOBJP)cl2map.o
+ 
+cl2map: $(SOPHYAEXEP)cl2map
+	echo $@ " done"
+$(SOPHYAEXEP)cl2map: $(SOPHYAOBJP)cl2map.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)cl2map.o $(SOPHYAEXTSLBLIST)
+ 
+map2cl: $(SOPHYAEXEP)map2cl
+	echo $@ " done"
+$(SOPHYAEXEP)map2cl: $(SOPHYAOBJP)map2cl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)map2cl.o $(SOPHYAEXTSLBLIST)
+ 
+prjsmap: $(SOPHYAEXEP)prjsmap
+	echo $@ " done"
+$(SOPHYAEXEP)prjsmap: $(SOPHYAOBJP)prjsmap.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)prjsmap.o $(SOPHYAEXTSLBLIST)
+ 
+cremskfrsph: $(SOPHYAEXEP)cremskfrsph
+	echo $@ " done"
+$(SOPHYAEXEP)cremskfrsph: $(SOPHYAOBJP)cremskfrsph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)cremskfrsph.o $(SOPHYAEXTSLBLIST)
+ 
+extrapsph: $(SOPHYAEXEP)extrapsph
+	echo $@ " done"
+$(SOPHYAEXEP)extrapsph: $(SOPHYAOBJP)extrapsph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extrapsph.o $(SOPHYAEXTSLBLIST)
+ 
+extrap2sph: $(SOPHYAEXEP)extrap2sph
+	echo $@ " done"
+$(SOPHYAEXEP)extrap2sph: $(SOPHYAOBJP)extrap2sph.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)extrap2sph.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)cl2map.o: cl2map.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cl2map.cc
+ 
+$(SOPHYAOBJP)cremskfrsph.o: cremskfrsph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cremskfrsph.cc
+ 
+$(SOPHYAOBJP)extrap2sph.o: extrap2sph.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extrap2sph.cc
+ 
+$(SOPHYAOBJP)extrapsph.o: extrapsph.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  extrapsph.cc
+ 
+$(SOPHYAOBJP)map2cl.o: map2cl.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  map2cl.cc
+ 
+$(SOPHYAOBJP)prjsmap.o: prjsmap.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitstarray.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  prjsmap.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PrgMap/usedlibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/usedlibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/usedlibs	(revision 3445)
@@ -0,0 +1,8 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+
+
Index: /tags/V_Nov2007/SophyaProg/PrgMap/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgMap/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgMap/usedslibs	(revision 3445)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile	(revision 3445)
@@ -0,0 +1,106 @@
+include ../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)runcxx $(SOPHYAEXEP)scanppf $(SOPHYAEXEP)scanfits
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)scanfits.o $(SOPHYAOBJP)scanppf.o $(SOPHYAOBJP)runcxx.o
+ 
+runcxx: $(SOPHYAEXEP)runcxx
+	echo $@ " done"
+$(SOPHYAEXEP)runcxx: $(SOPHYAOBJP)runcxx.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)runcxx.o $(SOPHYAEXTSLBLIST)
+ 
+scanppf: $(SOPHYAEXEP)scanppf
+	echo $@ " done"
+$(SOPHYAEXEP)scanppf: $(SOPHYAOBJP)scanppf.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)scanppf.o $(SOPHYAEXTSLBLIST)
+ 
+scanfits: $(SOPHYAEXEP)scanfits
+	echo $@ " done"
+$(SOPHYAEXEP)scanfits: $(SOPHYAOBJP)scanfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)scanfits.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)runcxx.o: runcxx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)cxxcmplnk.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  runcxx.cc
+ 
+$(SOPHYAOBJP)scanfits.o: scanfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scanfits.cc
+ 
+$(SOPHYAOBJP)scanppf.o: scanppf.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)histinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scanppf.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/Makefile.mgr	(revision 3445)
@@ -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_Nov2007/SophyaProg/PrgUtil/programs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/programs	(revision 3445)
@@ -0,0 +1,3 @@
+runcxx runcxx.o
+scanppf scanppf.o
+scanfits scanfits.o
Index: /tags/V_Nov2007/SophyaProg/PrgUtil/runcxx.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/runcxx.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/runcxx.cc	(revision 3445)
@@ -0,0 +1,331 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+#include <string>
+#include <vector>
+
+#include <typeinfo>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "sambainit.h"
+#include "skyinit.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
+  PIOPersist::Initialize() Starting Sophya Persistence management service
+  SOPHYA Version  1.6 Revision 6 (V_Mai2003) -- Jun 25 2003 12:01:04 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, XAstroPack
+  \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, \n"
+       << "                LinAlg, IFFTW, XAstroPack \n"
+       << endl;
+
+  exit(0);
+}
+
+
+
+/* --Main-- */
+int main(int narg, char *arg[])
+{
+  //SambaInitiator smbinit;
+
+  SophyaInit();
+  InitTim();
+
+  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") == 0)  inc1.push_back("skymap.h");
+      else if (strcmp(arg[k], "Samba") == 0)  inc1.push_back("samba.h");
+      else if (strcmp(arg[k], "SkyT") == 0)  inc1.push_back("skyt.h");
+      else if (strcmp(arg[k], "FitsIOServer") == 0)  inc1.push_back("fitsioserver.h");
+      else if (strcmp(arg[k], "LinAlg") == 0 )  inc1.push_back("intflapack.h");
+      else if (strcmp(arg[k], "IFFTW") == 0)  inc1.push_back("fftwserver.h");
+      else if (strcmp(arg[k], "XAstroPack") == 0)  inc1.push_back("xastropack.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 {
+
+    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 (std::exception & sex) {
+    cerr << " Catched std::exception " << (string)typeid(sex).name()
+         << " - Msg= " << sex.what() << 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> \n"
+    <<"#include <fstream> \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 \"sopnamsp.h\" \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_Nov2007/SophyaProg/PrgUtil/scanfits.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/scanfits.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/scanfits.cc	(revision 3445)
@@ -0,0 +1,152 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.h"
+
+#include "fitsfile.h"
+#include "fitsmanager.h"
+#include "fiosinit.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
+  csh> scanfits -h
+  PIOPersist::Initialize() Starting Sophya Persistence management service 
+  SOPHYA Version  1.9 Revision 25 (V_Dec2005) -- Jan  4 2006 14:50:01 cxx 
+  Usage: scanfits [flags] filename 
+  flags = -V1 -lh -rd -header 
+    -V1 : Scan using old (V1) code version 
+    -lh : Print the list of registered handlers (FitsHandlerInterface) 
+    -rd : try to read each HDU data using appropriate handler 
+    -header : List header information 
+  \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?");
+}
+
+static int scanV1(string & flnm) 
+{
+  char * argnm = new char[ flnm.length()+1 ];
+  strcpy(argnm, flnm.c_str());
+  int nbblk = FitsInFile::NbBlocks(argnm);
+  cout << " :::::::: File " << flnm << " has " << nbblk << " blocks " 
+       << " :::::::: " << endl;
+  
+  
+  for(int i=1; i<=nbblk; i++) {
+    int naxis;
+    vector<int> axis;
+    DVList header;
+    FitsFile::FitsExtensionType exttype;
+    FitsFile::FitsDataType datatype;
+    
+    FitsInFile::GetBlockType(argnm, 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;
+  } 
+  delete[] argnm;
+  return 0;
+}
+
+int main(int narg, char *arg[]) 
+{
+  if ((narg < 2) || (strcmp(arg[1],"-h") == 0) ) {
+    cout << " Usage: scanfits [flags] filename \n" 
+	 << " flags = -V1 -lh -rd -header \n"
+	 << "   -V1 : Scan using old (V1) code version \n"  
+	 << "   -lh : Print the list of registered handlers (FitsHandlerInterface) \n" 
+	 << "   -rd : try to read each HDU data using appropriate handler \n" 
+	 << "   -header : List header information \n" << endl;
+    return(0);
+  }
+  bool fgv1 = false;
+  bool fgrd = false;
+  bool fglh = false;
+  bool fghd = false;
+  bool fgflnm = false;
+  string flnm = "";
+  for (int k=1; k<narg; k++)   {
+    if (strcmp(arg[k], "-V1") == 0)  fgv1 = true;
+    else if (strcmp(arg[k], "-rd") == 0)  fgrd = true;
+    else if (strcmp(arg[k], "-lh") == 0)  fglh = true;
+    else if (strcmp(arg[k], "-header") == 0)  fghd = true;
+    else { 
+      fgflnm = true; flnm = arg[k]; 
+      break; 
+    }
+  }
+  int slev = 0;
+  if ( fgrd ) slev = 2;
+  if ( fghd ) slev += 1;
+  if (!fglh && !fgflnm) {
+    cout << " scanfits/Erreur : no file name specified and no -lh " << endl;
+    return 1;
+  }
+  try {
+    SophyaInit();
+    FitsIOServerInit();
+    cout << " ====== scanfits: FileName= " << flnm << " ==== " << endl;
+    if ( fglh ) FitsManager::ListHandlers();
+    if ( fgflnm ) {
+      if ( fgv1 ) scanV1(flnm);
+      else FitsManager::ScanFile(flnm, slev);
+    }
+  }
+  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_Nov2007/SophyaProg/PrgUtil/scanppf.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/scanppf.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/scanppf.cc	(revision 3445)
@@ -0,0 +1,135 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream>
+#include <string>
+
+#include "sopnamsp.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+#include "sambainit.h"
+#include "histinit.h"
+
+
+/*!
+  \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)
+  </UL>
+*/
+
+/*!
+  \ingroup PrgUtil
+  \file scanppf.cc
+  \brief \b scanppf: Check and scan PPF files
+
+  \verbatim
+
+  csh> scanppf -h
+ PIOPersist::Initialize() Starting Sophya Persistence management service 
+SOPHYA Version  2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx 
+ Usage: scanppf [flags] filename 
+ flags = -s -n -a0 -a1 -a2 -a3 -lh -lho -lmod
+   -s[=default} : Sequential reading of objects 
+   -n : Object reading at NameTags 
+   -a0...a3 : Tag List with PInPersist.AnalyseTags(0...3) 
+   -lh : List PPersist handler classes 
+   -lho : List PPersist handler and dataobj classes 
+   -lmod : List initialized/registered modules 
+
+  \endverbatim
+*/
+
+int main(int narg, char* arg[])
+{
+
+SambaInitiator smbinit;
+HiStatsInitiator hisinit;
+
+if ((narg < 2) || (strcmp(arg[1],"-h") == 0) ) {
+  cout << " Usage: scanppf [flags] filename \n" 
+       << " flags = -s -n -a0 -a1 -a2 -a3 -lh -lho -lmod \n"
+       << "   -s[=default} : Sequential reading of objects \n"  
+       << "   -n : Object reading at NameTags \n" 
+       << "   -a0...a3 : Tag List with PInPersist.AnalyseTags(0...3) \n" 
+       << "   -lh : List PPersist handler classes \n" 
+       << "   -lho : List PPersist handler and dataobj classes \n" 
+       << "   -lmod : List initialized/registered modules \n" << endl; 
+  return(0);
+  }
+
+try {
+  string flnm;
+  bool seq=true;
+  bool ana=false;
+  int analev = 0;
+  string opt = "s";
+  if ((narg >= 2) && (*arg[1] == '-')) { 
+    opt = arg[1];
+    if (narg > 2) flnm = arg[2];
+  }
+  else flnm = arg[1];
+
+  if (opt == "-lh")  {
+    cout << " --- scanppf : List of registered handler classes --- " << endl;
+    PIOPersist::ListPPHandlers();
+  }
+  else if (opt == "-lho") {
+    cout << " --- scanppf : List of registered handler and DataObj classes --- " << endl;
+    PIOPersist::ListPPHandlers();
+    PIOPersist::ListDataObjClasses();
+  }
+  else if (opt == "-lmod") {
+    cout << " --- scanppf : List of registered module names and version --- " << endl;
+    SophyaInitiator::ListModules(cout);
+  }
+  else {
+    if (opt == "-n")  seq = false;
+    else if ((opt[0] == '-') && (opt[1] == 'a')) {  
+      ana = true;  
+      analev = 0;
+      if (opt.length()>2)  analev = opt[2]-'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.NbNameTags();
+      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.GotoNameTagNum(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_Nov2007/SophyaProg/PrgUtil/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/smakefile	(revision 3445)
@@ -0,0 +1,106 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)runcxx $(SOPHYAEXEP)scanppf $(SOPHYAEXEP)scanfits
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)scanfits.o $(SOPHYAOBJP)scanppf.o $(SOPHYAOBJP)runcxx.o
+ 
+runcxx: $(SOPHYAEXEP)runcxx
+	echo $@ " done"
+$(SOPHYAEXEP)runcxx: $(SOPHYAOBJP)runcxx.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)runcxx.o $(SOPHYAEXTSLBLIST)
+ 
+scanppf: $(SOPHYAEXEP)scanppf
+	echo $@ " done"
+$(SOPHYAEXEP)scanppf: $(SOPHYAOBJP)scanppf.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)scanppf.o $(SOPHYAEXTSLBLIST)
+ 
+scanfits: $(SOPHYAEXEP)scanfits
+	echo $@ " done"
+$(SOPHYAEXEP)scanfits: $(SOPHYAOBJP)scanfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)scanfits.o $(SOPHYAEXTSLBLIST)
+ 
+$(SOPHYAOBJP)runcxx.o: runcxx.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)skyinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)cxxcmplnk.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  runcxx.cc
+ 
+$(SOPHYAOBJP)scanfits.o: scanfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsmanager.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)sophyainit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scanfits.cc
+ 
+$(SOPHYAOBJP)scanppf.o: scanppf.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)histinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  scanppf.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/PrgUtil/tst.icc
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/tst.icc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/tst.icc	(revision 3445)
@@ -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_Nov2007/SophyaProg/PrgUtil/usedlibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/usedlibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/usedlibs	(revision 3445)
@@ -0,0 +1,8 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+
+
Index: /tags/V_Nov2007/SophyaProg/PrgUtil/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/PrgUtil/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/PrgUtil/usedslibs	(revision 3445)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaProg/Tests/JTCMakefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/JTCMakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/JTCMakefile	(revision 3445)
@@ -0,0 +1,65 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet -pthread 
+include $(SOPHYADEVREP)/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_Nov2007/SophyaProg/Tests/Makefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/Makefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/Makefile	(revision 3445)
@@ -0,0 +1,1702 @@
+include ../BuildMgr/sophyamake.inc
+ 
+PROGS = $(SOPHYAEXEP)arrt $(SOPHYAEXEP)carrt $(SOPHYAEXEP)lpk $(SOPHYAEXEP)obj_fits $(SOPHYAEXEP)ovharr $(SOPHYAEXEP)pizthr $(SOPHYAEXEP)ppftswap $(SOPHYAEXEP)spar $(SOPHYAEXEP)sphg0 $(SOPHYAEXEP)sph2lm $(SOPHYAEXEP)tcmd $(SOPHYAEXEP)tcxxcmpldynl $(SOPHYAEXEP)tdcr $(SOPHYAEXEP)tdynl $(SOPHYAEXEP)tfft $(SOPHYAEXEP)thash $(SOPHYAEXEP)timg $(SOPHYAEXEP)tmxv $(SOPHYAEXEP)tnt $(SOPHYAEXEP)tobjio2 $(SOPHYAEXEP)tobjio $(SOPHYAEXEP)tpipe $(SOPHYAEXEP)tsimplex $(SOPHYAEXEP)tsphereecp $(SOPHYAEXEP)tspm2 $(SOPHYAEXEP)tspm $(SOPHYAEXEP)tstboloread $(SOPHYAEXEP)tstcolread $(SOPHYAEXEP)tstdtable $(SOPHYAEXEP)tstndblk $(SOPHYAEXEP)tstppfwrapstl $(SOPHYAEXEP)tstsegdb $(SOPHYAEXEP)tswfits $(SOPHYAEXEP)tnfits $(SOPHYAEXEP)tfitsdt $(SOPHYAEXEP)tsttmat $(SOPHYAEXEP)tsttminv $(SOPHYAEXEP)tsttvec $(SOPHYAEXEP)ttimestamp $(SOPHYAEXEP)zthr $(SOPHYAEXEP)tmtrnd $(SOPHYAEXEP)tmtrnd3 $(SOPHYAEXEP)tmtdt
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)tmtdt.o $(SOPHYAOBJP)tmtrnd3.o $(SOPHYAOBJP)tmtrnd.o $(SOPHYAOBJP)zthr.o $(SOPHYAOBJP)ttimestamp.o $(SOPHYAOBJP)tsttvec.o $(SOPHYAOBJP)tsttminv.o $(SOPHYAOBJP)tsttmat.o $(SOPHYAOBJP)tfitsdt.o $(SOPHYAOBJP)tnfits.o $(SOPHYAOBJP)tswfits.o $(SOPHYAOBJP)tstsegdb.o $(SOPHYAOBJP)tstppfwrapstl.o $(SOPHYAOBJP)tstndblk.o $(SOPHYAOBJP)tstdtable.o $(SOPHYAOBJP)tstcolread.o $(SOPHYAOBJP)tstboloread.o $(SOPHYAOBJP)tspm.o $(SOPHYAOBJP)tspm2.o $(SOPHYAOBJP)tsphereecp.o $(SOPHYAOBJP)tsimplex.o $(SOPHYAOBJP)tpipe.o $(SOPHYAOBJP)tobjio.o $(SOPHYAOBJP)tobjio2.o $(SOPHYAOBJP)tnt.o $(SOPHYAOBJP)tmxv.o $(SOPHYAOBJP)timg.o $(SOPHYAOBJP)thash.o $(SOPHYAOBJP)tfft.o $(SOPHYAOBJP)tdynl.o $(SOPHYAOBJP)tdcr.o $(SOPHYAOBJP)tcxxcmpldynl.o $(SOPHYAOBJP)tcmd.o $(SOPHYAOBJP)sph2lm.o $(SOPHYAOBJP)sphg0.o $(SOPHYAOBJP)spar.o $(SOPHYAOBJP)ppftswap.o $(SOPHYAOBJP)pizthr.o $(SOPHYAOBJP)ovharr.o $(SOPHYAOBJP)obj_fits.o $(SOPHYAOBJP)lpk.o $(SOPHYAOBJP)carrt.o $(SOPHYAOBJP)arrt.o
+ 
+arrt: $(SOPHYAEXEP)arrt
+	echo $@ " done"
+$(SOPHYAEXEP)arrt: $(SOPHYAOBJP)arrt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)arrt.o $(SOPHYAALLSLBLIST)
+ 
+carrt: $(SOPHYAEXEP)carrt
+	echo $@ " done"
+$(SOPHYAEXEP)carrt: $(SOPHYAOBJP)carrt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)carrt.o $(SOPHYAALLSLBLIST)
+ 
+lpk: $(SOPHYAEXEP)lpk
+	echo $@ " done"
+$(SOPHYAEXEP)lpk: $(SOPHYAOBJP)lpk.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)lpk.o $(SOPHYAALLSLBLIST)
+ 
+obj_fits: $(SOPHYAEXEP)obj_fits
+	echo $@ " done"
+$(SOPHYAEXEP)obj_fits: $(SOPHYAOBJP)obj_fits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)obj_fits.o $(SOPHYAALLSLBLIST)
+ 
+ovharr: $(SOPHYAEXEP)ovharr
+	echo $@ " done"
+$(SOPHYAEXEP)ovharr: $(SOPHYAOBJP)ovharr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ovharr.o $(SOPHYAALLSLBLIST)
+ 
+pizthr: $(SOPHYAEXEP)pizthr
+	echo $@ " done"
+$(SOPHYAEXEP)pizthr: $(SOPHYAOBJP)pizthr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pizthr.o $(SOPHYAALLSLBLIST)
+ 
+ppftswap: $(SOPHYAEXEP)ppftswap
+	echo $@ " done"
+$(SOPHYAEXEP)ppftswap: $(SOPHYAOBJP)ppftswap.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ppftswap.o $(SOPHYAALLSLBLIST)
+ 
+spar: $(SOPHYAEXEP)spar
+	echo $@ " done"
+$(SOPHYAEXEP)spar: $(SOPHYAOBJP)spar.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)spar.o $(SOPHYAALLSLBLIST)
+ 
+sphg0: $(SOPHYAEXEP)sphg0
+	echo $@ " done"
+$(SOPHYAEXEP)sphg0: $(SOPHYAOBJP)sphg0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)sphg0.o $(SOPHYAALLSLBLIST)
+ 
+sph2lm: $(SOPHYAEXEP)sph2lm
+	echo $@ " done"
+$(SOPHYAEXEP)sph2lm: $(SOPHYAOBJP)sph2lm.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)sph2lm.o $(SOPHYAALLSLBLIST)
+ 
+tcmd: $(SOPHYAEXEP)tcmd
+	echo $@ " done"
+$(SOPHYAEXEP)tcmd: $(SOPHYAOBJP)tcmd.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tcmd.o $(SOPHYAALLSLBLIST)
+ 
+tcxxcmpldynl: $(SOPHYAEXEP)tcxxcmpldynl
+	echo $@ " done"
+$(SOPHYAEXEP)tcxxcmpldynl: $(SOPHYAOBJP)tcxxcmpldynl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tcxxcmpldynl.o $(SOPHYAALLSLBLIST)
+ 
+tdcr: $(SOPHYAEXEP)tdcr
+	echo $@ " done"
+$(SOPHYAEXEP)tdcr: $(SOPHYAOBJP)tdcr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tdcr.o $(SOPHYAALLSLBLIST)
+ 
+tdynl: $(SOPHYAEXEP)tdynl
+	echo $@ " done"
+$(SOPHYAEXEP)tdynl: $(SOPHYAOBJP)tdynl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tdynl.o $(SOPHYAALLSLBLIST)
+ 
+tfft: $(SOPHYAEXEP)tfft
+	echo $@ " done"
+$(SOPHYAEXEP)tfft: $(SOPHYAOBJP)tfft.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tfft.o $(SOPHYAALLSLBLIST)
+ 
+thash: $(SOPHYAEXEP)thash
+	echo $@ " done"
+$(SOPHYAEXEP)thash: $(SOPHYAOBJP)thash.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)thash.o $(SOPHYAALLSLBLIST)
+ 
+timg: $(SOPHYAEXEP)timg
+	echo $@ " done"
+$(SOPHYAEXEP)timg: $(SOPHYAOBJP)timg.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)timg.o $(SOPHYAALLSLBLIST)
+ 
+tmxv: $(SOPHYAEXEP)tmxv
+	echo $@ " done"
+$(SOPHYAEXEP)tmxv: $(SOPHYAOBJP)tmxv.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmxv.o $(SOPHYAALLSLBLIST)
+ 
+tnt: $(SOPHYAEXEP)tnt
+	echo $@ " done"
+$(SOPHYAEXEP)tnt: $(SOPHYAOBJP)tnt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tnt.o $(SOPHYAALLSLBLIST)
+ 
+tobjio2: $(SOPHYAEXEP)tobjio2
+	echo $@ " done"
+$(SOPHYAEXEP)tobjio2: $(SOPHYAOBJP)tobjio2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tobjio2.o $(SOPHYAALLSLBLIST)
+ 
+tobjio: $(SOPHYAEXEP)tobjio
+	echo $@ " done"
+$(SOPHYAEXEP)tobjio: $(SOPHYAOBJP)tobjio.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tobjio.o $(SOPHYAALLSLBLIST)
+ 
+tpipe: $(SOPHYAEXEP)tpipe
+	echo $@ " done"
+$(SOPHYAEXEP)tpipe: $(SOPHYAOBJP)tpipe.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tpipe.o $(SOPHYAALLSLBLIST)
+ 
+tsimplex: $(SOPHYAEXEP)tsimplex
+	echo $@ " done"
+$(SOPHYAEXEP)tsimplex: $(SOPHYAOBJP)tsimplex.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsimplex.o $(SOPHYAALLSLBLIST)
+ 
+tsphereecp: $(SOPHYAEXEP)tsphereecp
+	echo $@ " done"
+$(SOPHYAEXEP)tsphereecp: $(SOPHYAOBJP)tsphereecp.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsphereecp.o $(SOPHYAALLSLBLIST)
+ 
+tspm2: $(SOPHYAEXEP)tspm2
+	echo $@ " done"
+$(SOPHYAEXEP)tspm2: $(SOPHYAOBJP)tspm2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tspm2.o $(SOPHYAALLSLBLIST)
+ 
+tspm: $(SOPHYAEXEP)tspm
+	echo $@ " done"
+$(SOPHYAEXEP)tspm: $(SOPHYAOBJP)tspm.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tspm.o $(SOPHYAALLSLBLIST)
+ 
+tstboloread: $(SOPHYAEXEP)tstboloread
+	echo $@ " done"
+$(SOPHYAEXEP)tstboloread: $(SOPHYAOBJP)tstboloread.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstboloread.o $(SOPHYAALLSLBLIST)
+ 
+tstcolread: $(SOPHYAEXEP)tstcolread
+	echo $@ " done"
+$(SOPHYAEXEP)tstcolread: $(SOPHYAOBJP)tstcolread.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstcolread.o $(SOPHYAALLSLBLIST)
+ 
+tstdtable: $(SOPHYAEXEP)tstdtable
+	echo $@ " done"
+$(SOPHYAEXEP)tstdtable: $(SOPHYAOBJP)tstdtable.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstdtable.o $(SOPHYAALLSLBLIST)
+ 
+tstndblk: $(SOPHYAEXEP)tstndblk
+	echo $@ " done"
+$(SOPHYAEXEP)tstndblk: $(SOPHYAOBJP)tstndblk.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstndblk.o $(SOPHYAALLSLBLIST)
+ 
+tstppfwrapstl: $(SOPHYAEXEP)tstppfwrapstl
+	echo $@ " done"
+$(SOPHYAEXEP)tstppfwrapstl: $(SOPHYAOBJP)tstppfwrapstl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstppfwrapstl.o $(SOPHYAALLSLBLIST)
+ 
+tstsegdb: $(SOPHYAEXEP)tstsegdb
+	echo $@ " done"
+$(SOPHYAEXEP)tstsegdb: $(SOPHYAOBJP)tstsegdb.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstsegdb.o $(SOPHYAALLSLBLIST)
+ 
+tswfits: $(SOPHYAEXEP)tswfits
+	echo $@ " done"
+$(SOPHYAEXEP)tswfits: $(SOPHYAOBJP)tswfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tswfits.o $(SOPHYAALLSLBLIST)
+ 
+tnfits: $(SOPHYAEXEP)tnfits
+	echo $@ " done"
+$(SOPHYAEXEP)tnfits: $(SOPHYAOBJP)tnfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tnfits.o $(SOPHYAALLSLBLIST)
+ 
+tfitsdt: $(SOPHYAEXEP)tfitsdt
+	echo $@ " done"
+$(SOPHYAEXEP)tfitsdt: $(SOPHYAOBJP)tfitsdt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tfitsdt.o $(SOPHYAALLSLBLIST)
+ 
+tsttmat: $(SOPHYAEXEP)tsttmat
+	echo $@ " done"
+$(SOPHYAEXEP)tsttmat: $(SOPHYAOBJP)tsttmat.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttmat.o $(SOPHYAALLSLBLIST)
+ 
+tsttminv: $(SOPHYAEXEP)tsttminv
+	echo $@ " done"
+$(SOPHYAEXEP)tsttminv: $(SOPHYAOBJP)tsttminv.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttminv.o $(SOPHYAALLSLBLIST)
+ 
+tsttvec: $(SOPHYAEXEP)tsttvec
+	echo $@ " done"
+$(SOPHYAEXEP)tsttvec: $(SOPHYAOBJP)tsttvec.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttvec.o $(SOPHYAALLSLBLIST)
+ 
+ttimestamp: $(SOPHYAEXEP)ttimestamp
+	echo $@ " done"
+$(SOPHYAEXEP)ttimestamp: $(SOPHYAOBJP)ttimestamp.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ttimestamp.o $(SOPHYAALLSLBLIST)
+ 
+zthr: $(SOPHYAEXEP)zthr
+	echo $@ " done"
+$(SOPHYAEXEP)zthr: $(SOPHYAOBJP)zthr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)zthr.o $(SOPHYAALLSLBLIST)
+ 
+tmtrnd: $(SOPHYAEXEP)tmtrnd
+	echo $@ " done"
+$(SOPHYAEXEP)tmtrnd: $(SOPHYAOBJP)tmtrnd.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtrnd.o $(SOPHYAALLSLBLIST)
+ 
+tmtrnd3: $(SOPHYAEXEP)tmtrnd3
+	echo $@ " done"
+$(SOPHYAEXEP)tmtrnd3: $(SOPHYAOBJP)tmtrnd3.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtrnd3.o $(SOPHYAALLSLBLIST)
+ 
+tmtdt: $(SOPHYAEXEP)tmtdt
+	echo $@ " done"
+$(SOPHYAEXEP)tmtdt: $(SOPHYAOBJP)tmtdt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtdt.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)arrt.o: arrt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  arrt.cc
+ 
+$(SOPHYAOBJP)carrt.o: carrt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  carrt.cc
+ 
+$(SOPHYAOBJP)lpk.o: lpk.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)intflapack.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lpk.cc
+ 
+$(SOPHYAOBJP)obj_fits.o: obj_fits.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)fitsxntuple.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsntuple.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  obj_fits.cc
+ 
+$(SOPHYAOBJP)ovharr.o: ovharr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ovharr.cc
+ 
+$(SOPHYAOBJP)pizthr.o: pizthr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pizthr.cc
+ 
+$(SOPHYAOBJP)ppftswap.o: ppftswap.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)tarrinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppftswap.cc
+ 
+$(SOPHYAOBJP)spar.o: spar.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spar.cc
+ 
+$(SOPHYAOBJP)sph2lm.o: sph2lm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)mapoperation.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fftwserver.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)fftservintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sph2lm.cc
+ 
+$(SOPHYAOBJP)sphg0.o: sphg0.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphg0.cc
+ 
+$(SOPHYAOBJP)tcmd.o: tcmd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)cexpre.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)rpneval.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tcmd.cc
+ 
+$(SOPHYAOBJP)tcxxcmpldynl.o: tcxxcmpldynl.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)cxxcmplnk.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tcxxcmpldynl.cc
+ 
+$(SOPHYAOBJP)tdcr.o: tdcr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)psighand.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tdcr.cc
+ 
+$(SOPHYAOBJP)tdynl.o: tdynl.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tdynl.cc
+ 
+$(SOPHYAOBJP)tfft.o: tfft.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fftmserver.h \
+  $(SOPHYAINCP)fftmayer.h \
+  $(SOPHYAINCP)fftwserver.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tfft.cc
+ 
+$(SOPHYAOBJP)tfitsdt.o: tfitsdt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fitshdtable.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsblkrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tfitsdt.cc
+ 
+$(SOPHYAOBJP)thash.o: thash.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  thash.cc
+ 
+$(SOPHYAOBJP)timg.o: timg.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timg.cc
+ 
+$(SOPHYAOBJP)tmtdt.o: tmtdt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitshdtable.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtdt.cc
+ 
+$(SOPHYAOBJP)tmtrnd3.o: tmtrnd3.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbtri.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)stsrand.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtrnd3.cc
+ 
+$(SOPHYAOBJP)tmtrnd.o: tmtrnd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)stsrand.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtrnd.cc
+ 
+$(SOPHYAOBJP)tmxv.o: tmxv.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmxv.cc
+ 
+$(SOPHYAOBJP)tnfits.o: tnfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitsarrhand.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tnfits.cc
+ 
+$(SOPHYAOBJP)tnt.o: tnt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tnt.cc
+ 
+$(SOPHYAOBJP)tobjio2.o: tobjio2.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tobjio2.cc
+ 
+$(SOPHYAOBJP)tobjio.o: tobjio.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)fioarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tobjio.cc
+ 
+$(SOPHYAOBJP)tpipe.o: tpipe.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tpipe.cc
+ 
+$(SOPHYAOBJP)tsimplex.o: tsimplex.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)simplex.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsimplex.cc
+ 
+$(SOPHYAOBJP)tsphereecp.o: tsphereecp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsphereecp.cc
+ 
+$(SOPHYAOBJP)tspm2.o: tspm2.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tspm2.cc
+ 
+$(SOPHYAOBJP)tspm.o: tspm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tspm.cc
+ 
+$(SOPHYAOBJP)tstboloread.o: tstboloread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fboloread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fabtcolread.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fabtwriter.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstboloread.cc
+ 
+$(SOPHYAOBJP)tstcolread.o: tstcolread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fabtcolread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fabtwriter.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstcolread.cc
+ 
+$(SOPHYAOBJP)tstdtable.o: tstdtable.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstdtable.cc
+ 
+$(SOPHYAOBJP)tstndblk.o: tstndblk.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstndblk.cc
+ 
+$(SOPHYAOBJP)tstppfwrapstl.o: tstppfwrapstl.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ppfwrapstlv.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstppfwrapstl.cc
+ 
+$(SOPHYAOBJP)tstsegdb.o: tstsegdb.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)fiosegdb.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppfwrapstlv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstsegdb.cc
+ 
+$(SOPHYAOBJP)tsttmat.o: tsttmat.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttmat.cc
+ 
+$(SOPHYAOBJP)tsttminv.o: tsttminv.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)intflapack.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttminv.cc
+ 
+$(SOPHYAOBJP)tsttvec.o: tsttvec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttvec.cc
+ 
+$(SOPHYAOBJP)tswfits.o: tswfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)fitshdtable.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tswfits.cc
+ 
+$(SOPHYAOBJP)ttimestamp.o: ttimestamp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ppfwrapstlv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ttimestamp.cc
+ 
+$(SOPHYAOBJP)zthr.o: zthr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  zthr.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/Tests/Makefile.mgr
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/Makefile.mgr	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/Makefile.mgr	(revision 3445)
@@ -0,0 +1,75 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYADEVREP)/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
+ifeq ($(MACHEROS),Darwin)
+LIBS := -L$(LIB) -lLinAlg $(LIBS) -L$(EXTLIBPATH) -framework Accelerate
+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_Nov2007/SophyaProg/Tests/arrt.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/arrt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/arrt.cc	(revision 3445)
@@ -0,0 +1,529 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+/*  --------------------------------------------------------- */
+/*  ------- Programme de test des fonctions de base  -------  */
+/*  ----    sur les TArray/TMatrix de SOPHYA    ----          */
+/*  2000-2006      -   C. Magneville,  R. Ansari              */
+/*  arrt -> Help/Usage                                        */
+/*  Pour effectuer les tests avec RC                          */
+/*  arrt  check       -> Rc=0 OK                              */
+/*  Pour verification avec les impressions                    */
+/*  arrt a / w / m / ascio                                    */
+/*  --------------------------------------------------------- */
+
+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);
+// Methode de verification des fonctionalites - Fev 2006 
+static int checktarr();
+
+static int prtlev = 1;
+
+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" 
+	 << " check: TArray Test/Check with Rc  \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 nprt = 50;
+  if (narg > 3) prtlev = atoi(arg[3]);
+  if (narg > 4) nprt = atoi(arg[4]);
+
+  BaseArray::SetMaxPrint(nprt, prtlev);
+
+  int rc = 0;
+  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 if (opt == "check") rc = checktarr();
+    else {
+      cout << " arrt/Error : unknown option ! " << endl;
+    }
+  }
+  catch (PThrowable exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+    rc = 97;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+    rc  = 99;
+  }  
+  PrtTim("--- End of arrt ---");
+  cout << " -----------  END of ArrayTest (Rc= " << rc << ") --------- " << endl;
+  return 0;
+}
+
+
+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));
+  if (prtlev > 0) 
+    cout << " ----- Matrix ma = \n " << ma << endl;
+  sma1 = 3.14;
+  if (prtlev > 0) 
+    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;
+  if (prtlev > 0) 
+    cout << " ----- Matrix mc = mb(=50.)+sma1(=3.14) = " << mc << endl;
+  TMatrix<r_4> md = (float)100+mc;
+  if (prtlev > 0) {
+    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.);
+  if (prtlev > 0) {
+    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);
+  if (prtlev > 0) {
+    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);
+  if (prtlev > 0) 
+    cout << " ----- Vector  vlig=ima.Row(1) = \n" << vlig << endl;
+
+  TMatrix<int_4> imb(3,10);
+  imb = RegularSequence(100.01,10.);
+  if (prtlev > 0) 
+    cout << " ----- Matrix imb(3,10) = RegularSequence(100.01,10.) = " << imb << endl;
+  TMatrix<int_4> imc = ima+imb;
+  if (prtlev > 0) 
+    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,imd);
+  if (prtlev > 0) 
+    cout << " ----- Matrix imd (? = 100) " << imd << endl;
+  imb -= imd;
+  imc -= imd;
+  if (prtlev > 0) 
+    cout << " ----- Matrix ((imc-=imd)-(imb-=imd))-ima (== 0 ?) " 
+         << (imc-imb)-ima << endl;
+  TVector<r_4> va(16, BaseArray::RowVector);
+  va = RegularSequence(0.,1.);
+  if (prtlev > 0) 
+    cout << " ----- Vector va = RegularSequence(0.,1.) = " << va << endl;
+  va(Range(2,0,6,2)) *= 10.;
+  if (prtlev > 0) 
+    cout << " ----- Vector va apres va(Range(2,0,6,2)) *= 10. " << va << endl;
+  va(Range(0,5)) += 100.;
+  if (prtlev > 0) 
+    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;
+  if (prtlev > 0) 
+    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.SumSq();
+
+  if (prtlev > 0) 
+    cout << " Min= " << emin << "  Max= " << emax 
+         << " Sum= " << esum << " Prod=" << eprod << " SumSq=" << 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 ;
+  
+  if (prtlev > 0) {
+    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);
+  if (prtlev > 0) {
+    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);
+  if (prtlev > 0) 
+    cout << " ----- Matrix a=RandomSequence(RandomSequence::Gaussian, 0., 2.5) = \n " << a << endl;
+  Vector x(n);
+  x = RegularSequence(1.,3.);
+  Vector b = a*x;
+  if (prtlev > 0) {
+    cout << " ----- Vector x = \n " << x << endl;
+    cout << " ----- Vector b = a*x = \n " << b << endl;
+  }
+  SimpleMatrixOperation<r_8> smo;
+  Matrix inva = smo.Inverse(a);
+  if (prtlev > 0) {
+    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 ;
+
+}
+
+// ----- Fonction de verification des fonctions de base de TArray 
+// Retourne 0 si OK 
+int checktarr()
+{
+  int rc = 0;
+
+  int NX = 17;
+  int NY = 8;
+  int NZ = 6;
+  int NT = 5;
+  if (prtlev > 0)  
+    cout << " CheckArry: Starting Test-1 EltAcc/SubArray <int> " << endl;
+  TArray<int> IA(NX, NY, NZ, NT);
+  for(int ix=0; ix<NX; ix++)
+    for(int iy=0; iy<NY; iy++)
+      for(int iz=0; iz<NZ; iz++)
+	for(int it=0; it<NT; it++)
+	  IA(ix, iy, iz, it) = it*10000+iz*1000+iy*100+ix;
+
+  TArray<int> IB(NX, NY);
+  TMatrix<int> IMXB(IB);
+  for(int ir=0; ir<IMXB.NRows(); ir++) {
+    IMXB.Row(ir) = RegularSequence(0.1);  
+    IMXB.Row(ir) += ir*100;
+  }
+
+  int nerr = 0;
+  int min=99, max=99;
+  for(int iz=0; iz<NZ; iz++)
+    for(int it=0; it<NT; it++)  {
+      TArray<int> IC = IB+(it*10000+iz*1000);
+      TArray<int> IAI = IA(Range::all(), Range::all(), Range(iz, iz), Range(it, it));
+      // Fait par SubArray      IAI.CompactTrailingDim();
+      if (prtlev > 2) {
+	cout << " CheckArry/Debug: Test-1 iz=" << iz << " it=" << it << endl;
+	cout << "IAI= \n " << IAI << " IC= \n " << IC << endl;
+      }
+      TArray<int> ID = IAI - IC;
+      ID.MinMax(min, max);
+      if ((min!=0) || (max!=0)) nerr++;
+    }
+  
+  if (nerr == 0)
+    cout << "(1) CheckTArray <int>  EltAcc, SubArray OK " << endl; 
+  else {
+    cout << "(1) CheckTArray <int>  EltAcc, SubArray ERROR -> Rc += 1 !!! NErr=" 
+	 << nerr << endl; 
+    rc += 1;
+  }
+
+  if (prtlev > 0)  
+    cout << " CheckArry: Starting Test-2 SubArray/Range <int> " << endl;  nerr = 0;
+  {
+  TArray<int> ID, IAI;
+  IAI = IA(Range::all(), Range::all(), Range::last(), Range::first());
+  // Fait par SubArray  IAI.CompactTrailingDim();
+  // cout << "---DBG- IAI= \n " << IAI << " IB= \n " << IB << endl;
+  ID = IAI - IB;
+  ID -= ((NZ-1)*1000);
+  // cout << "---DBG- ID= \n" << ID ;
+  ID.MinMax(min, max);
+  if ((min!=0) || (max!=0)) nerr++;
+  }
+  {
+  TArray<int> ID, IAI;
+  IAI = IA(Range::all(), Range::all(), Range::last(), Range::last());
+  // Fait par SubArray  IAI.CompactTrailingDim();
+  //  cout << "---DBG- IAI= \n " << IAI << " IB= \n " << IB << endl;
+  ID = IAI - IB;
+  ID -= ((NZ-1)*1000+(NT-1)*10000);
+  // cout << "---DBG- ID= \n" << ID ;
+  ID.MinMax(min, max);
+  if ((min!=0) || (max!=0)) nerr++;
+  }
+  if (nerr == 0)
+    cout << "(2) CheckTArray <int>  SubArray/Range::last() OK " << endl; 
+  else {
+    cout << "(2) CheckTArray <int>  SubArray/Range::last() ERROR  Rc += 2 !!! NErr=" 
+	 << nerr << endl; 
+    rc += 2;
+  }
+
+  if (prtlev > 0)  
+    cout << " CheckArry: Starting Test-3 SubArray(SubArray) <int> " << endl;  nerr = 0;
+  TArray<int> IAE = IA(Range::all(), Range::all(), 
+		       //	      		       Range(1, 0, 3, 2), Range::last() );
+  		       Range(Range::lastIndex(), Range::lastIndex(), 3, 2), Range::last() );
+  // Fait par SubArray  IAE.CompactTrailingDim();
+
+  TArray<int> IBE(NX/3, NY/2);  
+  for(int ix=0; ix<NX/3; ix++)
+    for(int iy=0; iy<NY/2; iy++)
+      IBE(ix, iy, 0) = 3*ix+(2*100*iy);
+
+  nerr = 0;
+  for(int iz=0; iz<IAE.SizeZ(); iz++) {
+    TArray<int> IAI = IAE(Range::all(), Range::all(), Range(iz, iz));
+    // Fait par SubArray  IAI.CompactTrailingDim();
+    //    cout << "---DBG- iz= " << iz << " IAI= \n " << IAI << " IB= \n " << IB << endl;
+    TArray<int> ID = IAI-IB;
+    ID -= ((iz*2+1)*1000+(NT-1)*10000);
+    ID.MinMax(min, max);
+    if ((min!=0) || (max!=0)) nerr++;
+  }
+
+  if (nerr == 0)
+    cout << "(3) CheckTArray <int>  SubArray(SubArray) OK " << endl; 
+  else {
+    cout << "(3) CheckTArray <int>  SubArray(SubArray)  ERROR  Rc += 4 !!! NErr=" 
+	 << nerr << endl; 
+    rc += 4;
+  }
+
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/carrt.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/carrt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/carrt.cc	(revision 3445)
@@ -0,0 +1,606 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+/*  --------------------------------------------------------- */
+/*  ---- Programme de test des operations et conversions ---  */
+/*  ----    sur les TArray/TMatrix de SOPHYA    ----          */
+/*  2000-2004      -   C. Magneville,  R. Ansari              */
+/*  carrt -> Help/Usage                                       */
+/*  Pour effectuer les tests :                                */
+/* Conversions entre arr<int> et arr<float>                   */
+/*  carrt  ac         -> Rc=0 OK                              */
+/*  carrt  ace        -> Exception/Rc=9                       */
+/*  carrt  oso        -> Rc=0 OK                              */
+/*  carrt  odo        -> Rc=0 OK                              */
+/*  --- carrt oso/odo NRow NCols  pour test grande tailles    */
+/*  --------------------------------------------------------- */
+
+static int test_ac(bool fgszm=false);
+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) { a.MinMax(min, max); }
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 2) {
+    cout << " carrt ac/ace/oso/odo [NRow=5] [NCols=10] [prtlev=0] [nprtmax=100] \n"
+	 << "   ac : array conversion test   \n" 
+	 << "   ace : array conversion test + conversion with sizemismatch -> exception/rc=9  \n" 
+	 << "   oso : operation same memory organisation \n" 
+	 << "   odo : operation different memory organisation \n" << endl;
+    return 1;
+  }
+
+  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);
+  int rc = 0;
+  PrtTim(" Start of Test ");
+  try {
+    if (opt == "ac") rc = test_ac(false);
+    else if (opt == "ace") rc = test_ac(true);
+    else if (opt == "oso") rc = test_oso(nr, nc);
+    else if (opt == "odo") rc = test_odo(nr, nc);
+  }
+  catch (PThrowable & exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+    rc = 9;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+  }  
+
+  PrtTim(" End of Test ");
+  cout << " ----- End of carrt - Rc= " << rc << " ----- " << endl;
+  if (rc > 255) rc = 255;
+  return rc;
+}
+
+
+int test_ac(bool fgszm)
+{
+  cout << "\n -----> Testing TArray Conversion <---- " << endl;
+  int rc = 0;
+  int_4 min, max;
+  TArray<int_4> ia(7,5),iac,iad;   
+  ia = RegularSequence(10., 2.);
+  TArray<r_4> ra(7,5);   
+  ra = ia;
+  if (prtlev>0) 
+    cout << " ra = ia(= RegularSequence(10., 2.)) = \n " << ra << endl;
+  iac = ra;
+  iad = iac-ia;
+  getMinMax(iad, min, max);
+  if ((min != 0) || (max != 0)) {
+    cout << "(1) !!! ERROR ra(7,5)=ia(7,5)  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << "(1) OK  ra(7,5)=ia(7,5)  OK " << endl; 
+
+  TArray<r_4> rb(5,3);
+  rb =  RegularSequence(20., .5);  
+  TMatrix<int_4> mx(3,5);
+  TMatrix<int_4> mxc(3,5);
+  mxc = RegularSequence(20., .5);  
+  if (prtlev>0) 
+    cout << " TArray<r_4> rb(5,3); rb =  RegularSequence(20., .5); rb : " << rb << endl;
+  mx = rb;
+  if (prtlev>0) 
+    cout << " TMatrix<int_4> mx(3,5);       mx = rb;  mx: " << mx << endl;
+  TMatrix<int_4> mxd = mxc-mx;
+  getMinMax(mxd, min, max);
+  if ((min != 0) || (max != 0)) {
+    cout << "(2) !!! ERROR mx<int>(5,3)=rb<r_4>(5,3)  Min=" << min << " Max=" << max << endl;
+    rc += 2;
+  }
+  else cout << "(2) OK  mx<int>(5,3)=rb<r_4>(5,3)  OK " << endl; 
+
+  TArray<r_4> rcv(10);
+  rcv = 3.1415;
+  TMatrix<r_8> mx2(rcv);
+  if (prtlev>0) 
+    cout << "   TArray<r_4> rcv(10) = 3.1415 , TMatrix<r_8> mx2(rc)=rcv : " << mx2 << endl;
+  TMatrix<int_4> mx2d = mx2-3.1415;
+  getMinMax(mxd, min, max);
+  if ((min != 0) || (max != 0)) {
+    cout << "(3) !!! ERROR mx2<r_8>(10)=rcv<r_4>(10)  Min=" << min << " Max=" << max << endl;
+    rc += 4;
+  }
+  else cout << "(3) OK  mx2<r_8>(10)=rcv<r_4>(10)  OK " << endl; 
+  if (fgszm) {
+    TMatrix<int_4> mx3(3,5);
+    cout << "(4) Trying  TMatrix<int_4> mx3(3,5);  mx3 = rcv(10); ?? -> Exception " << endl;
+    mx3 = rcv;
+  }
+  return(rc);
+}
+
+int test_oso(int nr, int nc)
+{
+  cout << "\n -----> Testing TArray operation TArray<int_4>(nx=" << nr << ",ny=" 
+       << nc << " ) " << endl;
+  cout << " -----> OSO (Same Mem. Mapping) Same memory mapping (default) for all arrays" << endl;
+
+  int rc = 0;
+  int min,max;
+
+  TArray<int_4> a(nr,nc);
+  a = 20;
+  TArray<int_4> b(nr,nc);
+  b = 9;
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+  }
+
+  TArray<int_4> ar;
+  ar = a+2;  
+  if (prtlev > 0) 
+    cout << "(1) AR = A+2=  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 22) || (max != 22)) {
+    cout << "(1) !!! ERROR Test AR=A+2  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << "(1) OK   Test AR=A+2  OK " << endl; 
+
+  ar = 28-a;  
+  if (prtlev > 0) 
+    cout << "(2) AR = 28-A=  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 8) || (max != 8)) {
+    cout << "(2) !!! ERROR Test AR=28-A  Min=" << min << " Max=" << max << endl;
+    rc += 2;
+  }
+  else cout << "(2) OK   Test AR=28-A  OK " << endl;
+ 
+  ar = a*3;  
+  if (prtlev > 0) 
+    cout << "(3) AR = A*3=  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 60) || (max != 60)) {
+    cout << "(3) !!! ERROR Test AR=A*3  Min=" << min << " Max=" << max << endl;
+    rc += 4;
+  }
+  else cout << "(3) OK   Test AR=A*3  OK " << endl; 
+
+  ar = a/5;  
+  if (prtlev > 0) 
+    cout << "(4) AR = A/5=  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 4) || (max != 4)) {
+    cout << "(4) !!! ERROR Test AR=A/5  Min=" << min << " Max=" << max << endl;
+    rc += 8;
+  }
+  else cout << "(4) OK   Test AR=A/5  OK " << endl; 
+
+  ar = 140/a;  
+  if (prtlev > 0) 
+    cout << "(5) AR = 140/A= \n " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 7) || (max != 7)) {
+    cout << "(5) !!! ERROR Test AR=140/A  Min=" << min << " Max=" << max << endl;
+    rc += 16;
+  }
+  else cout << "(5) OK   Test AR=140/A  OK " << endl; 
+
+  ar -= 3;  
+  if (prtlev > 0) 
+    cout << "(6) AR -= 3  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 4) || (max != 4)) {
+    cout << "(6) !!! ERROR Test AR-=3  Min=" << min << " Max=" << max << endl;
+    rc += 32;
+  }
+  else cout << "(6) OK   Test AR-=3  OK " << endl; 
+
+
+  TArray<int_4> c = a-2*b;
+  if (prtlev > 0) 
+    cout << "(7) C = A-2*B=  " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 2) || (max != 2)) {
+    cout << "(7) !!! ERROR Test C=A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 64;
+  }
+  else cout << "(7) OK   Test C=A+2*B  OK " << endl; 
+
+  (a*4+1).DivElt(b,c);
+  if (prtlev > 0) cout << "(8) C = (A*4+1)/B = " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 9) || (max != 9)) {
+    cout << "(8) !!! ERROR Test C = (A*4+1)/B  Min=" << min << " Max=" << max << endl;
+    rc += 128;
+  }
+  else cout << "(8) OK   Test C = (A*4+1)/B ((DivElt) OK " << endl; 
+  
+  a = RegularSequence(1, 1);
+  b = RegularSequence(nr*nc, -1);
+  c = (a*2)+(b*2);
+  if (prtlev > 0) {
+    cout << "(9) A =  " << a << endl;
+    cout << "(9) B =  " << b << endl;
+    cout << "(9) C = 2A-2*B=  " << c << endl;
+  }
+  c /= (nr*nc+1);
+  getMinMax(c, min, max);
+  if ((min != 2) || (max != 2)) {
+    cout << "(9) !!! ERROR Test C=2A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 256;
+  }
+  else cout << "(9) OK   Test C=2A+2*B  OK " << endl; 
+
+  a = 10;
+  b = 4;
+  c = 3*a-2*b;
+  if (prtlev > 0)  cout << "(10) A=10, B=4, C = 3*A-2*B = " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 22) || (max != 22)) {
+    cout << "(10) !!! ERROR Test C = 3*A-2*B  Min=" << min << " Max=" << max << endl;
+    rc += 512;
+  }
+  else cout << "(10) OK   Test C = 3*A-2*B  OK " << endl; 
+
+  c = 3*a+2*b;
+  if (prtlev > 0)  cout << "(11) A=10, B=4, C = 3*A+2*B = " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 38) || (max != 38)) {
+    cout << "(11) !!! ERROR Test C = 3*A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 512;
+  }
+  else cout << "(11) OK   Test C = 3*A+2*B  OK " << endl; 
+
+  a.MulElt(b+2,c);
+  if (prtlev > 0)  cout << "(12) A=10, B=4, a.MulElt(b+2,c) = " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 60) || (max != 60)) {
+    cout << "(12) !!! ERROR Test a.MulElt(b+2,c) Min=" << min << " Max=" << max << endl;
+    rc += 1024;
+  }
+  else cout << "(12) OK   Test A.MulElt(B+2,C)  OK " << endl; 
+
+  (3*a).DivElt(b+2,c);
+  if (prtlev > 0)  cout << "(13) A=10, B=4, (3*a).DivElt(b+2,c) C = " << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 5) || (max != 5)) {
+    cout << "(13) !!! ERROR Test (3*a).DivElt(b+2,c) Min=" << min << " Max=" << max << endl;
+    rc += 1024;
+  }
+  else cout << "(13) OK  Test (3*A).DivElt(B+2,C)  OK " << endl; 
+  
+  a = 3;
+  b = 2;
+  int_4 sc = a.ScalarProduct(b);
+  if (prtlev > 0)  cout << "(14) A=3, B=3, a.ScalarProduct(b)= " << sc << endl;
+  if (sc != nr*nc*6)   {
+    cout << "(14) !!! ERROR Test  a.ScalarProduct(b) sc " << sc << " !=" << nr*nc*6 << endl;
+    rc += 2048;
+  }
+  else cout << "(14) OK  Test a.ScalarProduct(b)  OK " << endl; 
+
+  TMatrix<int_4> mx(nr, nc), mxc(nr,nc);
+  for(int ir=0; ir<nr; ir++)
+    for(int ic=0; ic<nc; ic++) mxc(ir, ic) = ir*1000+ic*6;
+  if (prtlev > 0)  cout << "(15) mx.Row()/Column() operations MXC=" << mxc << endl;
+  
+  TVector<int_4> cv(nr), rv(nc, BaseArray::RowVector);
+  cv = RegularSequence(0, 1);
+  rv = RegularSequence(0, 1);
+  for(int ir=0; ir<nr; ir++)  { 
+    mx.Row(ir) = rv*3;
+    mx.Row(ir) *= 2;
+  }
+  for(int ic=0; ic<nc; ic++)  { 
+    mx.Column(ic) += cv*1000;
+  }
+  TMatrix<int_4> mxd = mx-mxc;
+  if (prtlev > 0)  { 
+    cout << "(15)  MX=" << mx << endl;
+    cout << "(15)  MXD=" << mxd << endl;
+  }
+  getMinMax(mxd, min, max);
+  if ((min != 0) || (max != 0)) {
+    cout << "(15) !!! ERROR Test mx.Row()/Column() operations Min=" << min << " Max=" << max << endl;
+    rc += 8192;
+  }
+  else cout << "(15) OK  Test mx.Row()/Column() operations  OK " << endl; 
+
+  a = RegularSequence(1, 1);
+  b = -a; 
+  c = a+b;
+  if (prtlev > 0) {
+    cout << "(16) A =  " << a << endl;
+    cout << "(16) B =  ((? == -A)" << b << endl;
+    cout << "(16) C = A+B  " << c << endl;
+  }
+  getMinMax(c, min, max);
+  if ((min != 0) || (max != 0)) {
+    cout << "(16) !!! ERROR Test B=-A  Min=" << min << " Max=" << max << endl;
+    rc += 256;
+  }
+  else cout << "(16) OK   Test B=-A  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 << " --> ODO (Diff. Mem. Mapping) A,CC: CMemoryMapping AR,B,C: 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> ar(nr,nc,BaseArray::FortranMemoryMapping);
+
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+  }
+
+  a.AddCst(2.,ar);
+  if (prtlev > 0) 
+    cout << "(1) AR = A+2 : a.AddCst(2,ar) : " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((fabs(min-22.) > 0.0001) || (fabs(max-22.) > 0.0001)) {
+    cout << "(1) !!! ERROR Test AR=A+2  a.AddCst(2,ar)   Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << "(1) OK   Test AR=A+2 a.AddCst(2,ar)  OK " << endl; 
+
+  a.SubCst(28.,ar,true);
+  if (prtlev > 0) 
+    cout << "(2) AR = 28-A : a.SubCst(28,ar,true) :  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((fabs(min-8.) > 0.0001) || (fabs(max-8.) > 0.0001)) {
+    cout << "(2) !!! ERROR Test AR=28-A  a.SubCst(28,ar,true) Min=" << min << " Max=" << max << endl;
+    rc += 2;
+  }
+  else cout << "(2) OK   Test AR=28-A  a.SubCst(28,ar,true) OK " << endl;
+ 
+  a.MulCst(3.,ar);
+  if (prtlev > 0) 
+    cout << "(3) AR = A*3= a.MulCst(3,ar)  " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((fabs(min-60.) > 0.0001) || (fabs(max-60.) > 0.0001)) {
+    cout << "(3) !!! ERROR Test AR=A*3  a.MulCst(3,ar) Min=" << min << " Max=" << max << endl;
+    rc += 4;
+  }
+  else cout << "(3) OK   Test AR=A*3  a.MulCst(3,ar) OK " << endl; 
+
+  a.DivCst(5.,ar);
+  if (prtlev > 0) 
+    cout << "(4) AR = A/5= a.DivCst(5,ar) : " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((fabs(min-4.) > 0.0001) || (fabs(max-4.) > 0.0001)) {
+    cout << "(4) !!! ERROR Test AR=A/5  a.DivCst(5,ar) Min=" << min << " Max=" << max << endl;
+    rc += 8;
+  }
+  else cout << "(4) OK   Test AR=A/5  a.DivCst(5,ar) OK " << endl; 
+
+  a.DivCst(140.,ar,true);
+  if (prtlev > 0) 
+    cout << "(5) AR = 140/A= a.DivCst(140.,ar,true) : " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((fabs(min-7.) > 0.0001) || (fabs(max-7.) > 0.0001)) {
+    cout << "(5) !!! ERROR Test AR=140/A  a.DivCst(140.,ar,true) Min=" << min << " Max=" << max << endl;
+    rc += 16;
+  }
+  else cout << "(5) OK   Test AR=140/A  a.DivCst(140.,ar,true) OK " << endl; 
+
+  ar -= 3.;  
+  if (prtlev > 0) 
+    cout << "(6) AR -= 3 " << ar << endl;
+  getMinMax(ar, min, max);
+  if ((min != 4) || (max != 4)) {
+    cout << "(6) !!! ERROR Test AR-=3  Min=" << min << " Max=" << max << endl;
+    rc += 32;
+  }
+  else cout << "(6) OK   Test AR-=3  OK " << endl; 
+
+  TMatrix<r_4> c(nr,nc,BaseArray::FortranMemoryMapping);
+  c = a-(b*2.0f);
+  if (prtlev > 0) cout << "(7) C = A-2*B=  " << c << endl;
+
+  getMinMax(c, min, max);
+  if ((fabs(min-2.) > 0.0001) || (fabs(max-2.) > 0.0001)) {
+    cout << "(7) !!! ERROR Test C=A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 64;
+  }
+  else cout << "(7) OK   Test C=A+2*B  OK " << endl; 
+
+  (a*4.0f+5.5f).DivElt(b,c);
+  if (prtlev > 0) cout << "(8) C = (A*4+12)/B = " << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-9.5) > 0.0001) || (fabs(max-9.5) > 0.0001)) {
+    cout << "(8) !!! ERROR Test C = (A*4+12)/B  Min=" << min << " Max=" << max << endl;
+    rc += 128;
+  }
+  else cout << "(8) 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 << "(9) A =  " << a << endl;
+    cout << "(9) B =  " << b << endl;
+    cout << "(9) C = 2A-2*B= " << c << endl;
+  }
+  c /= (nr*nc+1);
+  getMinMax(c, min, max);
+  if ((fabs(min-2.) > 0.0001) || (fabs(max-2.) > 0.0001)) {
+    cout << "(9) !!! ERROR Test C=2A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 256;
+  }
+  else cout << "(9) OK   Test3 C=2A+2*B  OK " << endl; 
+
+// ----------------------
+// Operation de type array +-*/ array 
+
+  a = 10.;
+  b = 4.;
+
+  (3.f*a).SubElt(2.f*b,c);
+  if (prtlev > 0)  cout << "(10) A=10, B=4, (3*a).SubElt(2*b,c)  C=" << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-22.) > 0.0001) || (fabs(max-22.) > 0.0001)) {
+    cout << "(10) !!! ERROR Test (3*a).SubElt(2*b,c)  Min=" << min << " Max=" << max << endl;
+    rc += 512;
+  }
+  else cout << "(10) OK   Test (3*a).SubElt(2.*b,c)  OK " << endl; 
+
+  (3.f*a).AddElt(2.f*b,c);
+  if (prtlev > 0)  cout << "(11) A=10, B=4, (3*a).AddElt(2*b,c) C= " << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-38.) > 0.0001) || (fabs(max-38.) > 0.0001)) {
+    cout << "(11) !!! ERROR Test (3*A).AddElt(2.*B,C)  Min=" << min << " Max=" << max << endl;
+    rc += 512;
+  }
+  else cout << "(11) OK   Test (3*a).AddElt(2*b,c) OK " << endl; 
+
+  a.MulElt(b+2.f,c);
+  if (prtlev > 0)  cout << "(12) A=10, B=4, a.MulElt(b+2,c) = " << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-60.) > 0.0001) || (fabs(max-60.) > 0.0001)) {
+    cout << "(12) !!! ERROR Test a.MulElt(b+2,c) Min=" << min << " Max=" << max << endl;
+    rc += 1024;
+  }
+  else cout << "(12) OK   Test A.MulElt(B+2,C)  OK " << endl; 
+
+  (3.f*a).DivElt(b+2.f,c);
+  if (prtlev > 0)  cout << "(13) A=10, B=4, (3*a).DivElt(b+2,c) C = " << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-5.) > 0.0001) || (fabs(max-5.) > 0.0001)) {
+    cout << "(13) !!! ERROR Test (3*a).DivElt(b+2,c) Min=" << min << " Max=" << max << endl;
+    rc += 1024;
+  }
+  else cout << "(13) OK  Test (3*A).DivElt(B+2,C)  OK " << endl; 
+
+  TMatrix<r_4> cc(nr,nc,BaseArray::CMemoryMapping);
+
+  (3.f*a).SubElt(2.f*b,cc);
+  if (prtlev > 0)  cout << "(14) A=10, B=4, (3*a).SubElt(2*b,cc)  " << cc << endl;
+  getMinMax(cc, min, max);
+  if ((fabs(min-22.) > 0.0001) || (fabs(max-22.) > 0.0001)) {
+    cout << "(14) !!! ERROR Test (3*a).SubElt(2*b,cc)  Min=" << min << " Max=" << max << endl;
+    rc += 2048;
+  }
+  else cout << "(14) OK   Test (3*A).SubElt(2*B,CC)  OK " << endl; 
+
+
+  (3.f*a).AddElt(2.f*b,cc);
+  if (prtlev > 0)  cout << "(15) A=10, B=4, (3*a).AddElt(2*b,cc) CC= " << cc << endl;
+  getMinMax(cc, min, max);
+  if ((fabs(min-38.) > 0.0001) || (fabs(max-38.) > 0.0001)) {
+    cout << "(15) !!! ERROR Test (3*a).AddElt(2*b,c)  Min=" << min << " Max=" << max << endl;
+    rc += 4096;
+  }
+  else cout << "(15) OK   Test (3*A).AddElt(2*B,CC) OK " << endl; 
+
+  a.MulElt(b+2.f,cc);
+  if (prtlev > 0)  cout << "(16) A=10, B=4, a.MulElt(b+2,c) = " << cc << endl;
+  getMinMax(cc, min, max);
+  if ((fabs(min-60.) > 0.0001) || (fabs(max-60.) > 0.0001)) {
+    cout << "(16) !!! ERROR Test A.MulElt(B+2,CC) Min=" << min << " Max=" << max << endl;
+    rc += 8192;
+  }
+  else cout << "(16) OK   Test A.MulElt(B+2,C)  OK " << endl; 
+
+  (3.f*a).DivElt(b+2.f,cc);
+  if (prtlev > 0)  cout << "(17) A=10, B=4, (3*a).DivElt(b+2,cc) C = " << cc << endl;
+  getMinMax(cc, min, max);
+  if ((fabs(min-5.) > 0.0001) || (fabs(max-5.) > 0.0001)) {
+    cout << "(17) !!! ERROR Test (3*a).DivElt(b+2,c) Min=" << min << " Max=" << max << endl;
+    rc += 16384;
+  }
+  else cout << "(17) OK  Test (3*A).DivElt(B+2,CC)  OK " << endl; 
+
+  a = 3.1;
+  b = -2.2;
+  r_4 sc = a.ScalarProduct(b);
+  r_4 sce = 0.;
+  for(int kkk=0; kkk<nr*nc; kkk++) sce += -2.2*3.1;
+  if (prtlev > 0)  cout << "(18) A=3, B=3, a.ScalarProduct(b)= " << sc << endl;
+  sc -= sce;
+  if ((fabs(sc) > 0.00001) || (fabs(sc) > 0.00001)) {
+    cout << "(18) !!! ERROR Test  a.ScalarProduct(b) sc-" <<  sce
+	 << " = " << sc << endl;
+    rc += 32768;
+  }
+  else cout << "(18) OK  Test a.ScalarProduct(b)  OK " << endl; 
+
+  TMatrix<r_4> mx(nr, nc), mxc(nr,nc,BaseArray::FortranMemoryMapping);
+  for(int ir=0; ir<nr; ir++)
+    for(int ic=0; ic<nc; ic++) mxc(ir, ic) = ir*1000+ic*6;
+  if (prtlev > 0)  cout << "(19) mx.Row()/Column() operations MXC=" << mxc << endl;
+  
+  TVector<r_4> cv(nr), rv(nc, BaseArray::RowVector, BaseArray::FortranMemoryMapping);
+  cv = RegularSequence(0, 1);
+  rv = RegularSequence(0, 1);
+  for(int ir=0; ir<nr; ir++)  { 
+    mx.Row(ir) = rv*3.f;
+    mx.Row(ir) *= 2.f;
+  }
+  for(int ic=0; ic<nc; ic++)  { 
+    mx.Column(ic) += cv*1000.f;
+  }
+  TMatrix<r_4> mxd = mx-mxc;
+  if (prtlev > 0)  { 
+    cout << "(19)  MX=" << mx << endl;
+    cout << "(19)  MXD=" << mxd << endl;
+  }
+  getMinMax(mxd, min, max);
+  if ((fabs(min) > 0.0001) || (fabs(max) > 0.0001)) {
+    cout << "(19) !!! ERROR Test mx.Row()/Column() operations Min=" << min << " Max=" << max << endl;
+    rc += 65536;
+  }
+  else cout << "(19) OK  Test mx.Row()/Column() operations  OK " << endl; 
+
+  a = RegularSequence(3.14, 1.3);
+  b = -a; 
+  c = a+b;
+  if (prtlev > 0) {
+    cout << "(20) A =  " << a << endl;
+    cout << "(20) B =  ((? == -A)" << b << endl;
+    cout << "(16) C = A+B  " << c << endl;
+  }
+  getMinMax(c, min, max);
+  if ((fabs(min) > 0.0001) || (fabs(max) > 0.0001)) {
+    cout << "(20) !!! ERROR Test B=-A  Min=" << min << " Max=" << max << endl;
+    rc += 131072;
+  }
+  else cout << "(20) OK   Test B=-A  OK " << endl; 
+  
+  return(rc);
+
+  return(rc);
+
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/exacmplnk.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/exacmplnk.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/exacmplnk.cc	(revision 3445)
@@ -0,0 +1,16 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/Tests/fitsServTest.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/fitsServTest.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/fitsServTest.cc	(revision 3445)
@@ -0,0 +1,147 @@
+//++
+// Verbatim	
+//
+
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/fitsioGorski.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/fitsioGorski.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/fitsioGorski.cc	(revision 3445)
@@ -0,0 +1,29 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+// Utilisation de la classe LocalMap<T>
+#include "sopnamsp.h"
+#include "ntoolsinit.h"
+#include "spheregorski.h"
+#include "ntuple.h"
+
+// Utilisation des generateurs aleatoires
+#include "srandgen.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_Nov2007/SophyaProg/Tests/fitsioImage.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/fitsioImage.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/fitsioImage.cc	(revision 3445)
@@ -0,0 +1,41 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+// Utilisation de la classe Image<T>
+#include "sopnamsp.h"
+#include "ntoolsinit.h"
+#include "cimage.h"
+// Utilisation des generateurs aleatoires
+#include "srandgen.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_Nov2007/SophyaProg/Tests/fitsioLocMap.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/fitsioLocMap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/fitsioLocMap.cc	(revision 3445)
@@ -0,0 +1,38 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+// Utilisation de la classe LocalMap<T>
+#include "sopnamsp.h"
+#include "ntoolsinit.h"
+#include "localmap.h"
+
+// Utilisation des generateurs aleatoires
+#include "srandgen.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_Nov2007/SophyaProg/Tests/fitsioSphere.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/fitsioSphere.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/fitsioSphere.cc	(revision 3445)
@@ -0,0 +1,33 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+// Utilisation de la classe LocalMap<T>
+#include "sopnamsp.h"
+#include "ntoolsinit.h"
+#include "spheregorski.h"
+
+// Utilisation des generateurs aleatoires
+#include "srandgen.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_Nov2007/SophyaProg/Tests/jtcpitarr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/jtcpitarr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/jtcpitarr.cc	(revision 3445)
@@ -0,0 +1,398 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "JTC/JTC.h"
+
+#include <math.h>
+#include <iostream>
+#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_Nov2007/SophyaProg/Tests/jtctarr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/jtctarr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/jtctarr.cc	(revision 3445)
@@ -0,0 +1,138 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "JTC/JTC.h"
+
+#include <math.h>
+#include <iostream>
+
+#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_Nov2007/SophyaProg/Tests/lpk.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/lpk.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/lpk.cc	(revision 3445)
@@ -0,0 +1,272 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+
+#include "srandgen.h"
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+#include "intflapack.h"
+
+
+int lpk_linsolve_mtx(int n);                             // ErrorCode = 8
+int lpk_svd_mtx(int l, int c, int wsf, bool covu=true);  // ErrorCode = 16
+int lpk_leastsquare_mtx(int l, int c);                   // ErrorCode = 32   
+int lpk_inverse_mtx(int l);                              // ErrorCode = 64
+
+static double TOLERANCE = 1.e-6;
+static int nprt = 100;
+static int prtlev = 1;
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+
+
+  if (narg < 2) {
+    cout << " lpk - LinAlg/LapackServer test \n" 
+	 << " Usage: lpk select [sizeL,C=5,5] [prtlev=1] \n" 
+	 << "             [nprtmax=100] [WorkSpaceSizeFactor=2] \n" 
+	 << "   select= linsolve svd svds lss inverse / all= \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"
+	 << "   inverse:  LapackServer::ComputeInverse() r_8 \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); 
+  if (narg > 3) prtlev = atoi(arg[3]);
+  if (narg > 4) nprt = atoi(arg[4]);
+  if (narg > 5) wsf = atoi(arg[5]);
+
+  cout << " lpk - LinAlg/LapackServer_Test sizeL,C=" << l << "," << c 
+       << " opt= " << opt << endl;
+  int rc = 0;
+  BaseArray::SetMaxPrint(nprt, prtlev);
+  try {
+    if (opt == "all") {
+      rc += lpk_linsolve_mtx(l);
+      rc += lpk_svd_mtx(l,c,wsf,true);
+      rc += lpk_leastsquare_mtx(l,c);
+      rc += lpk_inverse_mtx(l);
+    }
+    else 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 == "inverse") rc = lpk_inverse_mtx(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;
+  if (prtlev > 0) 
+    cout << " ------------ Vector X = \n " << x << "\n" << endl; 
+  for(i=0; i<n; i++) x(i) = GauRnd(2., 1.5);
+  b = a*x;
+
+  if (prtlev > 0) {
+    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) ");
+
+  if (prtlev > 0) 
+    cout << " ------------ Result B(=X ?) = \n " << b << "\n" << endl; 
+  Vector diff = b-x;
+  PrtTim(" End of Compute(diff)");
+  if (prtlev > 0) 
+    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(8);
+  } 
+  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; 
+  if (prtlev > 0) 
+    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() ");
+
+  if (prtlev > 0) 
+    cout << " ------------ Result S  = \n " << s << "\n" << endl; 
+  if (!covu) return(0);
+  if (prtlev > 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)");
+  if (prtlev > 0) 
+    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(16);
+  } 
+  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; 
+  if (prtlev > 0) {
+    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)));
+  if (prtlev > 0) {
+    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)");
+  if (prtlev > 0) 
+    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 32;
+  } 
+  return 0;
+
+}
+// -----------------------------------------------------------------------
+/* Nouvelle-Fonction */
+int lpk_inverse_mtx(int m)
+{
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+  cout << " lpk_inverse_mtx() - Test of LapackComputeInverse<r_8> " << endl;
+  
+  Matrix a(m , m), aa, ainv, idmx(m,m), mxprod, diff;
+  a = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+  aa = a;  // We make a copy of a, as it is modified by LapackServer
+  PrtTim(" End of a_inint");
+
+  cout << "\n   Calling  LapackInverse() .... " << endl;
+  ainv = LapackInverse(aa);
+  PrtTim(" End of LapackInverse(a)");
+  mxprod = a*ainv;
+  PrtTim(" End of mxprod = a*ainv");
+  idmx = IdentityMatrix();
+  PrtTim(" End of idmx = IdentityMatrix()");
+  diff = mxprod-idmx;
+  PrtTim(" End of Compute(diff)");
+
+  if (prtlev > 0) {
+    cout << " ------------ Matrix A = \n " << a << "\n" << endl; 
+    cout << " ------------ Matrix Inverse(A) = \n " << ainv << "\n" << endl; 
+    cout << " ------------ Matrix mxprod = A*Inverse(A) = \n " << mxprod << "\n" << endl; 
+  }
+  double min,max;
+  diff.MinMax(min, max);
+  PrtTim(" End of diffCheck");
+  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 64;
+  }
+  return 0;
+
+}
+
Index: /tags/V_Nov2007/SophyaProg/Tests/makepi
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/makepi	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/makepi	(revision 3445)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(SOPHYADEVREP)/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 -L/usr/X11R6/lib -lXm -lXt -lX11 -lm 
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl 
+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_Nov2007/SophyaProg/Tests/obj_fits.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/obj_fits.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/obj_fits.cc	(revision 3445)
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/ovharr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/ovharr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/ovharr.cc	(revision 3445)
@@ -0,0 +1,642 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "ctimer.h"
+#include "timing.h"
+#include "srandgen.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,*m4);  
+
+	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,m4); 
+      }
+    }
+
+    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++) m4[i] = m1[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_Nov2007/SophyaProg/Tests/pizthr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/pizthr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/pizthr.cc	(revision 3445)
@@ -0,0 +1,410 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include "zthread.h"
+
+#include <math.h>
+#include <unistd.h>
+#include <iostream>
+#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("Cancel", 10203);
+AppendMenu(m[1]);
+m[2] = new PIMenu(Menubar(),"Thread-2");
+m[2]->AppendItem("Cancel", 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;
+    //    }
+    while (XtAppPending(*appctx) != 0) {
+      amon.lock(); //  <ZThread> 
+      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]->cancel();  //  <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_Nov2007/SophyaProg/Tests/ppftswap.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/ppftswap.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/ppftswap.cc	(revision 3445)
@@ -0,0 +1,129 @@
+#include "sopnamsp.h"
+#include "sophyainit.h"
+#include "array.h"
+#include "fiondblock.h"
+#include "fioarr.h"
+#include "tarrinit.h"
+
+
+int main(int narg, char* arg[])
+{
+
+cout << " ------------------------------------------------ " << endl;
+cout << " ---------- Start of ppftswap program ----------- " << endl;
+
+try {
+  SophyaInit();
+  // Phase d'ecriture - remplissage de fichier PPF 
+  cout << ">>>> Create/Write PPF stream  ppfts.ppf " << endl;
+  {  
+#define DSZ_SWT  8
+    // Vecteur pour garder les positions des tableaux ecrits 
+    TVector<int_8> sw_fpos(10, BaseArray::RowVector);
+    vector<int_8> swsvfp;
+    // Tableau pour les donnees a ecrire (en mode swap)
+    // ds le flot PPersist
+    NDataBlock<int_4> sw_data(DSZ_SWT);
+    // Objets divers a ecrire dans le meme flot 
+    NDataBlock<int_4> idb(16);
+    idb = 16;
+    NDataBlock<r_4> fdb(7);
+    fdb = 4.5;
+    TVector<int_4> iv(7, BaseArray::RowVector);
+    iv = RegularSequence(5.,3.);
+    TMatrix<r_4> mx(3,5);
+    mx = RegularSequence(0.14,0.2);
+    // -------------------------------------------------------------
+    // Generation de donnees et ecriture (pour lecture en mode swap)
+    // -------------------------------------------------------------
+    POutPersist so("ppfts.ppf");
+    cout << " Writing data for testing swap ... " << endl;
+    for(int i=0; i<sw_fpos.Size(); i++) {
+      for(int j=0; j<sw_data.Size(); j++) sw_data(j) = i*100+j;
+      // Ecriture de tag de positionnement
+      sw_fpos(i) = so.WritePositionTag();
+      swsvfp.push_back(sw_fpos(i));
+
+      // Ecriture de donnees correspondantes
+      // Il vaut mieux ne pas utiliser un objet a ce stade
+      so.PutI4s(sw_data.Data(), sw_data.Size());
+      cout << "[" << i << "] Written data (Pos=" << sw_fpos(i) 
+	   << ") : " << sw_data << endl;
+    }
+    // On ecrit d'autres objets 
+    cout << " Writing DataBlock idb= \n" << idb << endl;
+    so << idb;
+    cout << " Writing Vector iv" << iv << endl;
+    so << iv;
+    cout << " Writing DataBlock fdb with TagName FDB : \n" << fdb << endl;
+    so << PPFNameTag("FDB") << fdb;
+    cout << " Writing Matrix mtx with TagName MTX " << mx << endl;
+    so << PPFNameTag("MTX") << mx;
+    // On ecrit finalement Les Positions Tag
+    string posttable="PosTagTable";
+    so.WriteNameTag(posttable);
+    // Ecriture de la table des PositionTags
+    // C'est cette methode qui doit etre utilisee en principe
+    so.PutPosTagTable(swsvfp);
+    // On ecrit aussi le TVecteur sw_fpos
+    so.PutObject(sw_fpos);
+    
+  }
+  
+  // Phase de relecture 
+  cout << ">>>> Reading objects from PPF stream  ppfts.ppf " << endl;
+  {
+    TVector<int_8> sw_fpos;
+    vector<int_8> swsvfp;
+    NDataBlock<int_4> sw_data(DSZ_SWT);
+    NDataBlock<int_4> idb;
+    NDataBlock<r_4> fdb;
+    TVector<int_4> iv;
+    TMatrix<r_4> mx;
+
+    PInPersist si("ppfts.ppf");
+    si >> idb;
+    cout << " Read-OK DataBlock idb= \n" << idb << endl;
+    si.GetObject(iv);
+    cout << " Read-OK Vector iv= " << iv << endl;
+    si >> PPFNameTag("MTX") >> mx;
+    cout << " Read-OK Matrix mx= " << mx << endl;
+    string tname = "FDB";
+    si.GotoNameTag(tname);
+    si >> fdb;
+    cout << " Read-OK DataBlock fdb at tag FDB : \n" << fdb << endl;
+    cout << " --- Reading PositionTagTable ... " << endl;
+    si >> PPFNameTag("PosTagTable");
+    si >> sw_fpos;
+    cout << " Read-OK sw_fpos= " << sw_fpos << endl;
+    for(int i=0; i<sw_fpos.Size(); i++) {
+      // On se positionne 
+      si.GotoPositionTag(sw_fpos(i));
+      // On lit le tableau
+      si.GetI4s(sw_data.Data(), sw_data.Size());
+      cout << "[" << i << "] Read data (Pos=" << sw_fpos(i) 
+	   << ") : " << sw_data << endl;
+    }
+    // On lit quand meme le PosTagTable pour verification 
+    cout << " Reading the PositionTagTable .... " << endl;
+    si >> PPFNameTag("PosTagTable");
+    si.GetPosTagTable(swsvfp); 
+    for(int k=0; k<swsvfp.size(); k++)  
+      cout << swsvfp[k] << "  ";
+    cout << endl;
+  }
+  
+}
+catch (PThrowable & exc) {
+  cerr << " ppftswap/Catched Exception " << (string)typeid(exc).name() 
+       << " - Msg= " << exc.Msg() << endl;
+}
+catch (...) {
+  cerr << " ppftswap/some other exception was caught ! " << endl;
+}
+
+ cout << " ----------- End of ppftswap program ------------ " << endl;
+ cout << " ------------------------------------------------ " << endl;
+
+}
+
Index: /tags/V_Nov2007/SophyaProg/Tests/programs
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/programs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/programs	(revision 3445)
@@ -0,0 +1,43 @@
+arrt arrt.o
+carrt carrt.o
+lpk lpk.o
+obj_fits obj_fits.o
+ovharr ovharr.o
+pizthr pizthr.o
+ppftswap ppftswap.o
+spar spar.o
+sphg0 sphg0.o
+sph2lm sph2lm.o
+tcmd tcmd.o
+tcxxcmpldynl tcxxcmpldynl.o
+tdcr tdcr.o
+tdynl tdynl.o
+tfft tfft.o
+thash thash.o
+timg timg.o
+tmxv tmxv.o
+tnt tnt.o
+tobjio2 tobjio2.o
+tobjio tobjio.o
+tpipe tpipe.o
+tsimplex tsimplex.o
+tsphereecp tsphereecp.o
+tspm2 tspm2.o
+tspm tspm.o
+tstboloread tstboloread.o
+tstcolread tstcolread.o
+tstdtable tstdtable.o
+tstndblk tstndblk.o
+tstppfwrapstl tstppfwrapstl.o
+tstsegdb tstsegdb.o
+tswfits tswfits.o
+tnfits tnfits.o
+tfitsdt tfitsdt.o
+tsttmat tsttmat.o
+tsttminv tsttminv.o
+tsttvec tsttvec.o
+ttimestamp ttimestamp.o
+zthr zthr.o
+tmtrnd tmtrnd.o
+tmtrnd3 tmtrnd3.o
+tmtdt tmtdt.o
Index: /tags/V_Nov2007/SophyaProg/Tests/smakefile
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/smakefile	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/smakefile	(revision 3445)
@@ -0,0 +1,1703 @@
+include $(SOPHYABASE)/include/sophyamake.inc
+
+ 
+PROGS = $(SOPHYAEXEP)arrt $(SOPHYAEXEP)carrt $(SOPHYAEXEP)lpk $(SOPHYAEXEP)obj_fits $(SOPHYAEXEP)ovharr $(SOPHYAEXEP)pizthr $(SOPHYAEXEP)ppftswap $(SOPHYAEXEP)spar $(SOPHYAEXEP)sphg0 $(SOPHYAEXEP)sph2lm $(SOPHYAEXEP)tcmd $(SOPHYAEXEP)tcxxcmpldynl $(SOPHYAEXEP)tdcr $(SOPHYAEXEP)tdynl $(SOPHYAEXEP)tfft $(SOPHYAEXEP)thash $(SOPHYAEXEP)timg $(SOPHYAEXEP)tmxv $(SOPHYAEXEP)tnt $(SOPHYAEXEP)tobjio2 $(SOPHYAEXEP)tobjio $(SOPHYAEXEP)tpipe $(SOPHYAEXEP)tsimplex $(SOPHYAEXEP)tsphereecp $(SOPHYAEXEP)tspm2 $(SOPHYAEXEP)tspm $(SOPHYAEXEP)tstboloread $(SOPHYAEXEP)tstcolread $(SOPHYAEXEP)tstdtable $(SOPHYAEXEP)tstndblk $(SOPHYAEXEP)tstppfwrapstl $(SOPHYAEXEP)tstsegdb $(SOPHYAEXEP)tswfits $(SOPHYAEXEP)tnfits $(SOPHYAEXEP)tfitsdt $(SOPHYAEXEP)tsttmat $(SOPHYAEXEP)tsttminv $(SOPHYAEXEP)tsttvec $(SOPHYAEXEP)ttimestamp $(SOPHYAEXEP)zthr $(SOPHYAEXEP)tmtrnd $(SOPHYAEXEP)tmtrnd3 $(SOPHYAEXEP)tmtdt
+ 
+all: $(PROGS)
+ 
+clean:
+	rm -f $(PROGS)
+	rm -f $(SOPHYAOBJP)tmtdt.o $(SOPHYAOBJP)tmtrnd3.o $(SOPHYAOBJP)tmtrnd.o $(SOPHYAOBJP)zthr.o $(SOPHYAOBJP)ttimestamp.o $(SOPHYAOBJP)tsttvec.o $(SOPHYAOBJP)tsttminv.o $(SOPHYAOBJP)tsttmat.o $(SOPHYAOBJP)tfitsdt.o $(SOPHYAOBJP)tnfits.o $(SOPHYAOBJP)tswfits.o $(SOPHYAOBJP)tstsegdb.o $(SOPHYAOBJP)tstppfwrapstl.o $(SOPHYAOBJP)tstndblk.o $(SOPHYAOBJP)tstdtable.o $(SOPHYAOBJP)tstcolread.o $(SOPHYAOBJP)tstboloread.o $(SOPHYAOBJP)tspm.o $(SOPHYAOBJP)tspm2.o $(SOPHYAOBJP)tsphereecp.o $(SOPHYAOBJP)tsimplex.o $(SOPHYAOBJP)tpipe.o $(SOPHYAOBJP)tobjio.o $(SOPHYAOBJP)tobjio2.o $(SOPHYAOBJP)tnt.o $(SOPHYAOBJP)tmxv.o $(SOPHYAOBJP)timg.o $(SOPHYAOBJP)thash.o $(SOPHYAOBJP)tfft.o $(SOPHYAOBJP)tdynl.o $(SOPHYAOBJP)tdcr.o $(SOPHYAOBJP)tcxxcmpldynl.o $(SOPHYAOBJP)tcmd.o $(SOPHYAOBJP)sph2lm.o $(SOPHYAOBJP)sphg0.o $(SOPHYAOBJP)spar.o $(SOPHYAOBJP)ppftswap.o $(SOPHYAOBJP)pizthr.o $(SOPHYAOBJP)ovharr.o $(SOPHYAOBJP)obj_fits.o $(SOPHYAOBJP)lpk.o $(SOPHYAOBJP)carrt.o $(SOPHYAOBJP)arrt.o
+ 
+arrt: $(SOPHYAEXEP)arrt
+	echo $@ " done"
+$(SOPHYAEXEP)arrt: $(SOPHYAOBJP)arrt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)arrt.o $(SOPHYAALLSLBLIST)
+ 
+carrt: $(SOPHYAEXEP)carrt
+	echo $@ " done"
+$(SOPHYAEXEP)carrt: $(SOPHYAOBJP)carrt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)carrt.o $(SOPHYAALLSLBLIST)
+ 
+lpk: $(SOPHYAEXEP)lpk
+	echo $@ " done"
+$(SOPHYAEXEP)lpk: $(SOPHYAOBJP)lpk.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)lpk.o $(SOPHYAALLSLBLIST)
+ 
+obj_fits: $(SOPHYAEXEP)obj_fits
+	echo $@ " done"
+$(SOPHYAEXEP)obj_fits: $(SOPHYAOBJP)obj_fits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)obj_fits.o $(SOPHYAALLSLBLIST)
+ 
+ovharr: $(SOPHYAEXEP)ovharr
+	echo $@ " done"
+$(SOPHYAEXEP)ovharr: $(SOPHYAOBJP)ovharr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ovharr.o $(SOPHYAALLSLBLIST)
+ 
+pizthr: $(SOPHYAEXEP)pizthr
+	echo $@ " done"
+$(SOPHYAEXEP)pizthr: $(SOPHYAOBJP)pizthr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)pizthr.o $(SOPHYAALLSLBLIST)
+ 
+ppftswap: $(SOPHYAEXEP)ppftswap
+	echo $@ " done"
+$(SOPHYAEXEP)ppftswap: $(SOPHYAOBJP)ppftswap.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ppftswap.o $(SOPHYAALLSLBLIST)
+ 
+spar: $(SOPHYAEXEP)spar
+	echo $@ " done"
+$(SOPHYAEXEP)spar: $(SOPHYAOBJP)spar.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)spar.o $(SOPHYAALLSLBLIST)
+ 
+sphg0: $(SOPHYAEXEP)sphg0
+	echo $@ " done"
+$(SOPHYAEXEP)sphg0: $(SOPHYAOBJP)sphg0.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)sphg0.o $(SOPHYAALLSLBLIST)
+ 
+sph2lm: $(SOPHYAEXEP)sph2lm
+	echo $@ " done"
+$(SOPHYAEXEP)sph2lm: $(SOPHYAOBJP)sph2lm.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)sph2lm.o $(SOPHYAALLSLBLIST)
+ 
+tcmd: $(SOPHYAEXEP)tcmd
+	echo $@ " done"
+$(SOPHYAEXEP)tcmd: $(SOPHYAOBJP)tcmd.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tcmd.o $(SOPHYAALLSLBLIST)
+ 
+tcxxcmpldynl: $(SOPHYAEXEP)tcxxcmpldynl
+	echo $@ " done"
+$(SOPHYAEXEP)tcxxcmpldynl: $(SOPHYAOBJP)tcxxcmpldynl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tcxxcmpldynl.o $(SOPHYAALLSLBLIST)
+ 
+tdcr: $(SOPHYAEXEP)tdcr
+	echo $@ " done"
+$(SOPHYAEXEP)tdcr: $(SOPHYAOBJP)tdcr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tdcr.o $(SOPHYAALLSLBLIST)
+ 
+tdynl: $(SOPHYAEXEP)tdynl
+	echo $@ " done"
+$(SOPHYAEXEP)tdynl: $(SOPHYAOBJP)tdynl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tdynl.o $(SOPHYAALLSLBLIST)
+ 
+tfft: $(SOPHYAEXEP)tfft
+	echo $@ " done"
+$(SOPHYAEXEP)tfft: $(SOPHYAOBJP)tfft.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tfft.o $(SOPHYAALLSLBLIST)
+ 
+thash: $(SOPHYAEXEP)thash
+	echo $@ " done"
+$(SOPHYAEXEP)thash: $(SOPHYAOBJP)thash.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)thash.o $(SOPHYAALLSLBLIST)
+ 
+timg: $(SOPHYAEXEP)timg
+	echo $@ " done"
+$(SOPHYAEXEP)timg: $(SOPHYAOBJP)timg.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)timg.o $(SOPHYAALLSLBLIST)
+ 
+tmxv: $(SOPHYAEXEP)tmxv
+	echo $@ " done"
+$(SOPHYAEXEP)tmxv: $(SOPHYAOBJP)tmxv.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmxv.o $(SOPHYAALLSLBLIST)
+ 
+tnt: $(SOPHYAEXEP)tnt
+	echo $@ " done"
+$(SOPHYAEXEP)tnt: $(SOPHYAOBJP)tnt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tnt.o $(SOPHYAALLSLBLIST)
+ 
+tobjio2: $(SOPHYAEXEP)tobjio2
+	echo $@ " done"
+$(SOPHYAEXEP)tobjio2: $(SOPHYAOBJP)tobjio2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tobjio2.o $(SOPHYAALLSLBLIST)
+ 
+tobjio: $(SOPHYAEXEP)tobjio
+	echo $@ " done"
+$(SOPHYAEXEP)tobjio: $(SOPHYAOBJP)tobjio.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tobjio.o $(SOPHYAALLSLBLIST)
+ 
+tpipe: $(SOPHYAEXEP)tpipe
+	echo $@ " done"
+$(SOPHYAEXEP)tpipe: $(SOPHYAOBJP)tpipe.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tpipe.o $(SOPHYAALLSLBLIST)
+ 
+tsimplex: $(SOPHYAEXEP)tsimplex
+	echo $@ " done"
+$(SOPHYAEXEP)tsimplex: $(SOPHYAOBJP)tsimplex.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsimplex.o $(SOPHYAALLSLBLIST)
+ 
+tsphereecp: $(SOPHYAEXEP)tsphereecp
+	echo $@ " done"
+$(SOPHYAEXEP)tsphereecp: $(SOPHYAOBJP)tsphereecp.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsphereecp.o $(SOPHYAALLSLBLIST)
+ 
+tspm2: $(SOPHYAEXEP)tspm2
+	echo $@ " done"
+$(SOPHYAEXEP)tspm2: $(SOPHYAOBJP)tspm2.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tspm2.o $(SOPHYAALLSLBLIST)
+ 
+tspm: $(SOPHYAEXEP)tspm
+	echo $@ " done"
+$(SOPHYAEXEP)tspm: $(SOPHYAOBJP)tspm.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tspm.o $(SOPHYAALLSLBLIST)
+ 
+tstboloread: $(SOPHYAEXEP)tstboloread
+	echo $@ " done"
+$(SOPHYAEXEP)tstboloread: $(SOPHYAOBJP)tstboloread.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstboloread.o $(SOPHYAALLSLBLIST)
+ 
+tstcolread: $(SOPHYAEXEP)tstcolread
+	echo $@ " done"
+$(SOPHYAEXEP)tstcolread: $(SOPHYAOBJP)tstcolread.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstcolread.o $(SOPHYAALLSLBLIST)
+ 
+tstdtable: $(SOPHYAEXEP)tstdtable
+	echo $@ " done"
+$(SOPHYAEXEP)tstdtable: $(SOPHYAOBJP)tstdtable.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstdtable.o $(SOPHYAALLSLBLIST)
+ 
+tstndblk: $(SOPHYAEXEP)tstndblk
+	echo $@ " done"
+$(SOPHYAEXEP)tstndblk: $(SOPHYAOBJP)tstndblk.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstndblk.o $(SOPHYAALLSLBLIST)
+ 
+tstppfwrapstl: $(SOPHYAEXEP)tstppfwrapstl
+	echo $@ " done"
+$(SOPHYAEXEP)tstppfwrapstl: $(SOPHYAOBJP)tstppfwrapstl.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstppfwrapstl.o $(SOPHYAALLSLBLIST)
+ 
+tstsegdb: $(SOPHYAEXEP)tstsegdb
+	echo $@ " done"
+$(SOPHYAEXEP)tstsegdb: $(SOPHYAOBJP)tstsegdb.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tstsegdb.o $(SOPHYAALLSLBLIST)
+ 
+tswfits: $(SOPHYAEXEP)tswfits
+	echo $@ " done"
+$(SOPHYAEXEP)tswfits: $(SOPHYAOBJP)tswfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tswfits.o $(SOPHYAALLSLBLIST)
+ 
+tnfits: $(SOPHYAEXEP)tnfits
+	echo $@ " done"
+$(SOPHYAEXEP)tnfits: $(SOPHYAOBJP)tnfits.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tnfits.o $(SOPHYAALLSLBLIST)
+ 
+tfitsdt: $(SOPHYAEXEP)tfitsdt
+	echo $@ " done"
+$(SOPHYAEXEP)tfitsdt: $(SOPHYAOBJP)tfitsdt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tfitsdt.o $(SOPHYAALLSLBLIST)
+ 
+tsttmat: $(SOPHYAEXEP)tsttmat
+	echo $@ " done"
+$(SOPHYAEXEP)tsttmat: $(SOPHYAOBJP)tsttmat.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttmat.o $(SOPHYAALLSLBLIST)
+ 
+tsttminv: $(SOPHYAEXEP)tsttminv
+	echo $@ " done"
+$(SOPHYAEXEP)tsttminv: $(SOPHYAOBJP)tsttminv.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttminv.o $(SOPHYAALLSLBLIST)
+ 
+tsttvec: $(SOPHYAEXEP)tsttvec
+	echo $@ " done"
+$(SOPHYAEXEP)tsttvec: $(SOPHYAOBJP)tsttvec.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tsttvec.o $(SOPHYAALLSLBLIST)
+ 
+ttimestamp: $(SOPHYAEXEP)ttimestamp
+	echo $@ " done"
+$(SOPHYAEXEP)ttimestamp: $(SOPHYAOBJP)ttimestamp.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)ttimestamp.o $(SOPHYAALLSLBLIST)
+ 
+zthr: $(SOPHYAEXEP)zthr
+	echo $@ " done"
+$(SOPHYAEXEP)zthr: $(SOPHYAOBJP)zthr.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)zthr.o $(SOPHYAALLSLBLIST)
+ 
+tmtrnd: $(SOPHYAEXEP)tmtrnd
+	echo $@ " done"
+$(SOPHYAEXEP)tmtrnd: $(SOPHYAOBJP)tmtrnd.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtrnd.o $(SOPHYAALLSLBLIST)
+ 
+tmtrnd3: $(SOPHYAEXEP)tmtrnd3
+	echo $@ " done"
+$(SOPHYAEXEP)tmtrnd3: $(SOPHYAOBJP)tmtrnd3.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtrnd3.o $(SOPHYAALLSLBLIST)
+ 
+tmtdt: $(SOPHYAEXEP)tmtdt
+	echo $@ " done"
+$(SOPHYAEXEP)tmtdt: $(SOPHYAOBJP)tmtdt.o
+	$(CXXLINK) $(CXXTEMPFLG) -o $@ $(SOPHYAOBJP)tmtdt.o $(SOPHYAALLSLBLIST)
+ 
+$(SOPHYAOBJP)arrt.o: arrt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  arrt.cc
+ 
+$(SOPHYAOBJP)carrt.o: carrt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  carrt.cc
+ 
+$(SOPHYAOBJP)lpk.o: lpk.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)intflapack.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  lpk.cc
+ 
+$(SOPHYAOBJP)obj_fits.o: obj_fits.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)fitsxntuple.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsntuple.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  obj_fits.cc
+ 
+$(SOPHYAOBJP)ovharr.o: ovharr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ovharr.cc
+ 
+$(SOPHYAOBJP)pizthr.o: pizthr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)pisysdep.h \
+  $(SOPHYAINCP)piapplx.h \
+  $(SOPHYAINCP)piapplgen.h \
+  $(SOPHYAINCP)pimsghandler.h \
+  $(SOPHYAINCP)picontainerx.h \
+  $(SOPHYAINCP)picontainergen.h \
+  $(SOPHYAINCP)piwdgx.h \
+  $(SOPHYAINCP)piwdggen.h \
+  $(SOPHYAINCP)picolist.h \
+  $(SOPHYAINCP)pimenubarx.h \
+  $(SOPHYAINCP)pimenubargen.h \
+  $(SOPHYAINCP)pimenux.h \
+  $(SOPHYAINCP)pimenugen.h \
+  $(SOPHYAINCP)picons.h \
+  $(SOPHYAINCP)pistdwdgx.h \
+  $(SOPHYAINCP)pistdwdggen.h \
+  $(SOPHYAINCP)pibwdgx.h \
+  $(SOPHYAINCP)pibwdggen.h \
+  $(SOPHYAINCP)picmap.h \
+  $(SOPHYAINCP)picmapx.h \
+  $(SOPHYAINCP)picmapgen.h \
+  $(SOPHYAINCP)pigraphx.h \
+  $(SOPHYAINCP)pigraphgen.h \
+  $(SOPHYAINCP)pifontx.h \
+  $(SOPHYAINCP)pifontgen.h \
+  $(SOPHYAINCP)pigrcoord.h \
+  $(SOPHYAINCP)pilineatt.h \
+  $(SOPHYAINCP)pigraphuc.h \
+  $(SOPHYAINCP)pievthandler.h \
+  $(SOPHYAINCP)psfile.h \
+  $(SOPHYAINCP)pigraphps.h \
+  $(SOPHYAINCP)piwindowx.h \
+  $(SOPHYAINCP)piwindowgen.h \
+  $(SOPHYAINCP)piperiodx.h \
+  $(SOPHYAINCP)periodic.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pizthr.cc
+ 
+$(SOPHYAOBJP)ppftswap.o: ppftswap.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)fiondblock.h \
+  $(SOPHYAINCP)tarrinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ppftswap.cc
+ 
+$(SOPHYAOBJP)spar.o: spar.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)resusage.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  spar.cc
+ 
+$(SOPHYAOBJP)sph2lm.o: sph2lm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)mapoperation.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)fftwserver.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)fftservintf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sph2lm.cc
+ 
+$(SOPHYAOBJP)sphg0.o: sphg0.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)HEALPixUtils.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sphg0.cc
+ 
+$(SOPHYAOBJP)tcmd.o: tcmd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)cexpre.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)rpneval.h \
+  $(SOPHYAINCP)commander.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tcmd.cc
+ 
+$(SOPHYAOBJP)tcxxcmpldynl.o: tcxxcmpldynl.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)cxxcmplnk.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tcxxcmpldynl.cc
+ 
+$(SOPHYAOBJP)tdcr.o: tdcr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)psighand.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tdcr.cc
+ 
+$(SOPHYAOBJP)tdynl.o: tdynl.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)pdlmgr.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tdynl.cc
+ 
+$(SOPHYAOBJP)tfft.o: tfft.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fftmserver.h \
+  $(SOPHYAINCP)fftmayer.h \
+  $(SOPHYAINCP)fftwserver.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tfft.cc
+ 
+$(SOPHYAOBJP)tfitsdt.o: tfitsdt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fitshdtable.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsblkrw.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tfitsdt.cc
+ 
+$(SOPHYAOBJP)thash.o: thash.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  thash.cc
+ 
+$(SOPHYAOBJP)timg.o: timg.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)cimage.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)fiondblock.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timg.cc
+ 
+$(SOPHYAOBJP)tmtdt.o: tmtdt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sspvflags.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitshdtable.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtdt.cc
+ 
+$(SOPHYAOBJP)tmtrnd3.o: tmtrnd3.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbtri.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)stsrand.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtrnd3.cc
+ 
+$(SOPHYAOBJP)tmtrnd.o: tmtrnd.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)stsrand.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmtrnd.cc
+ 
+$(SOPHYAOBJP)tmxv.o: tmxv.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tmxv.cc
+ 
+$(SOPHYAOBJP)tnfits.o: tnfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)fitsarrhand.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fiosinit.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tnfits.cc
+ 
+$(SOPHYAOBJP)tnt.o: tnt.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)xntuple.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tnt.cc
+ 
+$(SOPHYAOBJP)tobjio2.o: tobjio2.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tobjio2.cc
+ 
+$(SOPHYAOBJP)tobjio.o: tobjio.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)histos.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)histos2.h \
+  $(SOPHYAINCP)ntuple.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)fioarr.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tobjio.cc
+ 
+$(SOPHYAOBJP)tpipe.o: tpipe.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tpipe.cc
+ 
+$(SOPHYAOBJP)tsimplex.o: tsimplex.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)simplex.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)generalfit.h \
+  $(SOPHYAINCP)generaldata.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)poly.h \
+  $(SOPHYAINCP)peida.h \
+  $(SOPHYAINCP)utils.h \
+  $(SOPHYAINCP)perrors.h \
+  $(SOPHYAINCP)fmath.h \
+  $(SOPHYAINCP)generalfunc.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsimplex.cc
+ 
+$(SOPHYAOBJP)tsphereecp.o: tsphereecp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)samba.h \
+  $(SOPHYAINCP)alm.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)nbmath.h \
+  $(SOPHYAINCP)triangmtx.h \
+  $(SOPHYAINCP)bruit.h \
+  $(SOPHYAINCP)circle.h \
+  $(SOPHYAINCP)geometry.h \
+  $(SOPHYAINCP)lambdaBuilder.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)mlobe.h \
+  $(SOPHYAINCP)prefcount.h \
+  $(SOPHYAINCP)scan.h \
+  $(SOPHYAINCP)sphericaltransformserver.h \
+  $(SOPHYAINCP)fftservintf.h \
+  $(SOPHYAINCP)fftpserver.h \
+  $(SOPHYAINCP)tod.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsphereecp.cc
+ 
+$(SOPHYAOBJP)tspm2.o: tspm2.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)sambainit.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)fitstarray.h \
+  $(SOPHYAINCP)fitsfile.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)fitsspherehealpix.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tspm2.cc
+ 
+$(SOPHYAOBJP)tspm.o: tspm.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)skymapinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)skymap.h \
+  $(SOPHYAINCP)spherethetaphi.h \
+  $(SOPHYAINCP)sphericalmap.h \
+  $(SOPHYAINCP)smathconst.h \
+  $(SOPHYAINCP)pixelmap.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)spherepos.h \
+  $(SOPHYAINCP)unitvector.h \
+  $(SOPHYAINCP)vector3d.h \
+  $(SOPHYAINCP)longlat.h \
+  $(SOPHYAINCP)utilgeom.h \
+  $(SOPHYAINCP)datatype.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)spherehealpix.h \
+  $(SOPHYAINCP)HEALPixUtils.h \
+  $(SOPHYAINCP)localmap.h \
+  $(SOPHYAINCP)sphereecp.h \
+  $(SOPHYAINCP)fiospherethetaphi.h \
+  $(SOPHYAINCP)fiospherehealpix.h \
+  $(SOPHYAINCP)fiolocalmap.h \
+  $(SOPHYAINCP)fiosphereecp.h \
+  $(SOPHYAINCP)tod.h \
+  $(SOPHYAINCP)misstime.h \
+  $(SOPHYAINCP)timing.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tspm.cc
+ 
+$(SOPHYAOBJP)tstboloread.o: tstboloread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fboloread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fabtcolread.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fabtwriter.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstboloread.cc
+ 
+$(SOPHYAOBJP)tstcolread.o: tstcolread.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)fabtcolread.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fabtwriter.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstcolread.cc
+ 
+$(SOPHYAOBJP)tstdtable.o: tstdtable.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ctimer.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)swppfdtable.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppftpointerio.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstdtable.cc
+ 
+$(SOPHYAOBJP)tstndblk.o: tstndblk.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstndblk.cc
+ 
+$(SOPHYAOBJP)tstppfwrapstl.o: tstppfwrapstl.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)ppfwrapstlv.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstppfwrapstl.cc
+ 
+$(SOPHYAOBJP)tstsegdb.o: tstsegdb.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)fiosegdb.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)ppftpointerio.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)ppfswapper.h \
+  $(SOPHYAINCP)ppfwrapstlv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tstsegdb.cc
+ 
+$(SOPHYAOBJP)tsttmat.o: tsttmat.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttmat.cc
+ 
+$(SOPHYAOBJP)tsttminv.o: tsttminv.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)intflapack.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttminv.cc
+ 
+$(SOPHYAOBJP)tsttvec.o: tsttvec.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)array.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)fioarr.h \
+  $(SOPHYAINCP)sopemtx.h \
+  $(SOPHYAINCP)srandgen.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tsttvec.cc
+ 
+$(SOPHYAOBJP)tswfits.o: tswfits.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)fitsswapper.h \
+  $(SOPHYAINCP)swsegdb.h \
+  $(SOPHYAINCP)segdatablock.h \
+  $(SOPHYAINCP)thsafeop.h \
+  $(SOPHYAINCP)fitsinoutfile.h \
+  $(SOPHYAINCP)FitsIO/fitsio.h \
+  $(SOPHYAINCP)FitsIO/longnam.h \
+  $(SOPHYAINCP)fitsblkrw.h \
+  $(SOPHYAINCP)basedtable.h \
+  $(SOPHYAINCP)ntupintf.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)fiosinit.h \
+  $(SOPHYAINCP)swfitsdtable.h \
+  $(SOPHYAINCP)fitshandler.h \
+  $(SOPHYAINCP)datatable.h \
+  $(SOPHYAINCP)fitshdtable.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  tswfits.cc
+ 
+$(SOPHYAOBJP)ttimestamp.o: ttimestamp.cc \
+  $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)histinit.h \
+  $(SOPHYAINCP)ntoolsinit.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)ppfwrapstlv.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ttimestamp.cc
+ 
+$(SOPHYAOBJP)zthr.o: zthr.cc $(SOPHYAINCP)sopnamsp.h \
+  $(SOPHYAINCP)zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)resusage.h \
+  $(SOPHYAINCP)tmatrix.h \
+  $(SOPHYAINCP)tarray.h \
+  $(SOPHYAINCP)basarr.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)objfio.h \
+  $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)ppfnametag.h \
+  $(SOPHYAINCP)dvlist.h \
+  $(SOPHYAINCP)ndatablock.h \
+  $(SOPHYAINCP)utilarr.h \
+  $(SOPHYAINCP)tmatrix_tsnl.h \
+  $(SOPHYAINCP)tvector.h \
+  $(SOPHYAINCP)tvector_tsnl.h \
+  $(SOPHYAINCP)matharr.h \
+  $(SOPHYAINCP)tarrinit.h \
+  $(SOPHYAINCP)sophyainit.h \
+  $(SOPHYAINCP)timing.h \
+  $(SOPHYAINCP)ctimer.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  zthr.cc
+ 
Index: /tags/V_Nov2007/SophyaProg/Tests/spar.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/spar.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/spar.cc	(revision 3445)
@@ -0,0 +1,203 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+#include "resusage.h"
+
+/*  Programme de test de vitesse des operations sur TArray  */
+/*  de SOPHYA   Reza, Juillet 2004                          */
+
+/* Flag a activer pour compiler avec SOPHYA V <= 1.7 */
+/* #define VSOP_17  */
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 5) {
+    cout << " spar TSel NLoop NRow NCols \n" 
+	 << " TSel=0/1/2: Option de selection test 7 avec sous-tableaux \n" 
+	 << "      0: Ne pas faire test 7 (couteux en V <= 1.7) \n" 
+	 << "      1: Test 7 1ere partie (sans AA.Row(r)*x+BB.Row(r)*y \n" 
+	 << "      2: Test 7 complet  \n" 
+	 << " NLoop: Nombre d'iterations \n" 
+	 << " NRow,NCols: Taille de matrices \n" 
+	 << " Exemple: spar 0 10 800 1000 (Grande taille memoire) \n" 
+	 << "          spar 1 100 80 100 (Petite taille memoire) \n" << endl; 
+    return 1;
+  }
+  int ope = atoi(arg[1]);
+  int nloop = atoi(arg[2]);
+  int nr = atoi(arg[3]);
+  int nc = atoi(arg[4]);
+
+  cout << " ------------------------------------------------- " << endl;
+  cout << " spar = SpeedArray Ope=" << ope << " NLoop= " << nloop 
+       << " NR= " << nr << " NC= " << nc << endl;
+  cout << " ------------------------------------------------- " << endl;
+
+  ResourceUsage res;
+  cout << "(1) Initialisation matrices Ac,Bc,Af,Bf - Random" << endl;
+  Matrix A(nr, nc, BaseArray::CMemoryMapping);
+  Matrix B(nr, nc, BaseArray::CMemoryMapping);  
+  Matrix Ac(nr, nc, BaseArray::CMemoryMapping);
+  Matrix Bc(nr, nc, BaseArray::CMemoryMapping);  
+  Matrix Af(nr, nc, BaseArray::FortranMemoryMapping);
+  Matrix Bf(nr, nc, BaseArray::CMemoryMapping);
+
+  A = RandomSequence(RandomSequence::Flat);
+  B = RandomSequence(RandomSequence::Flat);
+
+  Ac = A;
+  Bc = B;
+  Af = A;
+  Bf = B;
+
+  PrtTim("(1) ApresInit Ac,Bc,Af,Bf ");
+  cout << res;
+
+  long nop, noptot;
+  noptot = 0;
+
+  cout << "(2) Operations de type A *= c , A += B  " << endl;
+  Ac = A;  Bc = B;
+  Af = A;  Bf = B;
+  for(int k=0; k<nloop; k++) {
+    Ac *= 1.2;
+    Bf *= 1.15;
+    Ac -= Bc;
+    Af += Bf;
+  }
+  nop = nloop*nr*nc*4/1000;
+  cout << "(2) Op A *= c, A += B   (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (2) ");
+
+  cout << "(3) Operations de type C = A*c , E = A+B  " << endl;
+  Ac = A;  Bc = B;
+  Af = A;  Bf = B;
+  for(int k=0; k<nloop; k++) {
+    Matrix C = Ac*8.5;
+    C = Bf*54.;
+    Matrix E = Ac-Bc;
+    E = Af+Bc;
+  }
+  nop = nloop*nr*nc*4/1000;
+  cout << "(3) Op  C = A*c , E = A+B    (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (3) ");
+
+
+  cout << "(4) Operations de type C = A*x+B*y  " << endl;
+  Ac = A;  Bc = B;
+  Af = A;  Bf = B;
+  for(int k=0; k<nloop; k++) {
+    Matrix Ccc = Ac*4.+2.5*Bc;
+    Matrix Ccf = Ac*4.+2.5*Bf;
+    Matrix Cff = Af*4.+2.5*Bc;
+  }
+  nop = nloop*3*nr*nc*3/1000;
+  cout << "(4) Op   C = A*x+B*y  (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (4) ");
+
+
+  cout << "(5) Operations de type C = A*x+B*y-z*A-B*t  " << endl;
+  Ac = A;  Bc = B;
+  Af = A;  Bf = B;
+  for(int k=0; k<nloop; k++) {
+    Matrix Ccc = Ac*4.+2.5*Bc-0.3*Ac-Bc*0.8;
+    Matrix Ccf = Ac*4.+2.5*Bf-0.3*Ac-Bf*0.8;
+    Matrix Cff = Af*4.+2.5*Bf-0.3*Af-Bf*0.8;
+  }
+  nop = nloop*3*nr*nc*7/1000;
+  cout << "(5) Op  C =  A*x+B*y-z*A-B*t (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (5) ");
+
+  cout << "(6) Operations de type (A*x+y*B).MulElt(B-A, ->D)  " << endl;
+  Ac = A;  Bc = B;
+  Af = A;  Bf = B;
+#ifndef VSOP_17
+  for(int k=0; k<nloop; k++) {
+    Matrix Dc;
+    (Ac+4.+6.5*Bc).MulElt(Bc-Ac, Dc);
+    Matrix Dcf;
+    (Ac+4.+6.5*Bf).MulElt(Bc-Af, Dcf);
+    Matrix Df;
+    (Af+4.+6.5*Bf).MulElt(Bf-Af, Df);
+  }
+#else
+  for(int k=0; k<nloop; k++) {
+    Matrix Dc;
+    Dc = (Ac+4.+6.5*Bc);
+    Dc.MulElt(Bc-Ac);
+    Matrix Dcf = (Ac+4.+6.5*Bf);
+    Dcf.MulElt(Bc-Af);
+    Matrix Df = (Af+4.+6.5*Bf);
+    Df.MulElt(Bf-Af);
+  }
+#endif
+  nop = nloop*3*nr*nc*5/1000;
+  cout << "(6.a) Op  (A*x+y*B).MulElt(B-A, ->D) (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (6.a) ");
+
+  for(int k=0; k<nloop; k++) {
+    Matrix Dc = (Ac+4.+6.5*Bc) && (Bc-Ac);
+    Matrix Dcf = (Ac+4.+6.5*Bf) && (Bc-Af);
+    Matrix Df = (Af+4.+6.5*Bf) && (Bf-Af);
+  }
+  nop = nloop*3*nr*nc*5/1000;
+  cout << "(6.b) Op  D = (A*x+y*B) && (B-A) (KFLOP) = " << nop << endl;
+  noptot += nop;
+  PrtTim(" Apres (6.b) ");
+  cout << res;
+
+  // Les operations sur sous-tableaux sont beaucoup trop couteux V <= 1.7 
+  if (ope > 0) {
+    cout << "\n(7) Op  AA.Row() *= ... [AA.Row()*x+BB.Row()*y  ope=2] " << endl;
+    Ac = A;  Bc = B;
+    Af = A;  Bf = B;
+#ifdef VSOP_17
+    cout << " !!! Operations couteuses en V<=1.7 " << endl;
+#endif
+    Matrix AA,BB;
+    Vector * vr = new Vector[nr];
+    for(int k=0; k<nloop; k++) {
+      AA = Ac;
+      BB = Bc;
+      for(int r=0; r<nr; r++) {
+        double fac = (5*r+0.33);
+        AA.Row(r) *= fac;
+        BB.Row(r) += AA.Row(r)*4.;
+	if (ope < 2) continue;
+#ifdef VSOP_17
+      // Attention, si on ne fait pas le SetSize a la main, ca explose en memoire en V <= 1.7
+        vr[r].SetSize(AA.Row(r).Size(), AA.Row(r).GetVectorType());
+        vr[r] =  AA.Row(r)*3.14+BB.Row(r)*5.6;
+#else
+        vr[r] =  AA.Row(r)*3.14+BB.Row(r)*5.6;
+#endif
+      }
+    }
+    if (ope < 2) nop = nloop*nr*nc*3/1000;
+    else nop = nloop*nr*nc*6/1000;
+    cout << "(7) Op AA.Row() *=  (KFLOP) = " << nop << endl;
+    noptot += nop;
+    PrtTim(" Apres (7) ");
+    cout << res;
+    delete[] vr;
+  }
+  cout << " ------------------------------------------------- " << endl;
+  cout << res;  
+  PrtTim("Fin spar  ");
+  cout << " ------ Fin spar N_OP_TOT= " << noptot << " (KFLOP)  ------- " << endl;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/sph2lm.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/sph2lm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/sph2lm.cc	(revision 3445)
@@ -0,0 +1,561 @@
+#include "sopnamsp.h"
+#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_Nov2007/SophyaProg/Tests/sphg0.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/sphg0.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/sphg0.cc	(revision 3445)
@@ -0,0 +1,24 @@
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/t_scan.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/t_scan.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/t_scan.cc	(revision 3445)
@@ -0,0 +1,71 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+
+#include <math.h>
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/tblitz.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tblitz.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tblitz.cc	(revision 3445)
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <iostream>
+#include "sopnamsp.h"
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tcmd.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tcmd.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tcmd.cc	(revision 3445)
@@ -0,0 +1,430 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+#include "sophyainit.h"
+#include "timing.h"
+#include "cexpre.h"
+#include "rpneval.h"
+#include "commander.h"
+
+/* -------------- Programme test de SOPHYA   tcmd.cc  
+   Test des classes Timer , CExpressionEvaluator , 
+   RPNExpressionEvaluator , Commander  , 
+   csh> tcmd commander
+   csh> tcmd cexptst
+   csh> tcmd rpntst
+   csh  tcmd timer
+   ------ R. Ansari ---- 2003-2007    --------------- */
+
+class TCmdExecutor : public CmdExecutor {
+public:
+  TCmdExecutor(Commander& cmd);
+  virtual ~TCmdExecutor() { }
+
+  virtual int Execute(string& keyw,vector<string>& args, string& toks);
+};
+
+TCmdExecutor::TCmdExecutor(Commander& cmd)
+{ 
+string hgrp = "TCmdExecutor";
+string usage,kw;
+
+kw = "ls";
+usage = "ls: Execute /usr/bin/ls \n";
+cmd.RegisterCommand(kw, usage, this, hgrp);
+kw = "mv";
+usage = "mv: Execute /usr/bin/mv \n";
+cmd.RegisterCommand(kw, usage, this, hgrp);
+kw = "cp";
+usage = "cp: Execute /usr/bin/cp \n";
+cmd.RegisterCommand(kw, usage, this, hgrp);
+}
+
+int TCmdExecutor::Execute(string& kw, vector<string>& args, string& toks)
+{
+  if ((kw!="ls")&&(kw!="mv")&&(kw!="cp"))  return 99; 
+  string cmd;
+  if (kw == "ls")     cmd = "/usr/bin/ls " ; 
+  else if (kw == "mv") cmd = "/usr/bin/mv " ;
+  else if (kw == "cp") cmd = "/usr/bin/cp " ;
+  else cmd = "/usr/bin/echo " ;
+  for(int kk=0; kk<args.size(); kk++)  { cmd += args[kk]; cmd += ' '; }
+  cout << "TCmdExecutor::Execute() : Executing " << cmd << endl;
+  return system(cmd.c_str());
+}
+
+int  InputLoop(Commander & cmd);
+int tst_cexpreval();  // Test de CExpressionEvaluator 
+int tst_rpneval();    // Test de RPNEvaluator 
+int tst_timer();      // Test de Timer
+
+/* --Main-- */
+int main(int narg, char *arg[])
+{
+
+  if (narg < 2) {
+    cout << " Usage: tcmd S=commander/cexptst/rpntst/timer \n" 
+	 << "  S= commander: Commader class test \n"
+	 << "  S= cexptst: CExpressionEvaluator class test \n"
+	 << "  S= rpntst: RPNExpressionEvaluator class test \n"
+	 << "  S= timer: Timer class test \n" << endl;
+    return 0;
+  }
+  string opt = arg[1];
+  SophyaInit();
+  InitTim();
+  int rc = 0;
+  cout << " ---- tcmd S= " << opt << " (commander/evaluator test) " << endl;
+  try {
+    if (opt == "commander") {
+      Commander cmd;
+      TCmdExecutor cmdex(cmd);
+      InputLoop(cmd);
+    }
+    else if (opt == "cexptst") rc = tst_cexpreval();
+    else if (opt == "rpntst")   rc = tst_rpneval();
+    else if (opt == "timer")   rc = tst_timer();
+    else {
+      cout << " tcmd/error: Unknown select option: " << opt << endl;
+      rc = 9;
+    }
+  }
+ 
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (std::exception & e) {
+    cerr << " exception catched : e.what()= " << e.what() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+  PrtTim(" End of tcmd ");
+  PrtTim("--Fin tcmd ");
+  return(rc);
+}
+
+/* --Fonction-- */
+int  InputLoop(Commander & cmd)
+{
+  cout << " ====================================================== " << endl;
+  cout << " ==============   Test of Commander class  ============ " << endl;
+  cout << " ====================================================== " << endl;
+  cout << " tcmd/InputLoop() : Type in your commands, \n" 
+       << "     end with a blanck line OR <Cntl>D " << endl;
+  int line = 0;
+  bool fg = true;
+  char buff[1024];
+  char * ret;
+  while (fg) {
+    printf("%d-%s ", line+1, cmd.GetCurrentPrompt().c_str());
+    fflush(stdout);
+    buff[0] = '\0';
+    ret = fgets(buff, 1024, stdin);
+    buff[1023] = '\0';
+    if (ret && ( (buff[0] != '\0') && (buff[0] != '\n') && (buff[0] != '\r')) ) { 
+      buff[strlen(buff)-1] = '\0';
+      string cline = buff;
+      cmd.Interpret(cline);
+      line++;
+    }
+    else fg = false;
+  }
+  cout << " \n Total " << line << " lines from stdin -> Commander " << endl;
+  if (line > 0) return(0);
+  else return(1);
+}
+
+/* -- Fonction Test de CExpressionEvaluator -- */
+int tst_cexpreval()
+{
+  double res;
+  int nok=0;
+  int nerr=0;
+  int nerrparse=0;
+  int num = 0;
+  cout << " ====================================================== " << endl;
+  cout << " ============   Test of CExpressionEvaluator ========== " << endl;
+  cout << " ====================================================== " << endl;
+  try {
+    try {
+      num++;
+      CExpressionEvaluator cex("4.e-1");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? " << ( res=4.e-1 ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      } 
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    try {
+      num++;
+      CExpressionEvaluator cex("4*3+8");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? 4*3+8 = " << ( res=4*3+8 ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      } 
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    try {
+      num++;
+      CExpressionEvaluator cex("cos(0)+2");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? cos(0)+2 = " << ( res=cos(0.)+2 ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+
+    try {
+      num++;
+      CExpressionEvaluator cex("4+3*8");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? 4+3*8 = " << ( res=4+3*8 ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+
+    try {
+      num++;
+      CExpressionEvaluator cex("4+3*6*2");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? 4+3*6*2 = " << ( res=4+3*6*2 ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    try {
+      num++;
+      CExpressionEvaluator cex("(12+3*6*cos(0))");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? (12+3*6*cos(0))  = " 
+	   << ( res=(12+3*6*cos(0.)) ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    try {
+      num++;    
+      CExpressionEvaluator cex("(12+3*6*cos(0))-(5*pow(2,2))");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? (12+3*6*cos(0))-(5*pow(2,2))  = " 
+	   << ( res=(12+3*6*cos(0.))-(5*pow(2.,2.)) ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    try {
+      num++;    
+      CExpressionEvaluator cex("sin(Pi/6)+E");
+      cout << "CExpr=sin(Pi/6)+E " << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << " =? sin(M_PI/6)+M_E  = " 
+	   << ( res=sin(M_PI/6)+M_E ) << endl;
+      if (fabs(cex.Value()-res) > 1.e-9) {
+	cout << " ERREUR CALCUL " << cex << endl;
+	nerr++;
+      }
+      else nok++;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+    // Expression avec erreur de syntaxe 
+   cout << " >>>>> Expression avec erreur <<<<<< " << endl;
+   try {
+      num++;    
+      CExpressionEvaluator cex("6**8");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << endl;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+   try {
+      num++;    
+      CExpressionEvaluator cex("6*(8+4");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << endl;
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+
+   try {
+      num++;    
+      CExpressionEvaluator cex("6*sin(4,)+12");
+      cout << "CExpr=" << cex; 
+      cout << " -> cex.Value() = " << cex.Value() << endl; 
+    }
+    catch (CExprException& err) {
+      nerrparse++;
+      cout << "Exp[" << num << "]  Exception: " << err.Msg() << endl; 
+    }
+    cout << "  [" << num << "] CExprBase::NbCreate() = " << CExprBase::NbCreate() 
+	 << "CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+
+  }
+  catch (CExprException& err) {
+    cout << " Exception: " << err.Msg() << endl; 
+  }
+
+  cout << "-------- CExprBase::NbCreate() = " << CExprBase::NbCreate() << " CExprBase::NbDelete()=" <<  CExprBase::NbDelete() << endl;
+  cout << "--- NExpr= " << num << " NOk= " <<  nok << " NErr=" << nerr << " NErrParse=" << nerrparse << endl;
+  if ( (nok == 8) && (nerr == 0) && (nerrparse == 3) ) return 0;
+  else return 99;
+}
+
+/* -- Fonction Test de CExpressionEvaluator -- */
+int tst_rpneval()
+{
+  int num = 0;
+  cout << " ====================================================== " << endl;
+  cout << " ============ Test of RPNExpressionEvaluator ========== " << endl;
+  cout << " ====================================================== " << endl;
+  try {
+    { 
+      num++;
+      RPNExpressionEvaluator rpn("4 2 print + 3 * ");
+      cout << "4 2 + 3 * -> rpn.Value() = " << rpn.Value() << endl;
+    }
+    {
+      num++;
+      RPNExpressionEvaluator rpn("1 2 3 4 5 sum");
+      cout << "1 2 3 4 5 sum -> rpn.Value() = " << rpn.Value() << endl;
+    }
+    {
+      num++;
+      RPNExpressionEvaluator rpn("4 3 pow");
+      cout << "4 3 pow -> rpn.Value() = " << rpn.Value() << endl;
+    }
+  }
+  catch (RPNExprException& err) {
+    cout << "RPNExp[" << num << "]  Exception: " << err.Msg() << endl; 
+  }
+
+  return 0;
+}
+
+/* --Fonction-- */
+int  tst_timer() 
+{
+  TIMEF ;
+  cout << "**** tcmd.cc : Test class SOPHYA::Timer() **** " << endl;
+  Timer tm("tcmd::Timer", false);
+  int N = 10000000;
+  double * x = new double[N];
+  for(int k=0; k<N; k++) x[k] = k*0.0001;
+  for(int k=0; k<N; k++) x[k] = sin(x[k]);
+  for(int k=0; k<N; k++) x[k] = cos(x[k]);
+  tm.Split();
+  cout << " Step1: PARTIAL CPU=" << tm.PartialCPUTime() 
+       << " Elapsed= " << tm.PartialElapsedTime() << endl;
+  cout << " Step1: TOTAL CPU=" << tm.TotalCPUTime() 
+       << "  Elapsed= " << tm.TotalElapsedTime() << endl;
+
+  for(int k=0; k<N; k++) x[k] *= 8.5; 
+  for(int k=0; k<N; k++) x[k] = tan(x[k]);
+
+  tm.Split();
+  cout << " Step2: PARTIAL CPU=" << tm.PartialCPUTime() 
+       << " Elapsed= " << tm.PartialElapsedTime() << endl;
+  cout << " Step2: TOTAL CPU=" << tm.TotalCPUTime() 
+       << "  Elapsed= " << tm.TotalElapsedTime() << endl;
+
+  for(int k=0; k<N; k++) x[k] = sin(x[k]);
+  for(int k=0; k<N; k++) x[k] = cos(x[k]);
+  for(int k=0; k<N; k++) x[k] *= 15.5; 
+  for(int k=0; k<N; k++) x[k] = sin(x[k]);
+
+  tm.Split();
+  cout << " Step3: PARTIAL CPU=" << tm.PartialCPUTime() 
+       << " Elapsed= " << tm.PartialElapsedTime() << endl;
+  cout << " Step3: TOTAL CPU=" << tm.TotalCPUTime() 
+       << "  Elapsed= " << tm.TotalElapsedTime() << endl;
+
+
+  delete x;
+}
+
Index: /tags/V_Nov2007/SophyaProg/Tests/tcxxcmpldynl.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tcxxcmpldynl.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tcxxcmpldynl.cc	(revision 3445)
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/tdcr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tdcr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tdcr.cc	(revision 3445)
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "sopnamsp.h"
+#include "math.h"
+#include <iostream>
+#include <string>
+
+// Pour le test 
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "psighand.h"
+
+
+#include "fmath.h"
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tdynl.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tdynl.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tdynl.cc	(revision 3445)
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+#include "sopnamsp.h"
+#include "tarrinit.h"
+#include "array.h"
+
+#include "pdlmgr.h"
+#include "pexceptions.h"
+#include "timing.h"
+
+// Fonction de test qu'on reproduit dans le fichier CTestFileName
+double testfunc_dynl(double x, double y)
+{
+  return (exp(-x)+sin(y)*x);
+}
+
+typedef double (* MyDlFunctionOfXY) (double x, double y);
+
+int main(int narg, char *arg[])
+{
+  SophyaInit();
+  InitTim();
+
+  if (narg < 3) {
+    cout << " --- tdynl -- test de la classe PDynLinkMgr --- \n " 
+         << " Usage: tdynl TmpDirName/ CTestFileName\n" 
+	 << " Exemple: tdynl /tmp/ toto.c \n" << endl;
+   return(0);
+  }
+
+  try {
+    string TmpDirName = arg[1];
+    string CTestFileName = arg[2];
+    string cfilename = TmpDirName + CTestFileName;
+    {
+      ofstream of(cfilename.c_str());
+      of << "#include <math.h> \n "
+	 << "double myf_dyl(double x, double y) \n"
+	 << "{ \n" 
+	 << " return (exp(-x)+sin(y)*x); \n"
+	 << "} \n" << endl;
+      cout << " File " << cfilename << "created ... " << endl;
+      }
+
+    cout << " Calling PDynLinkMgr::BuildFromCFile(" << cfilename << ")" << endl;
+    PDynLinkMgr::SetTmpDir(TmpDirName);
+    PDynLinkMgr * dyl = PDynLinkMgr::BuildFromCFile(cfilename);
+    PrtTim(" End of Compile-Link ");
+    if (dyl != NULL) {
+      MyDlFunctionOfXY f = (MyDlFunctionOfXY)dyl->GetFunction("myf_dyl");  
+      if (f != NULL) {
+	cout << " DlFunction f dyl.GetFunction(myf_dyl) linked OK - calling f() " << endl;
+	cout << "f(0,1)= " << f(0.,1.) << "  ?= testfunc_dynl(0,1)= " << testfunc_dynl(0.,1.) << endl;
+	cout << "f(1,1)= " << f(1.,1.) << "  ?= testfunc_dynl(1,1)= " << testfunc_dynl(1.,1.) << endl;
+	cout << "f(-1,2.5)= " << f(-1.,2.5) << "  ?= testfunc_dynl(-1,2.5)= " << testfunc_dynl(-1.,2.5) << endl;
+      } 
+      else {
+	cout << " ERROR linking DlFunction f !!! " << endl;
+      }
+    delete dyl;
+    }
+    else cout << " ERROR Creating shared object !!! " << 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 tdynl ");
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/testfitsio.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/testfitsio.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/testfitsio.cc	(revision 3445)
@@ -0,0 +1,144 @@
+//++
+// Verbatim	
+//
+
+#include <iostream>
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/tfft.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tfft.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tfft.cc	(revision 3445)
@@ -0,0 +1,341 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <ctype.h>
+#include <iostream>
+#include <typeinfo>
+
+#include "srandgen.h"
+#include "matharr.h"
+#include "fftpserver.h"
+#include "fftmserver.h"
+#include "fftmayer.h"
+#include "fftwserver.h"
+#include "ntoolsinit.h"
+
+#include "timing.h"
+
+/*  --------------------------------------------------------- */
+/*  ----       Programme de test de calcul de FFT        ---  */
+/*  ----          par les FFTServer de SOPHYA            ---  */
+/*  2000-2005      -   C. Magneville,  R. Ansari              */
+/*      Test FFT-1D real<>complex complex<>complex            */
+/*  Aide/Liste d'arguments :                                  */
+/*  csh> tfft                                                 */
+/*  Tests de base     ( ==> Rc=0 )                            */
+/*  csh> tfft 15 P                                            */
+/*  csh> tfft 16 P                                            */  
+/*  csh> tfft 15 W                                            */
+/*  csh> tfft 16 W                                            */ 
+/*  csh> tfft 1531 P D 0 50 0.0002                            */
+/*  csh> tfft 1220 P D 0 50 0.0002                            */
+/*  csh> tfft 1531 W D 0 50 0.0002                            */
+/*  csh> tfft 1220 W D 0 50 0.0002                            */
+/*  --------------------------------------------------------- */
+
+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;
+
+static  int prtlev = 0;
+
+//-------------------------------------------------
+template <class T>
+void TestFFTPack(T seuil, sa_size_t 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>
+int TestFFTS(T seuil, FFTServerInterface & ffts, sa_size_t 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);
+
+  if (inp_typ_random) {
+    cout << " TestFFTS/Random input vector ... " << endl;
+    ino = in = RandomSequence() ; // Nombre aleatoire gaussienne - sigma=1, mean=0
+    ComplexMathArray< T > cma;
+    TVector< T > im(num);
+    im = RandomSequence(RandomSequence::Flat);
+    inc = cma.FillFrom(in, im);
+  }
+  else {
+    cout << " TestFFTS/Random input vector = 0.5+cos(2x)+2sin(4x)... " << endl;
+    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 / Length= " << num << endl;
+  if (prtlev > 0) 
+    cout << in << endl; 
+
+  int ndiff = 0;
+  int rc = 0;
+
+  cout << "\n ----  Testing FFT-1D(T, complex<T>) ---- " << endl;
+  ffts.FFTForward(in, outc);
+  if (prtlev > 0) 
+    cout << " FourierCoefs: outc= \n" << outc << endl;
+
+  ffts.FFTBackward(outc, bk);
+  if (prtlev > 0) 
+    cout << " Backward: bk= \n" << bk << endl;
+ 
+  dif = bk*fact - in;
+  if (prtlev > 0) 
+    cout << " Difference dif= \n" << 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;
+ 
+  if (ndiff != 0)  rc += 4;
+
+  cout << "\n ----  Testing FFT-1D(complex<T>, complex<T>) ---- " << endl;
+  ffts.FFTForward(inc, outc);
+  if (prtlev > 0) 
+    cout << " FourierCoef , outc= \n" << outc << endl;
+
+  ffts.FFTBackward(outc, bkc);
+  if (prtlev > 0) 
+    cout << " Backward , bkc= \n " << bkc << endl;
+ 
+  difc = bkc*complex<T>(fact,0.) - inc;
+  if (prtlev > 0) 
+    cout << " Difference , difc= \n " << 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;
+
+  if (ndiff != 0)  rc += 8;
+  return rc;
+}
+
+inline void MayerFFTForw(r_4* d, int sz) {
+  fht_r4(d, sz);
+}
+inline void MayerFFTForw(r_8* d, int sz) {
+  fht_r8(d, sz);
+}
+
+//-------------------------------------------------
+template <class T>
+int MultiFFTTest(T t, sa_size_t sz, int nloop, bool fgp)
+{
+  cout <<" ===> MultiFFTTest<T=r_" << sizeof(T) << "> NLoop= " << nloop << " ArrSz= " << sz << endl;  
+  TVector< T > in(sz), incopie(sz);
+
+  incopie = in = RandomSequence();
+  FFTPackServer fftp(false);
+  TVector< complex<T> > outc;
+    
+  PrtTim("MultiFFT-LoopStart");
+
+  if (fgp) {
+    cout << " --- Test effectue avec FFTPack " << endl;
+    for(int kk=0; kk<nloop; kk++) {
+      in = incopie;
+      //      fftp.FFTForward(in, outc);
+      fftp.fftf(sz, in.Data());
+    }
+  }
+  else { 
+    cout << " --- Test effectue avec FFTMayer " << endl;
+    for(int kk=0; kk<nloop; kk++) {
+      in = incopie;
+      //      in += 0.01;
+      MayerFFTForw(in.Data(), sz);
+    }
+  }
+  PrtTim("MultiFFT-LoopEnd");
+  cout << " ----- End ---- MultiFFTTest<T> ----" << endl;
+  return 0;
+}
+
+
+
+//-------------------------------------------------
+//-------------------------------------------------
+//-------------------------------------------------
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 3) {
+    cout << "tfft/ args error - \n  Usage tfft size p/P/M/W [f/d/F/D  PrtLev=0 MaxNPrt=50 diffthr] \n" 
+	 << "    OR  tfft size P/M FL/DL/FZ/DZ  [NFFT=10]  \n" 
+	 << " 1D real/complex-FFT test (FFTServer) \n"
+	 << " size: input vector length \n " 
+	 << " p=FFTPackTest  P=FFTPack, M=FFTMayer, W= FFTWServer \n " 
+         << " F/f:float, D/d:double F/D:random in_vector (default=D) \n" 
+         << "  FL/DL : perform NFFT on a serie of float[size] or double[size] " 
+         << "  FZ/DZ : perform NFFT on a series of complex<float>[size] or complex<double>[size] " 
+         << " diffthr : Threshold for diff checks (=10^-6/10^-4 double/float)" 
+	 << endl;
+    return(1);
+  }
+
+  FFTPackServer fftp;
+  FFTMayerServer fftm;
+
+  FFTWServer fftw;
+
+  sa_size_t sz = atol(arg[1]);
+  int nprt = 50;
+  if (narg > 4) prtlev = atoi(arg[4]);
+  if (narg > 5) nprt = atoi(arg[5]);
+  BaseArray::SetMaxPrint(nprt, prtlev);
+  float fs = 1.e-4;
+  double ds = 1.e-6;
+  if (narg > 6) fs = ds = atof(arg[6]);
+
+  if (sz < 2) sz = 2;
+
+  char dtyp = 'D';
+  if (narg > 3) dtyp = *arg[3];
+  inp_typ_random = true;
+  if (islower(dtyp))  inp_typ_random = false;
+  dtyp = toupper(dtyp);
+
+
+  FFTServerInterface * ffts;
+  if (*arg[2] == 'M')  ffts = fftm.Clone();
+  else if (*arg[2] == 'W')  ffts = fftw.Clone();
+  else ffts = fftp.Clone();
+
+  int nloop = 0;
+  bool fgpack = true;
+  if (arg[3][1] == 'L') {  // MultiFFT test 
+    nloop = 10;
+    if (narg > 4) nloop = atoi(arg[4]);
+    if (*arg[2] == 'M')  fgpack = false;
+  }
+
+
+  cout << "\n ============================================= \n"
+       << " ------ Testing FFTServer " << typeid(*ffts).name() << "\n"
+       << "   VecSize= " << sz << " InputType= " 
+       << ( (inp_typ_random ) ? " random " : " fixed(sin+cos) ") << "\n"
+       << " =============================================== " << endl;
+
+  int rc = 0;
+  try {
+    if (dtyp == 'D') {
+      cout << "   ------ Testing FFTServer for double (r_8)----- " << endl;
+      if (*arg[2] == 'p') TestFFTPack(ds, sz);
+      else if (nloop > 0) rc = MultiFFTTest(ds, sz, nloop, fgpack);
+      else rc = TestFFTS(ds, *ffts, sz);
+    }
+    else {
+      cout << "   ------ Testing FFTServer for float (r_4)----- " << endl;
+      if (*arg[2] == 'p') TestFFTPack(fs, sz);
+      else if (nloop > 0) rc = MultiFFTTest(fs, sz, nloop, fgpack);
+      else rc = TestFFTS(fs, *ffts, sz);
+    }
+  }
+  catch(PThrowable& exc ) {
+    cerr << "TestFFT-main() , Catched exception: \n" << exc.Msg() << endl;
+    rc = 97;
+  }
+  catch(std::exception ex) {
+    cerr << "TestFFT-main() , Catched exception ! " << (string)(ex.what()) << endl;
+    rc = 98;
+  }
+  catch(...) {
+    cerr << "TestFFT-main() , Catched ... exception ! " << endl;
+    rc = 99;
+  }
+  PrtTim("End of tfft ");
+  delete ffts;
+  cout << " =========== End of tfft Rc= " << rc << " =============" << endl;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tfitsdt.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tfitsdt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tfitsdt.cc	(revision 3445)
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.h"
+#include "histinit.h"
+#include "datatable.h"
+#include "fitshdtable.h"
+#include "swfitsdtable.h"
+
+/* 
+   Programme de test lecture-ecriture FITS de DataTable
+    + test classe SwFitsDataTable
+      Oct 2005 - Jan 2006
+*/
+
+void test_fdtable() ; 
+
+int main(int narg, char *arg[])
+{
+  SophyaInit();
+  try {
+    test_fdtable();
+  }
+  catch(PThrowable exc ) {
+    cerr << "tfitsdt-main() , Catched exception: \n" << exc.Msg() << endl;
+  }
+  catch(std::exception ex) {
+    cerr << "tfitsdt-main() , Catched exception ! " << (string)(ex.what()) << endl;
+  }
+  catch(...) {
+    cerr << "tfitsdt-main() , Catched ... ! " << endl;
+  }
+}
+
+
+void test_fdtable() 
+{
+  int NL = 600;
+  DataTable refdt(100); // Reference DataTable - for tests 
+
+  cout << "======= test_fdtable: Simple DataTable+FITS test ======= " << endl;
+  {
+    cout << "1/ Creating DataTable / Writing to FITS " << endl;
+    DataTable dt(64);
+    dt.AddIntegerColumn("line");
+    dt.AddDoubleColumn("x");
+    dt.AddFloatColumn("f_sin");
+    dt.AddDoubleColumn("f_x2");
+    dt.AddStringColumn("str_line");
+    dt.AddComplexColumn("cmplx_cos_sin");
+    MuTyV rec[10];
+    char sbuff[32];
+    cout << " Filling ... (NLines=" << NL << ")" << endl;
+    for(int k = 0; k<NL; k++) {
+      rec[0] = k;
+      double x = M_PI*k/100.;
+      double fx = sin(x)*cos(x);
+      rec[1] = x+1;
+      rec[2] = sin(x);
+      rec[3] = x*x;
+      sprintf(sbuff, "SL-%d", k);
+      rec[4] = sbuff;
+      double sx = sin(x);
+      double cx = cos(x);
+      rec[5] = complex<r_4>(cx, sx);
+      dt.AddLine(rec);
+    }
+    cout << dt;
+    cout << " Copying dt to refdt (refdt = dt) " << endl;
+    refdt = dt;
+    cout << " Writing dt to fits file dtable.fits ... " << endl;
+    FitsInOutFile fios("!dtable.fits", FitsInOutFile::Fits_Create);
+    fios << dt;
+    cout << " Writing dt to fits as ASCII table with extname= ASC_DTable ... " << endl;
+    fios.SetDef_AscTable();
+    fios.SetNextExtensionName("ASC_DTable");
+    fios << dt;    
+    cout << "1.b/ Creating SwFitsDataTable (file swdtable.fits) " << endl;
+    FitsInOutFile swf("!swdtable.fits", FitsInOutFile::Fits_Create);
+    SwFitsDataTable swdt(swf, 64);
+    cout << " Copying from DataTable dt ..." << endl;
+    swdt = dt;
+    cout << swdt;
+  }
+  {
+    cout << "2/ Reading DataTable from FITS " << endl;
+    FitsInOutFile fios("dtable.fits", FitsInOutFile::Fits_RO);
+    cout << fios ;
+    fios.MoveToNextHDU();
+    DataTable dtr;
+    fios >> dtr;
+    cout << dtr;
+    cout << "2.b/  dtr.LineHeaderToString() dtr.LineToString(k)   : " << endl;
+    cout << dtr.LineHeaderToString() << endl;
+    for(int k = 0; k<NL; k+=NL/12) 
+      cout << "Line[" << k << "] " << dtr.LineToString(k) << endl ;  
+    cout << "2.b/  Reading from ASCII table   " << endl;
+    DataTable dtra;
+    fios >> dtra;
+    cout << dtra;
+    cout << dtra.LineHeaderToString() << endl;
+    for(int k = 0; k<NL; k+=NL/12) 
+      cout << "Line[" << k << "] " << dtra.LineToString(k) << endl ;  
+
+    cout << "2.c/  Reading SwFitsDataTable from  swdtable.fits  " << endl;   
+    SwFitsDataTable swdtr;
+    FitsInOutFile swf("swdtable.fits", FitsInOutFile::Fits_RO);   
+    swf.MoveAbsToHDU(2);  
+    swf >> swdtr;
+    cout << swdtr;
+    cout << swdtr.LineHeaderToString() << endl;
+    for(int k = 0; k<NL; k+=NL/12) 
+      cout << "Line[" << k << "] " << swdtr.LineToString(k) << endl ;  
+  }
+  cout << "============ FIN  test_fdtable =============== " << endl;  
+}
+
+
+
+
Index: /tags/V_Nov2007/SophyaProg/Tests/thash.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/thash.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/thash.cc	(revision 3445)
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.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_Nov2007/SophyaProg/Tests/timg.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/timg.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/timg.cc	(revision 3445)
@@ -0,0 +1,141 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream>
+// Utilisation de la classe Image<T>
+#include "sopnamsp.h"
+#include "ntoolsinit.h"
+#include "array.h"
+#include "cimage.h"
+// Utilisation des generateurs aleatoires
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tmtdt.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tmtdt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tmtdt.cc	(revision 3445)
@@ -0,0 +1,387 @@
+//--------------------------------------------------------------------------------
+// Programme de test des classes NTuple/DataTable/ ... en multi-threads (SOPHYA)
+//   R. Ansari - C. Magneville  ,   Novembre 2007
+//   (C) UPS+LAL IN2P3/CNRS   (C) DAPNIA/SPP  CEA  - 2007
+//
+// Exemples de commandes pour test (renvoie Rc=0 si OK) 
+// csh> tmtdt 
+//    tmtdt SEL TotSize NThreads [NOTHS] 
+// csh> tmtdt NT 50000 2
+// csh> tmtdt DT 50000 2
+// csh> tmtdt SWPPF 50000 2
+//  Le fits ne semble pas etre thread-safe, uniquement avec NTH=1
+// csh> tmtdt SWFITS 50000 1
+//--------------------------------------------------------------------------------
+
+#include "sopnamsp.h"
+#include "sspvflags.h"
+#include "zthread.h"
+#include "resusage.h"
+#include "ctimer.h"
+#include "timing.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string>
+#include <iostream>
+
+#include "tvector.h"
+#include "fioarr.h"
+#include "matharr.h"
+#include "tarrinit.h"
+
+// Pour tester la gestion multi-thread de Fill NTuple/DataTable
+#include "ntuple.h"
+#include "datatable.h"
+#include "swppfdtable.h"
+#ifndef SOPHYA_NO_FitsIOServer
+#include "fitsinoutfile.h"
+#include "swfitsdtable.h"
+#include "fitshdtable.h"
+#endif
+#include "histinit.h"
+
+
+
+//---------------------------------------------------------------------------------
+// Definition d'une classe heritant de ZThread, pour remplir ou lire NTuple/DataTable
+// des aleatoires
+class MTntdt : public ZThread {
+public:
+  MTntdt(bool fgc, sa_size_t sz, sa_size_t start, sa_size_t end);
+  inline void SetNTDTable(NTuple* nt=NULL, BaseDataTable* dt=NULL) 
+  {  nt_ = nt;  dt_ = dt; }
+  inline uint_8 NErr() { return nerr_; }
+  virtual void run(); 
+protected:
+  bool fgc_; // true -> fill , false -> read
+  sa_size_t size_, start_, end_;
+  NTuple* nt_;   // A remplir  si != NULL
+  BaseDataTable* dt_;  // A remplir si != NULL
+  string nom_;
+  int tid_;
+  uint_8 nerr_;
+};
+
+static int mtrandId = 0;  // Pour donner un identificateur a chaque thread
+
+MTntdt::MTntdt(bool fgc, sa_size_t sz, sa_size_t start, sa_size_t end)
+  : fgc_(fgc) , size_(sz), start_(start) , end_(end) , nerr_(0)
+{
+  SetNTDTable();
+  char buff[32];
+  sprintf(buff, "MTntdt-Id=%d", mtrandId);
+  tid_ = mtrandId;  mtrandId++;
+  nom_ = buff;
+  cout << " Thread MTntdt(" << nom_ << " ) Created ... " << endl;
+}
+
+
+// Le travail fait dans chaque thread (appele par start())
+void MTntdt::run()
+{
+  Timer tm(nom_.c_str());
+  char buff[128];
+  cout << "MTntdt::run() - Nom= " << nom_ << " TotSize " << size_ 
+       << " Start=" << start_ << " End=" << end_ << endl;
+  double x,cx,sx;
+  double xnt[10];
+  uint_8 nok = 0;
+
+
+  if (fgc_) { // Creation  	
+    if (nt_) {
+      for(sa_size_t k=start_; k<=end_; k++) {
+	x = k*0.013;
+	cx = cos(x);
+	sx = sin(x);
+    
+	xnt[0] = tid_; 
+	xnt[1] = k;
+	xnt[2] = x; 
+	xnt[3] = cx; 
+	xnt[4] = sx; 
+	nt_->Fill(xnt);
+      }
+    }
+    if (dt_) { 
+      DataTableRow dtr = dt_->EmptyRow();
+      for(sa_size_t k=start_; k<=end_; k++) {
+	x = k*0.013;
+	cx = cos(x);
+	sx = sin(x);
+	
+	dtr[0] = tid_;
+	dtr[1] = k;
+	dtr[2] = x; 
+	dtr[3] = cx; 
+	dtr[4] = sx; 
+	dt_->AddRow(dtr);
+      }
+    }
+    sprintf(buff, "%s : EndOf NT/DT Creation", nom_.c_str());
+    tm.Split(buff);
+  }
+  else {  // lecture - verification 
+    if (nt_) {
+      for(sa_size_t k=start_; k<=end_; k++) {
+	nt_->GetVecD(k, xnt);
+	sa_size_t kk = (sa_size_t)(xnt[1]+0.01);
+	x = kk*0.013;
+	if (fabs(x-xnt[2])>1.e-9) { nerr_++; continue; }
+	cx = cos(x);
+	if (fabs(cx-xnt[3])>1.e-9) { nerr_++; continue; }
+	sx = sin(x);
+	if (fabs(sx-xnt[4])>1.e-9) { nerr_++; continue; }
+	nok++;
+      }
+    }
+    if (dt_) { 
+      DataTableRow dtr = dt_->EmptyRow();
+      for(sa_size_t k=start_; k<=end_; k++) {
+	dt_->GetRow(k, dtr);
+	sa_size_t kk = (int_8)(dtr[1]);
+	x = kk*0.013;
+	xnt[2] = (r_8)(dtr[2]);    
+	if (fabs(x-xnt[2])>1.e-9) { nerr_++; continue; }
+	xnt[3] = (r_8)(dtr[3]);   	
+	cx = cos(x);
+	if (fabs(cx-xnt[3])>1.e-9) { nerr_++; continue; }
+	xnt[4] = (r_8)(dtr[4]);
+	sx = sin(x);
+	if (fabs(sx-xnt[4])>1.e-9) { nerr_++; continue; }	
+	nok++;
+      }
+    }
+    sprintf(buff, "%s : EndOf NT/DT Check NOk= %ld NErr=%ld ", nom_.c_str(),
+	    (long)nok, (long)nerr_);
+    tm.Split(buff);
+  }
+}
+// ----- Fin de la definition de la classe MTntdt ----
+//---------------------------------------------------------------------------------
+
+
+//------- f3_tmtdt()
+int f3_tmtdt(sa_size_t SZ, int NTH, 
+	     bool fgnt=true, bool fgdt=false, bool fgswppf=false, bool fgswfits=false,
+	     bool fgthsafe=true) 
+{
+  cout << "[1] f3_tmtdt/starting, SZ= " << SZ << " NTH= " << NTH << endl;
+  if (fgthsafe) cout << " ... Running NTuple/DataTable Thread-safe " << endl;
+  else cout << " ... WARNING Running NTuple/DataTable NOT Thread-safe " << endl;
+
+  ResourceUsage res(ResourceUsage::RU_All);
+  vector<MTntdt *> vth;
+
+  sa_size_t csz = SZ / NTH;
+  sa_size_t first, last;
+
+  int rc = 0;
+  // Verification des flags
+  if (!fgnt && !fgdt && !fgswppf && !fgswfits)  fgnt = true;
+
+  if (fgnt) fgdt = fgswppf = fgswfits = false;
+  else if (fgdt)  fgswppf = fgswfits = false;
+  else if (fgswppf) fgswfits = false;
+
+#ifdef SOPHYA_NO_FitsIOServer
+  if (fgswfits) {
+    cout << " SOPHYA compiled without FitsIOServer --> SwPPFDataTable " << endl;
+    fgswppf = true; fgswfits = false;
+  }
+#endif
+  char* nomnt[5]={"tid","k","x","cx","sx"};
+  NTuple* nt = NULL;
+  BaseDataTable* dt = NULL;
+  DataTable* dtmem = NULL;
+  SwPPFDataTable* dtswppf = NULL;
+
+  POutPersist* pond = new POutPersist("mtdt.ppf");
+  
+  if (fgnt) { 
+    nt = new NTuple(5, nomnt);
+    if (fgthsafe) nt->SetThreadSafe(true);
+  }
+  else if (fgdt) {
+    dtmem = new DataTable;
+    dt = dtmem;
+  }
+  else if (fgswppf) {
+    dtswppf = new SwPPFDataTable(*pond);
+    dt = dtswppf;    
+  }
+
+#ifndef SOPHYA_NO_FitsIOServer
+  SwFitsDataTable* dtswfits = NULL;
+  FitsInOutFile* fio = NULL;
+  if (fgswfits) {
+    // SwFitsDataTable creation 
+    fio = new FitsInOutFile("!mtdt.fits",FitsInOutFile::Fits_Create);
+    dtswfits = new SwFitsDataTable(*fio, 512, true);
+    dt = dtswfits;    
+  }  
+#endif
+
+  if (dt) {
+    if (fgthsafe) dt->SetThreadSafe(true);
+
+    dt->AddIntegerColumn("tid");
+    dt->AddLongColumn("k");
+    dt->AddDoubleColumn("x");
+    dt->AddDoubleColumn("cx");
+    dt->AddDoubleColumn("sx");
+  }
+  Timer tm("f2_tmtdt-NTupleDTable/MultiThreads");
+  cout << "[2] f3_tmtdt/creating fill threads " << endl;
+
+  for(int kt=0; kt<NTH; kt++) {
+    first = kt*csz;
+    last = (kt == NTH-1) ? SZ-1 : first+csz-1;
+     MTntdt* throp = new MTntdt(true, SZ, first, last);
+    throp->SetNTDTable(nt, dt);
+    vth.push_back(throp);
+  }
+  cout << "[3] f3_tmtdt/starting fill threads " << endl;
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->start();
+  cout << "[4] f3_tmtdt/waiting for all  threads to finish " << endl;
+  sleep(2);
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->join();
+
+  tm.Split();  
+
+  cout << "[5] f3_tmtdt/deleting thread objects " << endl;
+  for(int kt=0; kt<NTH; kt++)  delete vth[kt];
+  vth.clear();
+
+  if (pond && (dtmem || dtswppf || nt)) {
+  cout << "[6.a] f3_tmtdt/saving ntuple / data table to PPF " << endl;
+    if (nt) { 
+      (*pond) << PPFNameTag("NT") << (*nt);
+      cout << "[6.a.1] f3_tmtdt/ Ntuple NT saved to mtdt.ppf " << endl;
+      cout << (*nt) ;
+    }
+    if (dtmem || dtswppf) { 
+      (*pond) << PPFNameTag("DT");
+      if (dtmem) (*pond) << (*dtmem);
+      else if (dtswppf) (*pond) << (*dtswppf);
+      cout << "[6.a.2] f3_tmtdt/ DataTable DT saved to mtdt.ppf " << endl;
+      cout << (*dt) ;
+    }
+  }
+  if (pond) { delete pond; pond = NULL; }  // Closing the OutPPF file
+
+  tm.Split();  
+  
+  // Si c'est un SwPPFDataTable, on le relit sur le fichier PPF 
+  PInPersist* pind = NULL;
+  if (dtswppf) {
+    delete dtswppf;
+    SwPPFDataTable* dtswppf = new SwPPFDataTable();
+    pind = new PInPersist("mtdt.ppf");
+    (*pind) >> PPFNameTag("DT") >> (*dtswppf);
+    dt = dtswppf;
+    if (fgthsafe) dt->SetThreadSafe(true);
+  }
+
+// Si c'est un SwFITSDataTable, on le relit sur le fichier FITS 
+#ifndef SOPHYA_NO_FitsIOServer
+  if (dtswfits) {
+    delete dtswfits;
+    delete fio; fio = NULL;
+    //    fio = new FitsInOutFile("mtdt.fits",FitsInOutFile::Fits_RO);
+    //    fio->MoveAbsToHDU(2);
+    // SwFitsDataTable creation/readin in from fits file
+    string finame = "mtdt.fits";
+    dtswfits = new SwFitsDataTable(finame);
+    dt = dtswfits;    
+  }  
+#endif
+
+  tm.Split();
+  cout << "[7] f3_tmtdt/creating read/check threads " << endl;
+
+  for(int kt=0; kt<NTH; kt++) {
+    first = kt*csz;
+    last = (kt == NTH-1) ? SZ-1 : first+csz-1;
+     MTntdt* throp = new MTntdt(false, SZ, first, last);
+    throp->SetNTDTable(nt, dt);
+    vth.push_back(throp);
+  }
+  cout << "[8] f3_tmtdt/starting read/check threads " << endl;
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->start();
+  cout << "[8] f3_tmtdt/waiting for all  threads to finish " << endl;
+  sleep(2);
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->join();
+
+  tm.Split();  
+  
+  cout << "[9] f3_tmtdt/deleting thread objects " << endl;
+  for(int kt=0; kt<NTH; kt++)  {
+    cout << " Thread[" << kt << "] NErr= " << vth[kt]->NErr() << endl;
+    if (vth[kt]->NErr() != 0)  rc++;
+    delete vth[kt];
+  }
+
+  if (pind) { delete pind; pind = NULL; }  // Closing the InPPF file (for SwPPfDataTable)
+  if (nt) delete nt;
+  if (dt) delete dt;
+
+#ifndef SOPHYA_NO_FitsIOServer
+  if (fio) delete fio;
+#endif
+  
+  cout << res;
+  return rc;
+}
+//----------------- FIN des fonctions de test -----------------
+
+//-------------------------------------------------------------
+//---------------------- MAIN MAIN MAIN -----------------------
+//-------------------------------------------------------------
+
+int main(int narg, char *arg[])
+
+{
+  InitTim();
+  SophyaInit();
+
+  int rc = 0;
+  if (narg < 4) {
+    cout << "tmtdt/Error args - Usage: tmtdt SEL TotSize NThreads [NOTHS] " << endl;
+    cout << "  SEL: =NT->NTuple , =DT->DataTable, =SWPPF , =SWFITS SwPPF.SwFits DataTable" << endl;
+    cout << "  TotSize: Totale NTuple/DataTable NRows, NThreads= Number of Threads" << endl;
+    cout << "  if arg[4]==NOTHS -> NO call tp SetThreadSafe(true)" << endl;
+    return 1;
+  }
+  string sel = arg[1];
+  bool fgnt,fgdt,fgswppf,fgswfits;
+  fgnt = fgdt = fgswppf = fgswfits= false;
+  if (sel == "NT") fgnt = true;
+  else if (sel == "DT")  fgdt = true;
+  else if (sel == "SWPPF")  fgswppf = true;
+  else if (sel == "SWFITS")  fgswfits = true;
+
+  bool fgths = true;
+  if ((narg > 4) && (strcmp(arg[4],"NOTHS")==0))  fgths = false;
+
+  sa_size_t SZ = atoi(arg[2]);
+  int NTH = atoi(arg[3]);
+ 
+  try {
+    rc = f3_tmtdt(SZ, NTH, fgnt, fgdt, fgswppf, fgswfits, fgths);
+  }
+  catch (PThrowable exc) {
+    cerr << "zthr: catched Exception " << exc.Msg() << endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception (tmtdt.cc) " << endl; 
+    rc = 78; 
+  } 
+  cout << "----------- tmtdt/END    (Rc= " << rc << " ) ------------ " << endl;
+  PrtTim("---END tmtdt---");
+  return(rc);
+  
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tmtrnd.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tmtrnd.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tmtrnd.cc	(revision 3445)
@@ -0,0 +1,240 @@
+//--------------------------------------------------------------------------------
+// Programme d'exemple multi-threads et test de la classe RandomGenerator de SOPHYA
+//   R. Ansari - C. Magneville  ,   Novembre 2007
+//   SOPHYA (C) UPS+LAL IN2P3/CNRS   (C) DAPNIA/SPP  CEA  - 2007   
+// Exemples de commandes pour test (dans l'ordre ci-dessous :
+// csh> tmtrnd OCG 1000000 XXX
+// csh> tmtrnd STG 1000000 1024
+// csh> tmtrnd RDG 1000000 rg1.ppf
+// csh> tmtrnd MTG 3000000 4 
+//--------------------------------------------------------------------------------
+
+#include "sopnamsp.h"
+#include "zthread.h"
+#include "resusage.h"
+#include "ctimer.h"
+#include "timing.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string>
+#include <iostream>
+
+#include "tvector.h"
+#include "fioarr.h"
+#include "matharr.h"
+#include "tarrinit.h"
+
+#include "srandgen.h"
+#include "stsrand.h"
+
+
+//---------------------------------------------------------------------------------
+// Definition d'une classe heritant de ZThread, pour remplir un vecteur avec 
+// des aleatoires
+class MTRnd : public ZThread {
+public:
+  MTRnd(TVector<r_8>& v, bool fgg=true);
+  virtual void run(); 
+protected:
+  string nom_;
+  TVector<r_8> vv_;
+  bool fgg_; // true -> gaussien, false rand01() 
+};
+
+static int mtrandId = 0;  // Pour donner un identificateur a chaque thread
+
+MTRnd::MTRnd(Vector& v, bool fgg)
+  : vv_(v,true), fgg_(fgg)  // Partage de reference du vecteur 
+{
+  char buff[32];
+  sprintf(buff, "MTRnd-Id=%d", mtrandId);
+  mtrandId++;
+  nom_ = buff;
+  cout << " Thread MTRnd(" << nom_ << " ) Created ... " << endl;
+}
+
+
+// Le travail fait dans chaque thread (appele par start())
+void MTRnd::run()
+{
+  Timer tm(nom_.c_str());
+  cout << "MTRnd::run() - Nom= " << nom_ << " vv.Size()= " << vv_.Size() << endl;
+  RandomGenerator rgen;
+  if (fgg_) 
+    for(sa_size_t k=0; k<vv_.Size(); k++) vv_(k) = rgen.Gaussian();
+  else
+    for(sa_size_t k=0; k<vv_.Size(); k++) vv_(k) = rgen.Flat01();
+}
+// ----- Fin de la definition de la classe MTRnd ----
+//---------------------------------------------------------------------------------
+
+//----------------- Les fonction de test -----------------
+//------- f0_tmtrnd()
+int f0_tmtrnd(sa_size_t VSZ, bool fgg=true)
+{
+  cout << "[1] f0_tmtrnd/starting, VSZ= " << VSZ << endl;
+  TVector<r_8> DATA(VSZ);
+  {
+    Timer tm("f0_tmtrnd-GauRnd/drand01");
+    if (fgg) 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = GauRnd(0., 1.);
+    else 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = drand01();
+    cout << "[2] f0_tmtrnd/ End of random generation using GauRnd()/drand01() " << endl;
+  }
+  POutPersist po("data0.ppf");
+  po << DATA;
+  cout << "[3] f0_tmtrnd/  DATA saved to file data0.ppf " << endl;
+  return 0; 
+}
+//------- f1_tmtrnd()
+int f1_tmtrnd(sa_size_t VSZ, size_t seqsz, bool fgg=true)
+{
+  cout << "[1] f1_tmtrnd/starting, VSZ= " << VSZ << " SeqSz=" << seqsz << endl;
+  TVector<r_8> DATA(VSZ);
+  RandomGenerator rg(seqsz, (seqsz==0)?false:true);  
+  unsigned short seed[3];
+  rg.GetSeed(seed, 2);  // pour imprimer l'etat du generateur
+  {
+    Timer tm("f0_tmtrnd-GauRnd/drand01");
+    if (fgg) 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = rg.Gaussian();
+    else 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = rg.Flat01();
+    cout << "[2] f1_tmtrnd/ End of random generation using RandomGen class " << endl;
+  }
+  POutPersist po("data1.ppf");
+  po << DATA;
+  cout << "[3] f1_tmtrnd/  DATA saved to file data1.ppf " << endl;
+  POutPersist porg("rg1.ppf");
+  porg << rg;
+  rg.GetSeed(seed, 2);  // pour imprimer l'etat du generateur
+  cout << "[4] f1_tmtrnd/  RandGen saved to file rg1.ppf " << endl;
+  return 0; 
+}
+//------- f2_tmtrnd()
+int f2_tmtrnd(sa_size_t VSZ, string & inppf, bool fgg=true)
+{
+  cout << "[1] f2_tmtrnd/starting, VSZ= " << VSZ << " InPPFName=" << inppf << endl;
+  TVector<r_8> DATA(VSZ);
+  RandomGenerator rg;
+  PInPersist pirg(inppf);
+  pirg >> rg;
+  cout << "[1.b] f2_tmtrnd/ RandGen read from InPPF OK " << endl;
+  unsigned short seed[3];
+  rg.GetSeed(seed, 2);  // pour imprimer l'etat du generateur
+  {
+    Timer tm("f0_tmtrnd-GauRnd/drand01");
+    if (fgg) 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = rg.Gaussian();
+    else 
+      for(sa_size_t k=0; k<VSZ; k++)  DATA(k) = rg.Flat01();
+    cout << "[2] f1_tmtrnd/ End of random generation using RandomGen class " << endl;
+  }
+  POutPersist po("data2.ppf");
+  po << DATA;
+  cout << "[3] f1_tmtrnd/  DATA saved to file data2.ppf " << endl;
+  POutPersist porg("rg2.ppf");
+  porg << rg;
+  rg.GetSeed(seed, 2);  // pour imprimer l'etat du generateur
+  cout << "[4] f1_tmtrnd/  RandGen saved to file rg2.ppf " << endl;
+  return 0; 
+}
+
+//------- f3_tmtrnd()
+int f3_tmtrnd(sa_size_t VSZ, int NTH, bool fgg=true) 
+{
+  cout << "[1] f3_tmtrnd/starting, VSZ= " << VSZ << " NTH= " << NTH << endl;
+  ResourceUsage res(ResourceUsage::RU_All);
+  vector<MTRnd *> vth;
+  TVector<r_8> DATA(VSZ);
+  sa_size_t csz = VSZ / NTH;
+  sa_size_t first, last;
+  cout << "[2] f3_tmtrnd/creating threads " << endl;
+  for(int kt=0; kt<NTH; kt++) {
+    first = kt*csz;
+    last = (kt == NTH-1) ? VSZ-1 : first+csz-1;
+    TVector<r_8> sv = DATA(Range(first, last));
+    vth.push_back(new MTRnd(sv, fgg) );
+  }
+  cout << "[3] f3_tmtrnd/starting threads " << endl;
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->start();
+  
+  cout << "[4] f3_tmtrnd/waiting for all  threads to finish " << endl;
+  sleep(2);
+  for(int kt=0; kt<NTH; kt++)  vth[kt]->join();
+  
+  cout << "[5] f3_tmtrnd/deleting thread objects " << endl;
+  for(int kt=0; kt<NTH; kt++)  delete vth[kt];
+  
+  cout << "[6] f3_tmtrnd/saving DATA to file data3.ppf " << endl;
+  POutPersist po("data3.ppf");
+  po << DATA;
+  cout << res;
+  return 0;
+}
+//----------------- FIN des fonctions de test -----------------
+
+//-------------------------------------------------------------
+//---------------------- MAIN MAIN MAIN -----------------------
+//-------------------------------------------------------------
+
+int main(int narg, char *arg[])
+
+{
+  InitTim();
+  SophyaInit();
+
+  int rc = 0;
+  if (narg < 4) {
+    cout << " tmtrnd/Error args - Usage: tmtrnd SEL arg1 arg2 ... " << endl;
+    cout << "    ==> SEL=OCG/OCF : tmtrnd OCG/OCF VecSize XXX  (-> f0_tmtrnd())" << endl;
+    cout << "        OCG/OCF Random gen. with (old) c-functions G/F-> Gaussian/Flat " << endl;
+    cout << "    ==> SEL=STG/STF : tmtrnd STG/STF VecSize SeqSize  (-> f2_tmtrnd())" << endl;
+    cout << "        STG/STF RandGen(SeqSize) SeqSz=0 -> NO-ThSafe G/F-> Gaussian/Flat " << endl;
+    cout << "    ==> SEL=RDG/RDF : tmtrnd RDG/RDF VecSize InPPFName  (-> f2_tmtrnd())" << endl;
+    cout << "        RDG/RDF Read RandGen object from file InPPFName G/F-> Gaussian/Flat " << endl;
+    cout << "    ==> SEL=MTG/MTF : tmtrnd MTG/MTF VecSize NThread (-> f3_tmtrnd()) " << endl;
+    cout << "        MTG/MTF Multithread generation, MTG-> Gaussian, MTF-> Flat " << endl;
+    return 1;
+  }
+  string sel = arg[1];
+
+  try {
+    bool fgg = (sel[2]=='G')?true:false;
+    if ((sel == "OCG")||(sel == "OCF")) {
+      sa_size_t VSZ = atoi(arg[2]);
+      rc = f0_tmtrnd(VSZ, fgg);
+    }
+    if ((sel == "STG")||(sel == "STF")) {
+      sa_size_t VSZ = atoi(arg[2]);
+      size_t seqsz = atoi(arg[3]);
+      rc = f1_tmtrnd(VSZ, seqsz, fgg);
+    }
+    if ((sel == "RDG")||(sel == "RDF")) {
+      sa_size_t VSZ = atoi(arg[2]);
+      string inppf = arg[3];
+      rc = f2_tmtrnd(VSZ, inppf, fgg);
+    }
+    if ((sel == "MTG")||(sel == "MTF")) {
+      sa_size_t VSZ = atoi(arg[2]);
+      int NTH = atoi(arg[3]);
+      rc = f3_tmtrnd(VSZ, NTH, fgg);
+    }
+
+  }
+  catch (PThrowable exc) {
+    cerr << "zthr: catched Exception " << exc.Msg() << endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception (tmtrnd.cc) " << endl; 
+    rc = 78; 
+  } 
+  cout << "----------- tmtrnd/END ------- " << endl;
+  PrtTim("---END tmtrnd---");
+  return(rc);
+  
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tmtrnd3.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tmtrnd3.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tmtrnd3.cc	(revision 3445)
@@ -0,0 +1,330 @@
+// Test des operations de tirages aleatoires thread safe/nosafe
+#include "sopnamsp.h"
+#include "zthread.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string>
+#include <iostream>
+
+#include "tvector.h"
+#include "matharr.h"
+#include "fioarr.h"
+#include "tarrinit.h"
+#include "srandgen.h"
+#include "nbtri.h"
+#include "timing.h"
+
+#include "stsrand.h"
+
+long Check_Redondances(TVector<r_8>& v);
+
+//---------------------------------------------------------------------
+// Classe heritant de ZThread, pour remplir un vecteur avec des aleatoires
+class MTRndTest : public ZThread {
+public:
+  MTRndTest(TVector<r_8>& v,bool thsafe=true,int nbuff=1024);
+  virtual void run(); 
+protected:
+  string nom_; int inum_;
+  TVector<r_8> vv_;
+  bool thsafe_;
+  int nbuff_;
+};
+
+static int mtrandId = 0;  // Pour donner un identificateur a chaque thread
+
+MTRndTest::MTRndTest(Vector& v,bool thsafe,int nbuff)
+  : vv_(v,true) , thsafe_(thsafe), nbuff_(nbuff)
+{
+  if(nbuff_<=0) nbuff_ = 1024;
+  char buff[32];
+  inum_ = mtrandId;
+  sprintf(buff,"MTRndTest-Id=%d",mtrandId);
+  mtrandId++;
+  nom_ = buff;
+  cout<<"Thread MTRndTest("<<nom_<<" ) Created ... with threadsafe="<<thsafe_
+      <<", nbuff="<<nbuff_<<endl;
+}
+
+
+// Le travail fait dans chaque thread (appelle par start())
+void MTRndTest::run()
+{
+  cout<<"MTRndTest::run() - Nom= "<<nom_<<" vv.Size()= "<<vv_.Size()
+      <<" with threadsafe="<<thsafe_<<endl;
+  if(thsafe_) {  // On appele RandomGenerator Thread-Safe
+    RandomGenerator rgen(nbuff_,true);
+    for(sa_size_t k=0; k<vv_.Size(); k++) vv_(k) = rgen.Flat01();
+  } else {  // On appele RandomGenerator NO Thread-Safe
+    // ATTENTION: le comportement est different selon qu'un thread
+    // se termine avant ou apres que le suivant commence:
+    // Pour de petits VSZ le run() du thread "n" se termine
+    // avant que le run() du thread "n+1" ne commence:
+    // cela donne un comportement "tread_safe" APPARENT mais
+    // dans la realite drand48() N'EST PAS thread_safe !!!!
+    RandomGenerator rgen(0,false);
+    for(sa_size_t k=0; k<vv_.Size(); k++) vv_(k) = rgen.Flat01();
+  }
+  cout<<"....MTRndTest::run() - "<<nom_<<" ENDED !!!!!!!!!"<<endl;
+}
+
+//---------------------------------------------------------------------
+int main(int narg, char *arg[])
+
+{
+  SophyaInit();
+
+  if(narg<3) {cout<<"usage: tmtrnd3 ntir nthreads [nbuff]"<<endl; return -1;}
+  sa_size_t VSZ = atoi(arg[1]);
+  int NTH = atoi(arg[2]);
+  int NBUFF = (narg>3) ? atoi(arg[3]): 64;
+  if(NTH<=0) NTH = 1;
+  cout<<"tmtrnd/arguments, VSZ= "<<VSZ<<" NTH= "<<NTH<<" NBUFF="<<NBUFF<<endl;
+  // Il ne faut pas que les buffers de RandomGenerator soient remplis
+  // au dela de ce qui est necessaire si on veut faire
+  // la comparaison avec le mono thread
+  int lmod = NTH*NBUFF;
+  if(VSZ<lmod) VSZ = lmod;
+  if(VSZ%lmod!=0) VSZ = int(VSZ/(double)lmod+0.5)*lmod;
+  cout<<"tmtrnd/starting, lmod="<<lmod<<" NTH= "<<NTH<<" -> changed VSZ= "<<VSZ<<endl;
+
+  int rc = 0;
+  sa_size_t csz = VSZ / NTH;
+  sa_size_t first, last;
+
+  try {
+
+    //---
+    //--- Init et set de l'aleatoire
+    //---
+    RandomGenerator rgen_nothsf(0,false);
+    unsigned short seed_16v[3];
+    {
+    cout<<"\n>>>>>>> Init de l'aleatoire"<<endl;
+    rgen_nothsf.AutoInit(5);
+    rgen_nothsf.GetSeed(seed_16v,5);
+    }
+
+    InitTim();
+
+    //---
+    //--- remplissage en mono-thread directement avec drand48
+    //---
+    TVector<r_8> DATA0(VSZ);
+    {
+    cout<<"\n>>>>>>> Remplissage en mono-thread avec drand48()"<<endl;
+    rgen_nothsf.Init(seed_16v,5);
+    for(int i=0;i<VSZ;i++) DATA0(i) = drand48();
+    PrtTim(" ");
+    }
+
+    //---
+    //--- Remplissage par threads avec RandomGenerator thread safe
+    //---
+    TVector<r_8> DATA1(VSZ);
+    {
+    cout<<"\n>>>>>>> Remplissage par threads avec RandomGenerator thread safe"<<endl;
+    rgen_nothsf.Init(seed_16v,5);
+    vector<MTRndTest *> vth1;
+    cout<<"...tmtrnd/creating threads "<<endl;
+    for(int kt=0; kt<NTH; kt++) {
+      first = kt*csz;
+      last = (kt == NTH-1) ? VSZ-1 : first+csz-1;
+      TVector<r_8> sv = DATA1(Range(first, last));
+      vth1.push_back(new MTRndTest(sv,true,NBUFF) );
+    }
+    cout<<"...tmtrnd/starting threads"<<endl;
+    for(int kt=0; kt<NTH; kt++)  vth1[kt]->start();
+    cout<<"...tmtrnd/waiting for all  threads to finish"<<endl;
+    sleep(2);
+    for(int kt=0; kt<NTH; kt++)  vth1[kt]->join();
+    cout<<"...tmtrnd/deleting thread objects"<<endl;
+    for(int kt=0; kt<NTH; kt++)  delete vth1[kt];
+    PrtTim(" ");
+    }
+
+    //---
+    //--- Remplissage par threads avec RandomGenerator SANS thread safe
+    //---
+    TVector<r_8> DATA2(VSZ);
+    {
+    cout<<"\n>>>>>>> Remplissage par threads avec RandomGenerator SANS thread safe"<<endl;
+    rgen_nothsf.Init(seed_16v,5);
+    vector<MTRndTest *> vth2;
+    cout << "......tmtrnd/creating threads " << endl;
+    for(int kt=0; kt<NTH; kt++) {
+      first = kt*csz;
+      last = (kt == NTH-1) ? VSZ-1 : first+csz-1;
+      TVector<r_8> sv = DATA2(Range(first, last));
+      vth2.push_back(new MTRndTest(sv,false) );
+    }
+    cout<<"......tmtrnd/starting threads"<<endl;
+    for(int kt=0; kt<NTH; kt++)  vth2[kt]->start();
+    cout<<"......tmtrnd/waiting for all  threads to finish"<<endl;
+    sleep(2);
+    for(int kt=0; kt<NTH; kt++)  vth2[kt]->join();
+    cout<<"......tmtrnd/deleting thread objects "<<endl;
+    for(int kt=0; kt<NTH; kt++)  delete vth2[kt];
+    PrtTim(" ");
+    }
+
+    //---
+    //--- remplissage en mono-thread avec RandomGenerator
+    //---
+    TVector<r_8> DATA0R(VSZ);
+    {
+    cout<<"\n>>>>>>> Remplissage en mono-thread avec RandomGenerator"<<endl;
+    rgen_nothsf.Init(seed_16v,5);
+    for(int i=0;i<VSZ;i++) DATA0R(i) = rgen_nothsf.Flat01();
+    PrtTim(" ");
+    }
+
+    //---
+    //--- checking
+    //---
+    cout<<"\n>>>>>>> Sorting"<<endl;
+    qsort(DATA0.Data(),(size_t)VSZ,sizeof(double),qSort_Dble);
+    qsort(DATA1.Data(),(size_t)VSZ,sizeof(double),qSort_Dble);
+    qsort(DATA2.Data(),(size_t)VSZ,sizeof(double),qSort_Dble);
+    qsort(DATA0R.Data(),(size_t)VSZ,sizeof(double),qSort_Dble);
+    PrtTim(" ");
+
+    cout<<"\n>>>>>>> Checking differences"<<endl;
+    double vmax00=0., vmax01=0., vmax02=0., vmax12=0.;
+    for(int i=0;i<VSZ;i++) {
+      double v;
+      v = fabs(DATA0R(i)-DATA0(i));
+      if(v>vmax00) vmax00 = v;
+      v = fabs(DATA1(i)-DATA0(i));
+      if(v>vmax01) vmax01 = v;
+      v = fabs(DATA2(i)-DATA0(i));
+      if(v>vmax02) vmax02 = v;
+      v = fabs(DATA2(i)-DATA1(i));
+      if(v>vmax12) vmax12 = v;
+    }
+    cout<<"vmax00 = "<<vmax00<<endl
+        <<"vmax01 = "<<vmax01<<endl
+        <<"vmax02 = "<<vmax02<<endl
+        <<"vmax12 = "<<vmax12<<endl;
+
+    
+    cout<<"\n>>>>>>> Checking redondances"<<endl;
+    cout<<"DATA0:"<<endl; Check_Redondances(DATA0);
+    cout<<"DATA1:"<<endl; Check_Redondances(DATA1);
+    cout<<"DATA2:"<<endl; Check_Redondances(DATA2);
+    cout<<"DATA0R:"<<endl; Check_Redondances(DATA0R);
+
+    //--- persisting
+    cout<<"\n>>>>>>> Writing to ppf"<<endl;
+    string tag;
+    POutPersist pos("tmtrnd3.ppf");
+    tag = "d0r"; pos.PutObject(DATA0R,tag);
+    tag = "d0"; pos.PutObject(DATA0,tag);
+    tag = "d1"; pos.PutObject(DATA1,tag);
+    tag = "d2"; pos.PutObject(DATA2,tag);
+
+    double eps = 1.e-25;
+    if(vmax00>eps || vmax01>eps) rc = 1;
+
+  }
+  catch (PThrowable exc) {
+    cerr<<"zthr: catched Exception "<<exc.Msg()<<endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr<<"catched unknown (...) exception (lpk.cc)"<<endl; 
+    rc = 78; 
+  } 
+
+  cout<<"\n>>>>>>>  tmtrnd3/END"<<endl;
+
+  return(rc);
+}
+
+//---------------------------------------------------------------------
+long Check_Redondances(TVector<r_8>& v)
+// Recherche des aleatoire tires 2 fois
+// Le vecteur "v" doit deja etre trie par valeurs CROISSANTES
+{
+ int k=0;
+ double eps=1.e-25;
+ TVector<r_8> dd(v,false);
+ for(int i=dd.Size()-1;i>=1;i--) dd(i) -= dd(i-1);
+ dd(0) = 0.;
+ qsort(dd.Data(),(size_t)dd.Size(),sizeof(double),qSort_Dble);
+ for(int i=1;i<dd.Size();i++) if(fabs(dd(i))<eps) k++;
+ cout<<"Number of redondances pour v<"<<eps<<" : k="<<k<<endl;
+ return k;
+}
+
+/*
+delobjs *
+openppf tmtrnd3.ppf
+
+#------ les tableaux sont ranges par valeurs croissantes
+disp d0
+disp d0r "same"
+disp d1 "same red"
+disp d2 "same blue"
+
+
+#------
+newh1d hd0 0. 1. 1000
+n/proj hd0 d0.val
+newh1d hd1 0. 1. 1000
+n/proj hd1 d1.val
+newh1d hd2 0. 1. 1000
+n/proj hd2 d2.val
+
+disp hd0
+disp hd1 "same red"
+disp hd2 "same blue"
+
+#------ tableaux des differences / a la reference
+del d00 d10 d20 d21
+c++exec \
+TVector<r_8> d00(d0r,false); d00 -= d0; \
+TVector<r_8> d10(d1,false); d10 -= d0; \
+TVector<r_8> d20(d2,false); d20 -= d0; \
+TVector<r_8> d21(d2,false); d21 -= d1; \
+KeepObj(d00); KeepObj(d10); KeepObj(d20); KeepObj(d21); \
+cout<<"-- Fin"<<endl;
+
+# Doivent avoir min=max=0
+echo d00 min =  ${d00.min} , max =  ${d00.max}
+echo d10 min =  ${d10.min} , max =  ${d10.max}
+# Doivent avoir min!=0 et max!=0
+echo d20 min =  ${d20.min} , max =  ${d20.max}
+echo d21 min =  ${d21.min} , max =  ${d21.max}
+
+disp d00
+disp d10
+
+disp d20
+disp d21 "same red"
+
+#------ tableaux des redondances
+del dd1 dd2
+c++exec \
+TVector<r_8> dd1(d1,false); \
+for(int i=dd1.Size()-1;i>=1;i--) dd1(i) -= dd1(i-1); dd1(0) = 0.; \
+TVector<r_8> dd2(d2,false); \
+for(int i=dd2.Size()-1;i>=1;i--) dd2(i) -= dd2(i-1); dd2(0) = 0.; \
+qsort(dd1.Data(),(size_t)dd1.Size(),sizeof(double),qSort_Dble); \
+qsort(dd2.Data(),(size_t)dd2.Size(),sizeof(double),qSort_Dble); \
+double eps=1.e-25; \
+int k1=0; for(int i=1;i<dd1.Size();i++) if(fabs(dd1(i))<eps) k1++; \
+int k2=0; for(int i=1;i<dd2.Size();i++) if(fabs(dd2(i))<eps) k2++; \
+cout<<"Number of v<"<<eps<<" : k1="<<k1<<" , k2="<<k2<<endl; \
+KeepObj(dd1); KeepObj(dd2); \
+cout<<"-- Fin"<<endl;
+
+# Regarder pour les petites separations
+# dd1 ne doit pas avoir de redondance
+disp dd1
+# dd2 doit avoir des redondances
+disp dd2
+
+ */
Index: /tags/V_Nov2007/SophyaProg/Tests/tmxv.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tmxv.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tmxv.cc	(revision 3445)
@@ -0,0 +1,110 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream>
+
+#include "srandgen.h"
+#include "tarrinit.h"
+#include "tvector.h"
+#include "sopemtx.h"
+#include "timing.h"
+
+/********************************************************
+  Programme test pour les fonctionalites de calcul
+  sur matrices et vecteurs dans SOPHYA/TArray
+              Reza - fev 2005 
+*********************************************************/ 
+
+int mxv_inverse(int l);                    // ErrorCode = 64
+
+static double TOLERANCE = 1.e-6;
+static int nprt = 100;
+static int prtlev = 1;
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+
+
+  if (narg < 2) {
+    cout << " tmxv : Test SOPHYA Matrix/Vector operations\n" 
+	 << " Usage: tmxv select [sizeL,C=5,5] [prtlev=1] [nprtmax=100]\n" 
+	 << "   select= inverse / all= \n"
+	 << "   inverse:  ComputeInverse() r_8 \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); 
+  if (narg > 3) prtlev = atoi(arg[3]);
+  if (narg > 4) nprt = atoi(arg[4]);
+
+  cout << " tmxv - TMatrix/TVector operations tests sizeL,C=" << l << "," << c 
+       << " opt= " << opt << endl;
+  int rc = 0;
+  BaseArray::SetMaxPrint(nprt, prtlev);
+  try {
+    if (opt == "inverse") rc = mxv_inverse(l);
+    else { cout << "tmxv/ Unknown option " << opt << " ! " << endl; rc = 66; }
+  }
+  catch (PThrowable exc) {
+    cerr << " tmxv catched Exception (tmxv.cc) " << exc.Msg() << endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr << " tmxv catched unknown (...) exception (tmxv.cc) " << endl; 
+    rc = 78; 
+  } 
+  
+  PrtTim(" End of tmxv matrix inversion test ");
+  cout << " ---------------  END of Programme -------- (Rc= " 
+       << rc << ") --- " << endl;
+  return(rc);
+}
+
+// -----------------------------------------------------------------------
+/* Nouvelle-Fonction */
+int mxv_inverse(int m)
+{
+  cout << " mxv_inverse() - Test SimpleMatrixOperation<r_8> " << endl;
+  
+  Matrix a(m , m), ainv, idmx(m,m), mxprod, diff;
+  a = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+  PrtTim(" End of a_inint");
+
+  cout << "\n   Calling  SimpleMatrixOperation::Inverse .... " << endl;
+  SimpleMatrixOperation<r_8> smo;
+  ainv = smo.Inverse(a);
+  PrtTim(" End of smo.Inverse()");
+  mxprod = a*ainv;
+  PrtTim(" End of mxprod = a*ainv");
+  idmx = IdentityMatrix();
+  PrtTim(" End of idmx = IdentityMatrix()");
+  diff = mxprod-idmx;
+  PrtTim(" End of Compute(diff)");
+
+  if (prtlev > 0) {
+    cout << " ------------ Matrix A = \n " << a << "\n" << endl; 
+    cout << " ------------ Matrix Inverse(A) = \n " << ainv << "\n" << endl; 
+    cout << " ------------ Matrix mxprod = A*Inverse(A) = \n " << mxprod << "\n" << endl; 
+  }
+  double min,max;
+  diff.MinMax(min, max);
+  PrtTim(" End of diffCheck");
+  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 64;
+  }
+  return 0;
+
+}
+
Index: /tags/V_Nov2007/SophyaProg/Tests/tnfits.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tnfits.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tnfits.cc	(revision 3445)
@@ -0,0 +1,188 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream>
+#include <string>
+
+#include <typeinfo>
+#include "timing.h"
+#include "histinit.h"
+#include "array.h"
+#include "fitsinoutfile.h"
+#include "fitsblkrw.h"
+#include "fitsarrhand.h"
+#include "fiosinit.h"
+
+/*  Programme test des classes NFits                  */
+/*  SOPHYA - R. Ansari (LAL)  -   Sep 2005           */
+
+int tsfitsReadFile(string& flnm);
+
+int main(int narg, char* arg[])
+{
+  cout << " ---- Programme tnfits - Test classes NFits --- " << endl;
+  if ( (narg > 1) && (strcmp(arg[1],"-h")==0) ) {
+    cout << " Usage : tnfits [InputFitsFileName] " << endl;
+    return 1;
+  }
+  int rc = 0;
+  try {
+    SophyaInit();  
+    FitsIOServerInit();
+    InitTim(); 
+    if (narg > 1) {   // Lecture fichier entree 
+      string flnm = arg[1];
+      cout << "1/=== Lecture fichier FITS : " << flnm << endl;
+      FitsInOutFile fios(flnm, FitsInOutFile::Fits_RO);
+      fios.Print();
+      bool encore = true;
+      while (encore) {
+	cout << " HDU No" << fios.CurrentHDU() << " Type= " 
+	     << fios.CurrentHDUTypeStr() << endl;
+	DVList dvl;
+	fios.GetHeaderRecords(dvl);
+	cout << dvl;
+	if (fios.CurrentHDUType() == IMAGE_HDU) {
+	  LONGLONG naxes[5] = {0,0,0,0,0};
+	  int naxis=5;
+	  fios.GetImageHDUInfo(naxis, naxes);
+	  cout << "--GetImageHDUInfo() naxis= " << naxis << " : "
+	       << naxes[0] << 'x' << naxes[1] << 'x' << naxes[2] << endl;
+	  if (naxis == 2) {
+	    cout << "---Reading Matrix ... mx= " << endl;
+	    Matrix mx(naxes[1], naxes[0]);
+	    FitsBlockRW<double>::ReadImageData(fios, mx.Data(), mx.Size());
+	    cout << mx;
+	  }
+	}
+	else {
+	  vector<string> colnames;
+	  vector<int> coltypes;
+	  vector<LONGLONG> repcnt, width;
+	  int ncols = fios.GetColInfo(colnames, coltypes, repcnt, width);
+	  cout << " NCols from GetColInfo = " << ncols << endl;
+	  for(int kk=0; kk<colnames.size(); kk++) {
+	    cout << " kk=" << kk << " ColName= " << colnames[kk] 
+		 << " Type= " << coltypes[kk] 
+		 << " Repeat= " << repcnt[kk]
+		 << " W= " << width[kk] << endl;
+	  }
+	}
+	if (fios.CurrentHDU() < fios.NbHDUs()) 
+	  fios.MoveRelToHDU(1);
+	else encore = false;
+      }
+    }  // ---- Fin lecture fichier entree 
+    {
+      cout << "2/=== Ecriture BinTable dans toto.fits  " << endl;
+      FitsInOutFile fiosc("!toto.fits", FitsInOutFile::Fits_Create);
+      //     cout << " CurrHDU-1 : " << fiosc.CurrentHDU() 
+      // 	   << " Type=" << fiosc.CurrentHDUType() <<endl;
+      LONGLONG naxes[5] = {5,5,0,0,0};
+      fiosc.CreateImageHDU(FLOAT_IMG, 2, naxes);
+      float data[100];
+      double data2[100];
+      string sdata[100];
+      MuTyV mtv;
+      for(int kk=0; kk<100; kk++) { 
+	data[kk] = kk/5.;
+	data2[kk] = cos(data[kk]);
+	mtv = kk;
+	sdata[kk] = "Str_KK=";
+        sdata[kk] += (string)(mtv);
+      }
+      cout << " CurrHDU-2 : " << fiosc.CurrentHDU() 
+      	   << " Type=" << fiosc.CurrentHDUType() <<endl;
+      FitsBlockRW<float>::WriteImageData(fiosc, data, 25);
+      fiosc.Print(); 
+      /*
+      char * ttype[2] = {"Col1", "Col2"};
+      char * tform[2] = {"E", "D"};
+      char * tunit[2] = {"", ""};
+      fiosc.CreateTable(BINARY_TBL, "rzbintbl", 2, ttype, tform, tunit);
+      */
+      vector<string> ttype, tform, tunit;
+      ttype.push_back("Col1");
+      ttype.push_back("Col2");
+      ttype.push_back("Col3");
+      tform.push_back("E");
+      tform.push_back("D");
+      tform.push_back("18A");
+      tunit.push_back("");
+      tunit.push_back("");
+      tunit.push_back("");
+      string tblnm = "rzbintbl";
+      fiosc.CreateTable(BINARY_TBL, "rzbintbl", ttype, tform, tunit);
+
+      //      cout << " MovRelToHDU , Type=" << fiosc.MoveRelToHDU(1) << endl;
+      cout << " CurrHDU-3 : " << fiosc.CurrentHDU() 
+	   << " Type=" << fiosc.CurrentHDUType() <<endl;
+      fiosc.Print(); 
+      /*
+      cout << " DBG- fios.InsertColumn(1,Col1,E) " << endl;
+      fios.InsertColumn(1,"Col1","E");
+      cout << " DBG- fios.InsertColumn(2,Col2,D) " << endl;
+      fios.InsertColumn(2,"Col2","D");
+      */
+      FitsBlockRW<float>::WriteColumnData(fiosc, 1, 1, 1, data, 100);
+      FitsBlockRW<double>::WriteColumnData(fiosc, 2, 1, 1, data2, 100);
+      FitsBlockRW<string>::WriteColumnData(fiosc, 3, 1, 1, sdata, 100);
+	    
+      // Ecriture entete
+      DVList  dvl;
+      dvl("toto") = 14;    dvl("titi") = 25.5;    
+      dvl("tata") = "Bonjour !"; 
+      dvl("hello") = 88;  dvl("Hello") = 77.77;    
+      dvl.Comment() = "Blabla ... zone commentaire ds DVList";
+      fiosc.WriteHeaderRecords(dvl);
+    }
+
+    {
+      cout << "3/=== Ecriture tableaux dans ta.fits  " << endl;
+      FitsInOutFile fiosc("!ta.fits", FitsInOutFile::Fits_Create);
+      cout << " TArray<r_4> mxf(100,50,3) , TMatrix<int_4> mxi(60,30) " << endl;
+      TArray<r_4> mxf(100,50,3);
+      mxf = RegularSequence(0., 0.2);
+      mxf.Info()["info1"] = "info1: TArray<r_4>";
+      mxf.Info()["info2"] = "info2: (100,50,3)";
+      mxf.Info()["info3 "] = "info3: mot-cle-avec-blanc";
+      cout << mxf.Info();
+      TMatrix<int_4> mxi(60,30);
+      mxi = RegularSequence();
+      mxi.Info()["MtxNRow"] = mxi.NRows();
+      mxi.Info()["MtxNCol"] = mxi.NCols();
+      mxi.Info()["MtxStr"] = "TMatrix<int_4> mxi(60,30)";
+      fiosc << mxf << mxi ;
+    }
+    {
+      cout << "4/=== Lecture tableaux depuis ta.fits  " << endl;
+      FitsInOutFile fiosc("ta.fits", FitsInOutFile::Fits_RO);
+      TArray<r_4> mxf;
+      TMatrix<int_4> mxi;
+      fiosc >> mxf >> mxi ;
+      cout << mxf;
+      cout << " mxf.Info()= " << mxf.Info() << mxi;
+      cout << " mxi.Info()= " << mxi.Info() << mxi;
+    }
+
+  }
+  catch (PThrowable & exc) {
+    cerr << " tnfits.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << "\n...exc.Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " tnfits.cc: Catched std::exception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " tnfits.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End tnfits " );
+  cout << " ---- Programme tnfits.cc-  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tnt.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tnt.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tnt.cc	(revision 3445)
@@ -0,0 +1,535 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <fstream>
+
+#include "sopnamsp.h"
+#include "histinit.h"
+#include "dvlist.h"
+#include "ntuple.h"
+#include "xntuple.h"
+#include "datatable.h"
+#include "swppfdtable.h"
+
+/*  Programme test des classes  DVList, NTuple,, XNTuple          */
+/*  DataTable et les handlers PPF                                 */
+/*  SOPHYA - R. Ansari (LAL)  -   2000 -  2005                    */
+
+void test_dvl();
+void test_ntuple();
+void test_xntuple() ; 
+void test_Xntuple() ; 
+void test_DataTable() ; 
+void test_SwPPFDataTable() ; 
+
+int main(int narg, char *arg[])
+{
+  SophyaInit();
+  if (narg < 2) {
+    cout << " tnt/Erreur arg - Usage: tnt d/n/x/X/DT/SWDT \n" 
+	 << " d:DVList n:NTuple x/X:XNTuple DT,SWDT: SwPPF/DataTable test \n" << endl;
+    exit(0);
+  }
+  int rc = 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();
+    else if (strcmp(arg[1],"DT") == 0)  test_DataTable();
+    else if (strcmp(arg[1],"SWDT") == 0)  test_SwPPFDataTable();
+  }
+  catch(PThrowable exc ) {
+    cerr << "tnt-main() , Catched exception: \n" << exc.Msg() << endl;
+    rc = 97;
+  }
+  catch(std::exception ex) {
+    cerr << "tnt-main() , Catched exception ! " << (string)(ex.what()) << endl;
+    rc = 98;
+  }
+  catch(...) {
+    cerr << "tnt-main() , Catched ... ! " << endl;
+    rc = 99;
+  }
+  return rc;
+}
+
+/*  ***** 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;
+   PInPersist fsi(fn);
+   NTuple nt2; 
+   fsi >> nt2;
+   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)dvs= " << (double)dvs << endl;
+TimeStamp ts;
+MuTyV tv = ts;
+cout << "MuTyV=TimeStamp->String: tv = " << tv 
+     << " ->double= " << (double)tv << " ->TimeStamp:" 
+     << TimeStamp((double)tv).ToString() << endl;
+tv = "1995-09-23T15:20:32";
+string tts = (string)tv;
+cout << "MuTyV=TimeStamp tv=" << tv << " ->TimeStamp(tv)=" 
+     << TimeStamp(tts) << 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["ToDay"] = ts;
+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_DataTable() 
+{
+  cout << "======= test_DataTable:  simple DataTable test ======= " << endl;
+  DataTable dt(64);
+  dt.AddIntegerColumn("line");
+  dt.AddStringColumn("sline");
+  dt.AddDoubleColumn("x");
+  dt.AddFloatColumn("f_sin");
+  dt.AddFloatColumn("f_cos");
+  dt.AddDoubleColumn("f_sinxcos");
+  dt.AddDoubleColumn("f_x2");
+  dt.AddComplexColumn("cmplx_cos_sin");
+  dt.AddDoubleComplexColumn("dcmplx_cos_sin");
+  dt.AddDateTimeColumn("datime");
+  MuTyV rec[10];
+  TimeStamp ts("01/3/2005","0:0:0"); 
+  TimeStamp ts2(0.);
+  
+  cout << " 1/ First 1000 lines .... " << endl;
+  for(int k = 0; k<1000; k++) {
+    rec[0] = k;
+    string sline = "L-";
+    sline += (string)rec[0];
+    rec[1] = sline;
+    double x = M_PI*k/100.;
+    double fx = sin(x)*cos(x);
+    double sx = sin(x);
+    double cx = cos(x);
+    rec[2] = x;
+    rec[3] = sx;
+    rec[4] = cx;
+    rec[5] = fx;
+    rec[6] = x*x;
+    rec[7] = complex<r_4>(cx, sx);
+    rec[8] = complex<r_8>(cx, sx);
+    ts2.Set(ts.ToDays()+(double)k/24.);
+    rec[9] = ts2;
+    dt.AddLine(rec);
+  }
+  cout << "1.b/ Use of = operator to make copy of dt " << endl;
+  DataTable dtc1;
+  dtc1 = dt;
+
+  dt.Show(); 
+  cout << " 2/ Lines 1000-2000  .... " << endl;
+  for(int k = 1000; k<2000; k++) {
+    rec[0] = k;
+    string sline = "L-";
+    sline += (string)rec[0];
+    rec[1] = sline;
+    double x = M_PI*k/100.;
+    double fx = sin(x)*cos(x);
+    double sx = sin(x);
+    double cx = cos(x);
+    rec[2] = x;
+    rec[3] = sx;
+    rec[4] = cx;
+    rec[5] = fx;
+    rec[6] = x*x;
+    rec[7] = complex<r_4>(cx, sx);
+    rec[8] = complex<r_8>(cx, sx);
+    ts2.Set(ts.ToDays()+(double)k/24.);
+    rec[9] = ts2;
+    dt.AddLine(rec);
+  }
+  cout << "2.b/ dt.Show();  : " << endl;
+  dt.Show();  
+  cout << "2.c/ dtc1.Show();  : " << endl;
+  dtc1.Show();  
+  cout << "2.d/  dt.LineHeaderToString() dt.LineToString(k)   : " << endl;
+  cout << dt.LineHeaderToString() << endl;
+  for(int k = 0; k<1500; k+=75) 
+    cout << "Line[" << k << "] " << dt.LineToString(k) << endl ; 
+  {
+    cout << "3/ Writing DataTable dt to PPF stream dtable.ppf " << endl;
+    POutPersist po("dtable.ppf");
+    po << dt;
+  }
+  {
+    cout << "4/ Reading DataTable dtr from PPF stream dtable.ppf " << endl;
+    PInPersist pi("dtable.ppf");
+    DataTable dtr;
+    pi >> dtr;
+    cout << "4.b/ cout << dtr; " << endl;
+    cout << dtr;
+    cout << "4.c/  dtr.LineHeaderToString() dtr.LineToString(k)   : " << endl;
+    cout << dtr.LineHeaderToString() << endl;
+    for(int k = 0; k<1500; k+=75) 
+      cout << "Line[" << k << "] " << dtr.LineToString(k) << endl ; 
+    
+  }
+  {
+    cout << "5/ Reading DataTable dtr from text file dtable.txt " << endl;
+    {
+      cout << "5.a Writing lines to file dtable.txt " << endl; 
+      ofstream os("dtable.txt");
+      dt.Print(os,0,450);
+    }
+    cout << "5.b CopyStructure + FillFromASCIIFile from dtable.txt " << endl; 
+    ifstream is("dtable.txt");
+    DataTable dtr;
+    dtr.CopyStructure(dt);
+    dtr.FillFromASCIIFile(is);
+    cout << dtr;
+    cout << "5.c/  dtr.LineHeaderToString() dtr.LineToString(k)   : " << endl;
+    cout << dtr.LineHeaderToString() << endl;
+    for(int k = 0; k<10; k++) 
+      cout << "Line[" << k << "] " << dtr.LineToString(k) << endl ; 
+    for(int k = 50; k<300; k+=25) 
+      cout << "Line[" << k << "] " << dtr.LineToString(k) << endl ; 
+    
+  }
+  cout << "6./Test with DataTableRow object " << endl; 
+  DataTable dtrow(64);
+  dtrow.AddDoubleColumn("x");
+  dtrow.AddFloatColumn("f_cos");
+  dtrow.AddStringColumn("sline");
+  dtrow.AddIntegerColumn("line");
+  dtrow.AddDateTimeColumn("datime");
+
+  DataTableRow row = dtrow.EmptyRow();
+  for(int k = 0; k<25; k++) {
+    MuTyV mtk = k;
+    string sline = "L-";
+    sline += (string)mtk;
+    row["sline"] = sline;
+    row["line"] = k;
+    double x = M_PI*k/25.;
+    double cx = cos(x);
+    row[0] = x;
+    row[1] = cx;
+    ts2.Set(ts.ToDays()+(double)k);
+    row["datime"] = ts2;
+    dtrow.AddRow(row);
+  }
+  cout << dtrow << endl;
+  cout << dtrow.LineHeaderToString() << endl;
+  for(int k = 0; k<25; k+=3) {
+    dtrow.GetRow(k, row);
+    cout << "k=" << k << " GetRow():   " << row << endl;
+    cout << " ...LineToString(): " << dtrow.LineToString(k) << endl;
+  }
+  cout << endl;
+  cout << "============ FIN  test_DataTable ============== " << endl;  
+}
+
+void test_SwPPFDataTable() 
+{
+  cout << "======= test_SwPPFDataTable():  simple SwPPFDataTable test ======= " << endl;
+  {
+    POutPersist po("swdtable.ppf");
+    SwPPFDataTable dt(po, 64);
+    dt.AddIntegerColumn("line");
+    dt.AddStringColumn("sline");
+    dt.AddDoubleColumn("x");
+    dt.AddFloatColumn("f_sin");
+    dt.AddFloatColumn("f_cos");
+    dt.AddDoubleColumn("f_sinxcos");
+    dt.AddDoubleColumn("f_x2");
+    dt.AddComplexColumn("cmplx_cos_sin");
+    dt.AddDoubleComplexColumn("dcmplx_cos_sin");
+    dt.AddDateTimeColumn("datime");
+    MuTyV rec[10];
+    TimeStamp ts("01/3/2005","0:0:0"); 
+    TimeStamp ts2(0.);
+    cout << " 1/ First 1000 lines .... " << endl;
+    for(int k = 0; k<1000; k++) {
+      rec[0] = k;
+      string sline = "L-";
+      sline += (string)rec[0];
+      rec[1] = sline;
+      double x = M_PI*k/100.;
+      double fx = sin(x)*cos(x);
+      double sx = sin(x);
+      double cx = cos(x);
+      rec[2] = x;
+      rec[3] = sx;
+      rec[4] = cx;
+      rec[5] = fx;
+      rec[6] = x*x;
+      rec[7] = complex<r_4>(cx, sx);
+      rec[8] = complex<r_8>(cx, sx);
+      ts2.Set(ts.ToDays()+(double)k/24.);
+      rec[9] = ts2;
+      dt.AddLine(rec);
+    }
+    cout << "1.b/ Use of = operator to make copy of dt " << endl;
+    SwPPFDataTable dtc1;
+    dtc1 = dt;
+    dt.Show(); 
+    cout << " 2/ Lines 1000-2000  .... " << endl;
+    for(int k = 1000; k<2000; k++) {
+      rec[0] = k;
+      string sline = "L-";
+      sline += (string)rec[0];
+      rec[1] = sline;
+      double x = M_PI*k/100.;
+      double fx = sin(x)*cos(x);
+      double sx = sin(x);
+      double cx = cos(x);
+      rec[2] = x;
+      rec[3] = sx;
+      rec[4] = cx;
+      rec[5] = fx;
+      rec[6] = x*x;
+      rec[7] = complex<r_4>(cx, sx);
+      rec[8] = complex<r_8>(cx, sx);
+      ts2.Set(ts.ToDays()+(double)k/24.);
+      rec[9] = ts2;
+      dt.AddLine(rec);
+    }
+    cout << "2.b/ dt.Show();  : " << endl;
+    dt.Show();  
+    cout << "2.c/ dtc1.Show();  : " << endl;
+    dtc1.Show();  
+    cout << "3/ Writing SwPPFDataTable dt to PPF stream swdtable.ppf " << endl;
+    po << dt;
+  }
+  {
+    cout << "4/ Reading SwPPFDataTable dtr from PPF stream swdtable.ppf " << endl;
+    PInPersist pi("swdtable.ppf");
+    SwPPFDataTable dtr;
+    pi >> dtr;
+    cout << "4.b/ cout << dtr; " << endl;
+    cout << dtr;
+    cout << "4.c/  dtr.LineHeaderToString() dtr.LineToString(k)   : " << endl;
+    cout << dtr.LineHeaderToString() << endl;
+    for(int k = 0; k<1500; k+=75) 
+      cout << "Line[" << k << "] " << dtr.LineToString(k) << endl ;     
+  }
+
+  cout << "============ FIN  test_SwPPFDataTable() ======== ======= " << endl;  
+}
+
+
+
+
+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_Nov2007/SophyaProg/Tests/tobjio.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tobjio.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tobjio.cc	(revision 3445)
@@ -0,0 +1,174 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "sopnamsp.h"
+#include "math.h"
+#include <iostream>
+#include <string>
+
+// Pour le test 
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+
+
+#include "fmath.h"
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tobjio2.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tobjio2.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tobjio2.cc	(revision 3445)
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include <string>
+
+// Pour le test 
+#include "sopnamsp.h"
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+#include "tarray.h"
+
+
+#include "fmath.h"
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tpipe.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tpipe.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tpipe.cc	(revision 3445)
@@ -0,0 +1,194 @@
+#include "sopnamsp.h"
+#include "zthread.h"
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+
+#include <time.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "timing.h"
+
+/*  --------------------------------------------------------- */
+/*  ------ -Programme de test des tuyaux unix  (pipe) ------  */
+/*  Avec creation de threads (les ZThread de Sophya)          */
+/*  Ou avec creation de process (fork())                      */
+/*    Octobre 2003 -   C. Magneville,  R. Ansari              */
+/*  --------------------------------------------------------- */
+
+/* Identificateur de fichier de pipe */
+/* pipe_desc[0] : lecture  pipe_desc[1] : ecriture */
+static int pipe_desc[2];
+
+/* fonction a executer dans le thread 1 ou process 1 */
+void write_to_pipe(void * arg);
+/* fonction a executer dans le thread 2 ou process 2 */
+void read_frpipe(void * arg);
+
+/* Tailles en nombre de double */
+static int NSample; /*  Nombre total d'echantillons */ 
+static int NBlk1;   /*  Taille de paquet en ecriture (Thr1 ou Proc1) */
+static int NBlk2;   /*  Taille de paquet en lecture (Thr2 ou Proc2) */
+static double DeltaX;  /* pas du calcul de cosinus */
+
+int main(int narg, char *arg[])
+
+{
+
+  if ((narg < 5) || ((narg>1)&&(strcmp(arg[1],"-h")==0)) ) {
+    cout << " Usage: tpipe T/P NSample Blk1 Blk2 \n " 
+	 << "   T --> Threads , P --> 2 process \n" 
+	 << "   NSample: Nb total d'echantillons \n"
+	 << "   NBlk1: Taille de paquet en ecriture \n"
+	 << "   NBlk2: Taille de paquet en lecture \n" << endl;
+    return(0);
+  }
+  
+  if ((*arg[1] != 'T') && (*arg[1] != 'P')) {
+    cout << " tpipe: arg erreur / specifiez T ou P , tpipe -h pour aide \n" << endl;
+    return 1;
+  }
+
+  char proc_or_thread = *arg[1];
+  NSample = atoi(arg[2]);
+  NBlk1 = atoi(arg[3]);
+  NBlk2 = atoi(arg[4]);
+  double DeltaX = 50.*M_PI/(double)NSample;
+  cout << " ===============  tpipe (Pipe Test Program) =================" << endl;
+  if (proc_or_thread == 'T') cout << " ----> avec Threads " << endl;
+  else cout << " ----> avec fork() / process  " << endl;
+  cout << " -- NSample= " << NSample << " NBlk1=" << NBlk1
+       << " NBlk2=" << NBlk2 << endl;
+  cout << " ============================================================\n" << endl;
+
+  InitTim();
+
+  cout << ">> tpipe: Opening pipe ... " << endl;
+  int rc = pipe(pipe_desc);
+  if (rc != 0) { 
+    cout << " ERREUR creation pipe !" << endl;
+    return 99;
+  }
+  if (proc_or_thread == 'T') {
+    cout << ">> tpipe: Creation des Threads ... " << endl;
+    
+    ZThread zt1;
+    zt1.setAction(write_to_pipe, arg[1]);
+    ZThread zt2;
+    zt2.setAction(read_frpipe, arg[2]);
+    cout << ">> tpipe: Start des Threads Z1 et Z2 ... " << endl;
+    zt1.start();
+    zt2.start();
+    cout << ">> tpipe: Attente z1/2.join() ... " << endl;
+    zt1.join();
+    zt2.join();
+    cout << ">> tpipe: Thread Z1 and Z2  joined " << endl;
+    PrtTim("EndOftpipe_Threads ");
+  }
+  else {
+    cout << ">> tpipe: fork() - creation de process ... " << endl;
+    char * zzz = "toto";
+    pid_t rcf = fork();
+    if (rcf == 0) {
+      cout << ">> tpipe: Processus FILS - PID= " << getpid() 
+	   << " -> execution de read_frpipe()" << endl;
+      read_frpipe(zzz);
+      cout << ">> tpipe: FIN execution read_frpipe() ds FILS - PID= " << getpid() << endl;
+      PrtTim("EndOffun_Fils ");
+    }
+    else {
+      cout << ">> tpipe: Processus PERE - PID= " << getpid() 
+	   << " -> execution de read_frpipe()" << endl;
+      write_to_pipe(zzz);
+      cout << ">> tpipe: FIN execution write_to_pipe() ds PERE - PID= " << getpid() << endl;
+      PrtTim("EndOffun_Pere ");
+      cout << ">> tpipe: Attente processus fils PID=" << rcf << endl;
+      int status_procs[20];
+      waitpid(rcf, status_procs, 0);
+      cout << ">> tpipe: Status fils= " << status_procs[0] << endl;
+    }
+  }
+
+  char buff[128];
+  sprintf(buff,"EndOftpipe-PID=%d ",getpid());
+  PrtTim(buff);
+  cout << " ======= Fin du programme tpipe (PID= " << getpid() 
+       << ") ======= \n" << endl;
+ 
+  return(0);
+  
+}
+
+/* fonction a executer dans le thread 1 ou process 1 : write to pipe */
+void write_to_pipe(void *arg)
+{
+  double * d = new double[NBlk1];
+  int ns = 0;
+  cout << " ====> fonction write_to_pipe : START write to pipe ... " << endl;
+  for(int k=0; k<NSample; k+=NBlk1) {
+    // ---------------------
+    for(int i=0; i<NBlk1; i++) d[i] = cos((k+i)*DeltaX)+log((k+i)*DeltaX*100.+0.1);
+    // d[0] continet le numero d'un element particulier 
+    // dont la valeur est multipliee par 3
+    int kkr = random()%NBlk1;
+    d[0] = kkr+0.1;
+    d[kkr] *= 3.; 
+    // ---------------------
+    int nwrt = NBlk1;
+    if (k+NBlk1 > NSample) nwrt = NSample-k;
+    write(pipe_desc[1], d, nwrt*sizeof(double));  
+    ns += nwrt;
+  }
+  cout << " ====> fonction write_to_pipe : END write to pipe NSample= " << ns << endl;
+  delete[] d;
+
+  return;
+}
+
+/* fonction a executer dans le thread 2 ou process 2 : read from pipe */
+void read_frpipe(void *arg)
+{
+  double * d = new double[NBlk2];
+  char * cd = (char *)d;
+  char * ccd = cd;
+  int ns = 0;
+  int nerr = 0; 
+  int nwait = 0;
+  cout << " ====> fonction read_frpipe : START read from pipe ... " << endl;
+  int kkr = -1;
+  for(int k=0; k<NSample; k+=NBlk2) {
+    for(int ii=0; ii<NBlk2; ii++) d[ii] = -2.;
+    int nrd = NBlk2;
+    if (k+NBlk2 > NSample) nrd = NSample-k;
+    ssize_t nrdok = read(pipe_desc[0], d, nrd*sizeof(double));
+    if (nrdok != nrd*sizeof(double)) {
+      int nrdc = nrd*sizeof(double)-nrdok;
+      ccd = cd + nrdok;
+      while (nrdc != 0) {
+	nwait++;
+	usleep(1000);
+	nrdok = read(pipe_desc[0], ccd, nrdc);
+	nrdc -= nrdok;
+	ccd += nrdok;
+      }
+    }
+    ns += nrd;
+    for(int i=0; i<nrd; i++) {
+      if ((k+i)%NBlk1 == 0)  { kkr = d[i]; continue; }
+      double xp = cos((k+i)*DeltaX)+log((k+i)*DeltaX*100.+0.1);
+      if (((k+i)%NBlk1) == kkr) xp *= 3.;
+      if (fabs(d[i]-xp) > 1.e-39)  nerr++ ;
+    }
+  }
+  cout << " ====> fonction read_frpipe : END read from pipe NSample= " 
+       << ns << " NErr=" << nerr << endl;
+  cout << " ====> fonction read_frpipe NWait= " << nwait << endl; 
+  delete[] d;
+
+  return;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tsimplex.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tsimplex.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tsimplex.cc	(revision 3445)
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream>
+#include <string>
+
+#include "sopnamsp.h"
+#include "simplex.h"
+#include "histinit.h"
+#include "pexceptions.h"
+#include <typeinfo>
+#include "timing.h"
+
+int main(int narg, char* arg[])
+{
+  cout << " ---- Programme tsimplex.cc - Test de Minimisation simplex --- " << endl;
+  int prt = 0;
+  int tsel = -1;
+  int rc = 0;
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0)) {
+    cout << " tsimplex: test de Minimisation simplex (classe MinZSimplex) \n"
+	 << "   Usage: tsimplex [ISel (=-1,0,..,4) PrtLev (=0,1,2,...) \n" 
+	 << "   defaut Isel=-1 (all) , PrtLev=0 \n " << endl;
+    return rc;
+  } 
+  if (narg > 1) tsel = atoi(arg[1]);
+  if (narg > 2) prt = atoi(arg[2]);
+  try {
+    SophyaInit();
+    InitTim();
+    rc = MinZSimplex::AutoTest(tsel, prt);
+  }
+  catch (PThrowable & exc) {
+    cerr << " tsimplex.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " tsimplex.cc: Catched std::xception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " tsimplex.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End tsimplex " );
+  cout << " ---- Programme tsimplex.cc -  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tsphereecp.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tsphereecp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tsphereecp.cc	(revision 3445)
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "sopnamsp.h"
+#include "math.h"
+#include <iostream>
+#include <string>
+
+#include "sambainit.h"
+#include "pexceptions.h"
+#include <typeinfo>
+#include "timing.h"
+#include "sphereecp.h"
+#include "fiosphereecp.h"
+#include "array.h"
+#include "samba.h"
+
+int main(int narg, char* arg[])
+{
+  cout << " ---- Programme tsphereecp.cc - Test SphereECP --- " << endl;
+  int rc = 0;
+  try {
+    SophyaInit();
+    
+    InitTim();
+    SphereECP<r_8> ecp(M_PI/2.-0.05, M_PI/2.+0.05, 10, 0., 0.2, 10);
+    ecp.SetPixels(15.);
+    cout << ecp ;
+ 
+    SphereECP<r_8> ecp2;
+    ecp2 = ecp;
+    ecp2 += 4.;
+    cout << " ecp2 = ecp+4. = \n " << ecp2 ;
+    {
+      cout << " Writing ecp ecp2 to POutPersist sphecp.ppf " << endl;
+      POutPersist po("sphecp.ppf");
+      po << ecp << ecp2;
+    }
+    {
+      SphereECP<r_8> recp, recp2;
+      cout << " Reading from sphecp.ppf " << endl;
+      PInPersist pi("sphecp.ppf");
+      pi >> recp >> recp2;
+      cout << " recp recp2 from PInPersist " << endl; 
+      cout << recp;
+      cout << recp2;
+    }
+    // Test avec transforme Ylm 
+    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;
+    SphereECP<r_8> map(256);
+    cout << " Generating map from Cl " << endl;
+    ylmserver.GenerateFromCl(map, -1,  clin, 0.);
+    cout << " Computing Cl from map " << endl;
+    Vector clout = ylmserver.DecomposeToCl(map, lmax,  0.);
+    SphereECP<r_8> mappar(0.25*M_PI, 0.75*M_PI, 128, 0.25*M_PI, 1.25*M_PI, 256);
+    cout << " Generating partial map from Cl " << endl;
+    ylmserver.GenerateFromCl(mappar, -1,  clin, 0.);
+    cout << " Computing Cl from partialmap " << endl;
+    Vector cloutpar = ylmserver.DecomposeToCl(mappar, lmax,  0.);
+
+    cout << " Writing clin, map, clout to ecpylm.ppf" << endl;
+    POutPersist so("ecpylm.ppf");
+    so << PPFNameTag("clin") << clin <<  PPFNameTag("map") << map
+       << PPFNameTag("clout") << clout ;
+    cout << " Writing mappar, cloutpar to ecpylm.ppf" << endl;
+    so << PPFNameTag("mappar") << mappar
+       << PPFNameTag("cloutpar") << cloutpar ;
+  }
+  catch (PThrowable & exc) {
+    cerr << " tsphereecp.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " tsphereecp.cc: Catched std::xception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " ssphereecp.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End tsphereecp " );
+  cout << " ---- Programme tsphereecp.cc -  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tspm.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tspm.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tspm.cc	(revision 3445)
@@ -0,0 +1,138 @@
+#include <iostream>
+#include "sopnamsp.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(string("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_Nov2007/SophyaProg/Tests/tspm2.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tspm2.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tspm2.cc	(revision 3445)
@@ -0,0 +1,209 @@
+#include <iostream>
+#include <math.h>
+#include "sopnamsp.h"
+#include "sambainit.h"
+#include "skymap.h"
+
+#include "tod.h"
+#include "fitstarray.h"
+#include "fitsspherehealpix.h"
+#include "srandgen.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_Nov2007/SophyaProg/Tests/tstboloread.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstboloread.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstboloread.cc	(revision 3445)
@@ -0,0 +1,201 @@
+// 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 "sopnamsp.h"
+#include "machdefs.h"
+#include <typeinfo>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+// #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_Nov2007/SophyaProg/Tests/tstcolread.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstcolread.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstcolread.cc	(revision 3445)
@@ -0,0 +1,178 @@
+// Test des classes FitsBTColRead
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <typeinfo>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+// #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) {
+    LONGLONG 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(LONGLONG 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;
+  LONGLONG istep = fbt->GetNbLine()/10; if(istep>1000) istep=1000;
+  for(LONGLONG i=0;i<fbt->GetNbLine();i+=istep) {
+    LONGLONG i2=i+istep-1; if(i2>=fbt->GetNbLine()) i2=fbt->GetNbLine()-1;
+    LONGLONG 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_Nov2007/SophyaProg/Tests/tstdtable.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstdtable.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstdtable.cc	(revision 3445)
@@ -0,0 +1,171 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.h"
+#include "histinit.h"
+#include "ctimer.h"
+#include "datatable.h"
+#include "swppfdtable.h"
+
+/*  Programme test performances des DataTables / cf G. Barrand    */
+/*  R. Ansari (LAL)  -   Avril 2005                    */
+
+static int prtlev = 1;  // niveau d'impression 
+
+void cre_rempli_table(BaseDataTable& dt, sa_size_t nl)
+{
+  Timer tm("cre_rempli_table");
+  cout << " tstdtable/Info: cre_rempli_table() avec nl = " << nl << endl;
+  // Ajout de colonnes int + 6 x double
+  dt.AddIntegerColumn("i");
+  dt.AddDoubleColumn("p1");
+  dt.AddDoubleColumn("p2");
+  dt.AddDoubleColumn("p3");
+  dt.AddDoubleColumn("p4");
+  dt.AddDoubleColumn("p5");
+  dt.AddDoubleColumn("p6");
+  // remplissage :
+  MuTyV rec[10];
+  //  r_8 rec[10];  Si on veut tout remplir avec des double
+  sa_size_t nl10 = nl/10;
+  for(sa_size_t k=0; k<nl; k++) {
+    rec[0] = (int_4)(k+1);
+    rec[1] = (r_8)(k*M_PI);
+    rec[2] = (r_8)(2*k*M_PI);
+    rec[3] = (r_8)(3*k*M_PI);
+    rec[4] = (r_8)(4*k*M_PI);
+    rec[5] = (r_8)(5*k*M_PI);
+    rec[6] = (r_8)(6*k*M_PI);
+    dt.AddLine(rec);    
+    if ( (prtlev > 1) && ((k%nl10)==0) )
+      cout << "cre_rempli_table/Info fin remplissage ligne " << k << endl;
+  }
+  tm.Split("cre_rempli_table/fin remplissage");
+  // Impression resume de la table :
+  if (prtlev > 0) cout << dt ;
+  return;
+}
+
+void lit_ck_table(BaseDataTable& dt)
+{
+  cout << " tstdtable/Info: lit_ck_table() - Table: " << endl; 
+  if (prtlev > 0) cout << dt;
+  if (dt.NEntry() < 1) {
+    cout << " tstdtable/Error: Table vide ! " << endl;
+    return;
+  }
+  r_8 mean[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0. };
+  r_8* rec;
+  sa_size_t nl10 = dt.NEntry()/10;
+  for(sa_size_t k=0; k<dt.NEntry(); k++) {
+    rec = dt.GetLineD(k);
+    for(int i=0; i<7; i++) mean[i] += rec[i];
+    if ( (prtlev > 1) && ((k%nl10)==0) )
+      cout << "li_ck_table/Info fin check ligne " << k << endl;
+  }
+  double wtot = dt.NEntry();
+  for(int i=0; i<7; i++) { 
+    mean[i] /= wtot;
+    if (prtlev > 0)    
+      cout << " tstdtable/Info: Moyenne[" << i << "]= " << mean[i] << endl;
+  }
+  return;
+}
+
+int main(int narg, char *arg[])
+{
+  if (narg < 3) {
+    cout << " tstdtable/Erreur: arguments manquants \n"
+	 << " Usage: tstdtable r/w filename [mem/swap] [Nlines] [segsize] [prtlev] \n" 
+	 << "  r : lecture depuis filename - calcule moyenne \n"
+	 << "  w : creation / ecriture ds filename \n"
+	 << "  NLines: Nombre de lignes de la table si w (defaut=10^6) \n"
+	 << "  mem: Utilisation de DataTable (memoire) = defaut \n"
+	 << "  swap: Utilisation de SwPPFDataTable (swap sur PPF) \n"
+	 << "  segsize: Taille de segment (defaut=1024) \n"
+	 << "  prtlev: Niveau d'impression 0,1,2 (defaut=1) \n"
+	 << endl;
+    return 1;
+  }
+
+  try {
+    SophyaInit();
+    char oper = *arg[1];
+    string fname = arg[2];
+    sa_size_t nlines = 1000000;
+    sa_size_t segsize = 1024;
+    string msw = "mem";
+    if (narg > 3) msw = arg[3];
+    if (narg > 4) nlines = atol(arg[4]);
+    if (narg > 5) segsize = atol(arg[5]);
+    prtlev = 1;
+    if (narg > 6) prtlev = atoi(arg[6]);
+   cout << "======== tstdtable: DataTable/G.Barrand test de performance I/O ========" << endl;
+    cout << " Operation= " << oper << " FileName= " << fname 
+	 << " (NLines= " << nlines << " Mem/Swap= " << msw << " )" << endl;
+//----------  Creation , ecriture table
+    if (oper == 'w') { 
+      if (msw == "mem") {
+	Timer tm("DTable:Mem/W");
+	cout << "1/ tstdtable/Info: Creation/Ecriture DataTable (memoire) " << endl;
+	DataTable dt(segsize);
+	cre_rempli_table(dt, nlines);
+	tm.Split("Mem/W:Fin-Remplissage");
+	cout << "2/ tstdtable/Info: Ecriture DataTable ds " << fname << endl;
+	POutPersist so(fname);
+	so << dt;
+	tm.Split("Mem/W:Fin-PPFWrite");
+      }
+      else {
+	Timer tm("DTable:Swap/W");
+	cout << "1/ tstdtable/Info: Creation/Ecriture DataTable (PPFSwap) " << endl;
+	POutPersist so(fname);
+	SwPPFDataTable dt(so, segsize);
+	cre_rempli_table(dt, nlines);
+	tm.Split("Swap/W:Fin-Remplissage");
+	cout << "2/ tstdtable/Info: Ecriture DataTable ds " << fname << endl;
+	so << dt;
+	tm.Split("Mem/W:Fin-Ecriture");
+      }
+    }
+//----------  Lecture/verification table
+    else {
+      if (msw == "mem") {
+	Timer tm("DTable:Mem/R");
+	cout << "1/ tstdtable/Info: Lecture DataTable (memoire) de " << fname << endl;
+	DataTable dt;
+	PInPersist si(fname);
+	si >> dt;
+	tm.Split("Mem/R:Fin-PPFRead");
+	cout << "2/ tstdtable/Info: Lecture/verification table " << endl;
+	lit_ck_table(dt);
+	tm.Split("Mem/R:Fin-CheckLecture");
+      }
+      else {
+	Timer tm("DTable:Swap/R");
+	cout << "1/ tstdtable/Info: Lecture DataTable (swap) de " << fname << endl;
+	SwPPFDataTable dt;
+	PInPersist si(fname);
+	si >> dt;
+	tm.Split("Swap/R:Fin-PPFRead");
+	cout << "2/ tstdtable/Info: Lecture/verification table " << endl;
+	lit_ck_table(dt);
+	tm.Split("Swap/R:Fin-CheckLecture");
+      }
+    }
+
+  }
+  catch(PThrowable& exc ) {
+    cerr << "tstdtable-main() , Catched exception: \n" << exc.Msg() << endl;
+  }
+  catch(std::exception& ex) {
+    cerr << "tstdtable-main() , Catched exception ! " << (string)(ex.what()) << endl;
+  }
+  catch(...) {
+    cerr << "tstdtable-main() , Catched ... ! " << endl;
+  }
+  cout << "============== tstdtable: DataTable =================" << endl;  
+  return 0;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tstndblk.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstndblk.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstndblk.cc	(revision 3445)
@@ -0,0 +1,223 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaProg/Tests/tstppfwrapstl.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstppfwrapstl.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstppfwrapstl.cc	(revision 3445)
@@ -0,0 +1,155 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream>
+#include <string>
+
+#include <typeinfo>
+#include "timing.h"
+#include "histinit.h"
+#include "pexceptions.h"
+#include "ppfwrapstlv.h" 
+
+/*  Programme test du PPFWrapper pour les vecteurs de la STL */
+/*  SOPHYA - R. Ansari (LAL)  -   Avril 2005                 */
+ 
+int main(int narg, char* arg[])
+{
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+    cout << " tstppfwrapstl : Test classes PPFWrapper \n"
+	 << "   Usage: tstppfwrapstl [VectorSize=10] [prtlev=0,1] " << endl;
+    return 0;
+  }
+  cout << " ---- Programme tstppfwrapstl.cc ---- \n" 
+       << "      ::: Test classes PPFWrapper de std::vector ::: " << endl;
+  int prtlev = 0;
+  int SZV = 10;
+  if (narg > 1) SZV = atoi(arg[1]); 
+  if (narg > 2) prtlev = atoi(arg[2]);
+  cout << " ----- Test PPFWrapperSTLVector<T> Size= " << SZV << " PrtLev= " 
+       << prtlev << endl;
+  int rc = 0;
+  try {
+    SophyaInit();
+
+    InitTim(); 
+    vector<float> vw(SZV);
+    for(int k=0; k<SZV; k++) vw[k] = 3.141596*k;
+    #define MyNSC 6 
+    char * strcst[MyNSC] = { "Langage C++" , "Programmation Objet", "Calcul scientifique",
+			   "Librairie de classes", "SOPHYA", " et Java alors ?"};
+
+    cout << "1/ Initialisation  vector<float> vf , vector<int> vi , vector<string> vs " << endl;
+    
+    vector<float> vf(SZV);
+    vector<string> vs(SZV); 
+    vector<int> vi(SZV);
+    for(int k=0; k<SZV; k++) { 
+      vf[k] = 3.141596*k;
+      vs[k] = strcst[k%MyNSC];
+      vi[k] = random();
+    }
+    if (prtlev > 0) {
+      cout << "  vector<float> vf Size= " << vf.size() << " values: \n" ;
+      int k;
+      for(k=0; k<vf.size(); k++) cout << vf[k] << " ;  ";
+      cout << endl;
+      cout << "  vector<int> vi Size= " << vi.size() << " values: \n" ;
+      for(k=0; k<vi.size(); k++) cout << vi[k] << " ;  ";
+      cout << endl;
+      cout << "  vector<string> vs Size= " << vs.size() << " values: \n" ;
+      for(k=0; k<vs.size(); k++) cout << vs[k] << " ;  ";
+      cout << endl;
+    }
+    {
+      cout << "2/  Ecriture vf vi vs ds  fichier wrapstl.ppf" << endl;
+      POutPersist so("wrapstl.ppf");
+      so << PPFNameTag("STLVec<float>") << vf; 
+      so << PPFNameTag("STLVec<string>") << vs; 
+      so << PPFNameTag("STLVec<int>") << vi; 
+    }
+    vector<string> vsr;
+    vector<int> vir;
+    vector<float> vfr;
+    {
+      cout << "3/ Relecture vfr vir vsr depuis fichier wrapstl.ppf " << endl;
+      PInPersist si("wrapstl.ppf");
+      si >> PPFNameTag("STLVec<string>") >> vsr >> vir; 
+      si >> PPFNameTag("STLVec<float>") >> vfr;
+      if (prtlev > 0) {
+	cout << "  vector<float> vfr Size= " << vfr.size() << " values: \n" ;
+	int k;
+	for(k=0; k<vfr.size(); k++) cout << vfr[k] << " ;  ";
+	cout << endl;
+	cout << "  vector<int> vir Size= " << vir.size() << " values: \n" ;
+	for(k=0; k<vir.size(); k++) cout << vir[k] << " ;  ";
+	cout << endl;
+	cout << "  vector<string> vsr Size= " << vsr.size() << " values: \n" ;
+	for(k=0; k<vsr.size(); k++) cout << vsr[k] << " ;  ";
+	cout << endl;
+      }
+    }
+    cout << "3/ Comparaison vfr<>vf vir<>vr vsr<>vr  " << endl;
+    int k;
+    if (vfr.size() != vf.size()) {
+      cout << "  ... Difference de taille vf et vfr " << endl;
+      rc += 1;
+    }
+    else {
+      int ndiff = 0;
+      for(k=0; k<vfr.size(); k++) 
+	if (vfr[k] != vf[k]) ndiff ++;
+      if (ndiff != 0) { 
+	cout << " vf <> vfr  NDiff = " << ndiff << endl;
+	rc += 2;
+      }
+    }
+    if (vir.size() != vi.size()) {
+      cout << "  ... Difference de taille vi et vir " << endl;
+      rc += 4;
+    }
+    else {
+      int ndiff = 0;
+      for(k=0; k<vir.size(); k++) 
+	if (vir[k] != vi[k]) ndiff ++;
+      if (ndiff != 0) { 
+	cout << " vi <> vir  NDiff = " << ndiff << endl;
+	rc += 8;
+      }
+    }
+    if (vsr.size() != vs.size()) {
+      cout << "  ... Difference de taille vi et vir " << endl;
+      rc += 16;
+    }
+    else {
+      int ndiff = 0;
+      for(k=0; k<vsr.size(); k++) 
+	if (vsr[k] != vs[k]) ndiff ++;
+      if (ndiff != 0) { 
+	cout << " vs <> vsr  NDiff = " << ndiff << endl;
+	rc += 32;
+      }
+    }
+    if (rc == 0) cout << " .... Comparaison OK " << endl;
+
+  }
+  catch (PThrowable & exc) {
+    cerr << " tstppfwrapstl.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " tstppfwrapstl.cc: Catched std::xception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " tstppfwrapstl.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End tstppfwrapstl  " );
+  cout << " ---- Programme tstppfwrapstl.cc -  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tstsegdb.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tstsegdb.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tstsegdb.cc	(revision 3445)
@@ -0,0 +1,116 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream>
+#include <string>
+
+#include <typeinfo>
+#include "timing.h"
+#include "histinit.h"
+#include "pexceptions.h"
+#include "segdatablock.h"
+#include "fiosegdb.h" 
+#include "swsegdb.h" 
+#include "ppfswapper.h" 
+#include "ppfwrapstlv.h"
+
+/*  Programme test des classes  SegDataBlock<T> et son PPF writer */
+/*  SwSegDataBlock<T> avec le swapper PPF                         */
+/*  SOPHYA - R. Ansari (LAL)  -   Avril 2005                      */
+ 
+int main(int narg, char* arg[])
+{
+  cout << " ---- Programme tstsegdb.cc ----- \n" 
+       << "     Test classe SegDataBlock<T> et  SwSegDataBlock<T>  " << endl;
+  int rc = 0;
+  try {
+      SophyaInit();
+
+    InitTim(); 
+    cout << "1/ Test SegDataBlock Creation,remplissage, impression (segi, ssegi, sgds" << endl;
+    SegDataBlock<int> segi;
+    segi.Extend();
+    cout << segi;
+
+    SegDataBlock<int> ssegi(segi);
+    segi = 432;
+    ssegi.Extend(); 
+    ssegi.Print(cout, 4, " , ");
+    SegDataBlock<string> sgds(5,3); 
+    cout << sgds;
+    sgds[2] = "bonjour";  sgds[5] = "AAAA"; 
+    sgds[8] = "BbbBBbb";
+    sgds.Print(cout, 4, " ; ");
+    cout << "1.b/ Appel operateur copie : sgsdscp = sgds " << endl;
+    SegDataBlock<string> sgdscp;
+    sgdscp = sgds;
+    {
+      cout << "2/ Ecriture segi sgds et ssegi dans segdb.ppf " << endl;
+      POutPersist so("segdb.ppf");
+      so << segi << sgds << ssegi;
+    }
+    {
+      cout << "3/ Lecture depuis segdb.ppf et print " << endl;
+      SegDataBlock<int> rsd1, rsd2;
+      SegDataBlock<string> rsds;
+      PInPersist si("segdb.ppf");
+      si >> rsd1 >> rsds >> rsd2;
+      rsds.Print(cout, 4, " ; ");
+      cout << "4/ On modifie certains elements de rsd1 et on verifie le partage de reference en lecture" << endl;
+      for(int jj=0; jj<rsd1.Size(); jj += 9) 
+	rsd1[jj] = 999;
+      rsd1.Print(cout, 4, " , ");
+      rsd2.Print(cout, 4, " , ");
+    }
+    cout << "5/ Test  SwSegDataBlock<T>  creation/remplissage  " << endl;
+    int SWSEGSZ = 4;
+    {
+      cout << " Creation PPFDataSwapper<float> swout(so) avec swseg.ppf " << endl;
+      POutPersist so("swseg.ppf");
+      PPFDataSwapper<float> swout(so);
+      SwSegDataBlock<float> swsd(swout, SWSEGSZ, 3);
+      float * fp = swsd.GetSegment(0);
+      fp[0] = 6.54321;   fp[1] = 65.4321;  fp[2] = 654.321;  fp[3] = 6543.21;
+      fp = swsd.GetSegment(1);
+      fp[0] = 2.56789;   fp[1] = 25.6789;  fp[2] = 256.789;  fp[3] = 2567.89;
+      fp = swsd.GetSegment(2);
+      fp[0] = 12.567;   fp[1] = 225.67;  fp[2] = 3256.7;  fp[3] = 42567.;
+      vector<int_8> tags = swsd.GetSwapPosTagTable();
+      so << tags;
+    }
+    {
+      cout << "6/ Creation PPFDataSwapper<float> avec lecture depuis swseg.ppf " << endl;
+      PInPersist si("swseg.ppf");
+      PPFDataSwapper<float> swin(si);
+      vector<int_8> tags;
+      si >> tags;
+      SwSegDataBlock<float> swsd(swin, tags, SWSEGSZ);
+      cout <<"7/ Recopie ds SegDataBlock<float> depuis SwSegDataBlock<float> et print" << endl;
+      SegDataBlock<float> segf,segf2;
+      segf = swsd;
+      segf.Print(cout, 4, "  ");
+      segf2 = swsd;
+      segf2.Print(cout, 4, "  ");
+    }
+   
+  }
+  catch (PThrowable & exc) {
+    cerr << " tstsegdb.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " tstsegdb.cc: Catched std::xception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " tstsegdb.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End tstsegdb " );
+  cout << " ---- Programme tstsegdb.cc -  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tsttmat.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tsttmat.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tsttmat.cc	(revision 3445)
@@ -0,0 +1,228 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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 = 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 = AAA * C;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"a:"<<endl<<a;
+TMatrix<r_8> b(B,false);
+cout<<"Matrices BBB = 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 = 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 = 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 = Xinv * X;
+cout<<"Xinv = 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_Nov2007/SophyaProg/Tests/tsttminv.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tsttminv.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tsttminv.cc	(revision 3445)
@@ -0,0 +1,634 @@
+// Test de l'inversion de matrices et valeurs propres (avec Lapack) (cmv 21/07/04)
+//       cmvtminv -a 1234 -l 0 -s 1 -b 25,10000 -n 50 -S
+
+///////////////////////////////////////////////////
+///////////////////////////////////////////////////
+// PARTIE POUVANT ETRE CHANGEE PAR L'UTILISATEUR //
+///////////////////////////////////////////////////
+///////////////////////////////////////////////////
+
+// --- Choix de travailler avec des matrices complexes ?
+//#define COMPLEX
+
+//////////////////////////////////////////////////
+// --- Choix de travailler en simple precision ?
+//#define PRECIS32
+
+//////////////////////////////////////////////////
+// --- Choix GausPiv + Lapack ?
+#define USE_GAUSPIV
+#define USE_LAPACK
+
+// --- Choix de ce que doit faire Lapack
+#define ALSO_LAPACK_INV
+#define ALSO_LAPACK_INV_SYM
+#define ALSO_LAPACK_INV_LSS
+#define ALSO_LAPACK_INV_LSS_SVD
+#define ALSO_LAPACK_EV
+#define ALSO_LAPACK_EV_SYM
+#define ALSO_LAPACK_SVD
+#define ALSO_LAPACK_SVD_DC
+
+//////////////////////////////////////////////////
+//////////////////////////////////////////////////
+//           NE RIEN CHANGER CI-APRES           //
+//////////////////////////////////////////////////
+//////////////////////////////////////////////////
+
+//////////////////////////////////////////////////
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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"
+#if defined(USE_LAPACK)
+#include "intflapack.h"
+#endif
+
+//////////////////////////////////////////////////
+#if defined(COMPLEX)
+  #if defined(PRECIS32)
+    #define TYPE complex<r_4>
+    #define TYPER r_4
+  #else
+    #define TYPE complex<r_8>
+    #define TYPER r_8
+  #endif
+  #define REAL_PART(_x_) (TYPE((_x_).real(),0.))
+  #define CONJ_VAL(_x_) (TYPE((_x_).real(),-(_x_).imag()))
+  #define ABS_VAL(_x_) sqrt((double)((_x_).real()*(_x_).real() + (_x_).imag()*(_x_).imag()))
+#else
+  #if defined(PRECIS32)
+    #define TYPE r_4
+    #define TYPER r_4
+  #else
+    #define TYPE r_8
+    #define TYPER r_8
+  #endif
+  #define REAL_PART(_x_) (_x_)
+  #define CONJ_VAL(_x_) (_x_)
+  #define ABS_VAL(_x_) fabs((double)_x_)
+#endif
+
+//////////////////////////////////////////////////
+void Symetrize(TMatrix< TYPE >& A);
+void Hermitian(TMatrix< TYPE >& A);
+r_8  Check_Mat_Ident(TMatrix< TYPE >& A);
+r_8  Check_Mat_Zero(TMatrix< TYPE >& A);
+r_8  Check_Mat_VecCol_0(TMatrix< TYPE >& A);
+void  Check_Mat_VecCol_2(TMatrix< complex<TYPER> >& A);
+
+
+//////////////////////////////////////////////////
+int main(int narg,char *arg[])
+{
+//--------------------------------------------------------
+//-- Initialisation
+//--------------------------------------------------------
+// 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 = 100.;
+// Nombre de lignes de matrice a imprimer
+uint_4 nprline = N;
+// Initialisation du pauvre de l'aleatoire
+uint_4 nalea = 0;
+// data scaling for gauss pivoting and determinant
+int tscal = 1;
+bool detok=false;
+// Please symetrize the input matrice
+bool symetok=false;
+// Please symetrize the input matrice
+bool gaussok=false;
+
+//--------------------------------------------------------
+//-- Decodage arguments
+//--------------------------------------------------------
+char c;
+while((c = getopt(narg,arg,"Sdgn:s:b:l:a:t:h")) != -1) {
+  switch (c) {
+  case 'S' :
+    symetok = true;
+    break;
+  case 'd' :
+    detok = true;
+    break;
+  case 'g' :
+    gaussok = true;
+    break;
+  case 'n' :
+    sscanf(optarg,"%d",&N);
+    break;
+  case 's' :
+    sscanf(optarg,"%lf",&scale);
+    break;
+  case 'b' :
+    sscanf(optarg,"%d,%lf",&nbig,&vbig);
+    break;
+  case 'l' :
+    sscanf(optarg,"%d",&nprline);
+    break;
+  case 'a' :
+    sscanf(optarg,"%d",&nalea);
+    break;
+  case 't' :
+    sscanf(optarg,"%d",&tscal);
+    break;
+  case 'h' :
+    cout<<"tsttminv [-h] [-n N] [-S] [-s scale] [-b nbig,vbig] [-g]"<<endl
+        <<"         [-l nprline] [-a nalea] [-t tscal] [-d]"<<endl
+        <<"-- matrix A(N,N) filled with {[-1,1] +/- vbig(nbig time)}*scale --"<<endl
+	<<"-g : instead of flat [-1,1] use normal gaussian distribution for A(i,j)"<<endl
+	<<"-S : symetrize the input matrix"<<endl
+	<<"-l : print nprline of input and test matrices"<<endl
+	<<"-a : for random (pseudo) changing"<<endl
+        <<"-- Only GausPiv --"<<endl
+	<<"-t 0/1/2 : data scaling 0=no, 1=global (def), 2=row-by-row"<<endl
+	<<"-d : also compute determinant (ne pas utiliser si N est grand)"<<endl;
+    return(-1);
+  }
+}
+if(N<=1) N = 1;
+cout<<"Taille matrice NxN, N = "<<N<<endl;
+if(gaussok) cout<<"Elements gaussian normal * scale = "<<scale<<endl;
+  else      cout<<"Elements entre +/- 1 * scale = "<<scale<<endl;
+cout<<"Nombre de valeurs hors standard nbig = "<<nbig<<endl;
+cout<<"Valeurs hors standard (+/- vbig = "<<vbig<<" ) * scale = "<<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<<endl;
+if(symetok) cout<<"Input matrix has been symetrized "<<symetok<<endl;
+cout<<endl;
+
+//--------------------------------------------------------
+//-- Initialization arrays
+//--------------------------------------------------------
+SophyaInit();
+InitTim();
+#if defined(USE_LAPACK)
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+#endif
+if(nalea>0) for(int i=0;i<nalea;i++) drand01();
+BaseArray::SetMaxPrint(nprline*N,0);
+
+//--------------------------------------------------------
+//-- Definition global arrays
+//--------------------------------------------------------
+TMatrix< TYPE > Ainput(N,N); Ainput = (TYPE) 0;
+TMatrix< TYPE > A(N,N); A = (TYPE) 0;
+Ainput.Show();
+
+//--------------------------------------------------------
+//-- Fill matrices with flat random
+//--------------------------------------------------------
+if(gaussok) Ainput = RandomSequence(RandomSequence::Gaussian,0.,1.);
+  else      Ainput = RandomSequence(RandomSequence::Flat,0.,1.);
+#if defined(COMPLEX)
+if(gaussok) A = RandomSequence(RandomSequence::Gaussian,0.,1.);
+  else      A = RandomSequence(RandomSequence::Flat,0.,1.);
+Ainput += TYPE(0.,1.)*A;
+#endif
+
+//--------------------------------------------------------
+//-- Fill matrices with big values
+//--------------------------------------------------------
+if(nbig>0) {
+#if defined(COMPLEX)
+  nbig = (nbig+1)/2;
+#endif
+  TMatrix< uint_2 > Vind(N,N); Vind = 0;
+  // for real part
+  uint_4 nbr=0;
+  for(int k=0;k<nbig;k++) {
+    int i = (int) (drand01()*N); int j = (int) (drand01()*N);
+    double s=(drand01()>0.5)?1.:-1.;
+    if(Vind(i,j)==0) {Ainput(i,j) += (TYPER) s*vbig; Vind(i,j)+=1; nbr++;}
+  }
+  cout<<"Nombre de valeurs BIG reelles = "<<nbr<<endl;
+#if defined(COMPLEX)
+  // for imaginary part
+  uint_4 nbi=0;
+  for(int k=0;k<nbig;k++) {
+    int i = (int) (drand01()*N); int j = (int) (drand01()*N);
+    double s=(drand01()>0.5)?1.:-1.;
+    if(Vind(i,j)<=1) {Ainput(i,j) += TYPE(0.,(TYPER)s*vbig); Vind(i,j)+=2; nbi++;}
+  }
+  cout<<"Nombre de valeurs BIG imaginaires = "<<nbi<<endl;
+  cout<<"Nombre de valeurs BIG = "<<nbr+nbi<<endl;
+#endif
+}
+
+//--------------------------------------------------------
+//-- Scale matrix for machine precision tests
+//--------------------------------------------------------
+Ainput *= (TYPE) scale;
+
+//--------------------------------------------------------
+//-- Create symetric matrix for all A if requested
+//--------------------------------------------------------
+if(symetok) Symetrize(Ainput);
+
+//--------------------------------------------------------
+//-- Print matrice Ainput
+//--------------------------------------------------------
+cout<<"------------ TMatrix Ainput :"<<endl;
+if(nprline>0) {cout<<Ainput; cout<<endl;}
+PrtTim("--- End of Matrix filling ---");
+
+
+//////////////////////////////////////////////
+///////// Test Inversion avec Lapack /////////
+//////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_INV)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Inversion LAPACK (LU factorization)"<<endl;
+A = Ainput;
+//-- Inversion
+TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N);
+int_4 info = LapackLinSolve(A,InvA);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackLinSolve Inversion ---");
+//-- AiA = A * InvA
+cout<<"Compute AiA = A * InvA"<<endl;
+TMatrix< TYPE > AiA(N,N); AiA = Ainput * InvA;
+if(nprline>0) {cout<<AiA; cout<<endl;}
+//-- Check
+Check_Mat_Ident(AiA);
+PrtTim("--- End of LapackLinSolve Test ---");
+}
+#endif
+
+
+//////////////////////////////////////////////////
+///////// Test Inversion avec Lapack sym /////////
+//////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_INV_SYM)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Inversion LAPACK symetric (LU factorization)"<<endl;
+TMatrix< TYPE > Asym(N,N); Asym=Ainput; Symetrize(Asym); A=Asym;
+//-- Inversion
+TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N);
+int_4 info = LapackLinSolveSym(A,InvA);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackLinSolveSym Inversion ---");
+//-- AiA = A * InvA
+cout<<"Compute AiA = A * InvA"<<endl;
+TMatrix< TYPE > AiA(N,N); AiA = Asym * InvA;
+cout<<"------------ TMatrix AiA = A * InvA:"<<endl;
+if(nprline>0) {cout<<AiA; cout<<endl;} 
+//-- Check
+Check_Mat_Ident(AiA);
+PrtTim("--- End of LapackLinSolveSym Test ---");
+}
+#endif
+
+
+////////////////////////////////////////////////
+///////// Test avec Lapack LeastSquare /////////
+////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_INV_LSS)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Inversion LAPACK LeastSquare (QR or LQ factorization)"<<endl;
+A = Ainput;
+//-- Inversion
+TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N);
+int_4 info = LapackLeastSquareSolve(A,InvA);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackLeastSquareSolve Inversion ---");
+//-- AiA = A * InvA
+cout<<"Compute AiA = A * InvA"<<endl;
+TMatrix< TYPE > AiA(N,N); AiA = Ainput * InvA;
+if(nprline>0) {cout<<AiA; cout<<endl;} 
+//-- Check
+Check_Mat_Ident(AiA);
+PrtTim("--- End of LapackLeastSquareSolve Test ---");
+}
+#endif
+
+
+///////////////////////////////////////////////////////
+///////// Test avec Lapack LeastSquare by SVD /////////
+///////////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_INV_LSS_SVD)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Inversion LAPACK LeastSquare (SVD decomposition)"<<endl;
+A = Ainput;
+//-- Inversion
+TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N);
+TVector<r_8> S;
+int_4 rank;
+r_8 rcond = -1.;
+int_4 info = LapackLeastSquareSolveSVD_DC(A,InvA,S,rank,rcond);
+cout<<"info="<<info<<"  (rank="<<rank<<")"<<endl;
+PrtTim("--- End of LapackLeastSquareSolveSVD_DC Inversion ---");
+if(nprline>0) {cout<<S; cout<<endl;}
+double smax = fabs(S(0)), smin = fabs(S(S.Size()-1));
+cout<<" Smin = |"<<S(S.Size()-1)<<"| = "<<smin<<", "
+    <<" Smax = |"<<S(0)<<"| = "<<smax<<", "
+    <<" --> Smin/Smax = "<<smin/smax<<endl;
+//-- AiA = A * InvA
+cout<<"Compute AiA = A * InvA"<<endl;
+TMatrix< TYPE > AiA(N,N); AiA = Ainput * InvA;
+if(nprline>0) {cout<<AiA; cout<<endl;} 
+//-- Check
+Check_Mat_Ident(AiA);
+PrtTim("--- End of LapackLeastSquareSolveSVD_DC Test ---");
+}
+#endif
+
+
+////////////////////////////////////////////////
+///////// Test avec Lapack pour EV /////////
+////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_EV)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Eigen decompositon LapackEigen "<<endl;
+A=Ainput;
+TMatrix< TYPE > Evec;
+TVector< complex<r_8> > Eval;
+//-- Decompositon
+int_4 info = LapackEigen(A,Eval,Evec,true);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackEigen decompositon ---");
+if(nprline>0) {cout<<Eval; cout<<endl; cout<<Evec; cout<<endl;}
+//-- Find the complex conjugate pairs
+#if !defined(COMPLEX)
+TVector< uint_2 > Evalconj(N); Evalconj = 0;
+int_4 nconj=0;
+for(int i=0;i<N-1;i++) {
+  if(Evalconj(i)!=0) continue;   // deja traite
+  if(Eval(i).imag()==0.) continue; // real eigenvalue
+  if(fabs(Eval(i).imag()+Eval(i+1).imag())>1e-150) continue; // les 2 consecutives ne sont pas conjuguees
+  if(Eval(i).imag()<0.) continue; // first conjugate have positive imaginary part
+  if(Eval(i+1).imag()>0.) continue;
+  Evalconj(i) = 1; Evalconj(i+1) = 2; nconj++;
+}
+//cout<<Evalconj<<endl;
+cout<<"Number of conjugate eigen values: "<<nconj<<" *2 = "<<2*nconj<<" / "<<N<<endl;
+#endif
+//-- Azmlz = A*z(l) - l*z(l)
+cout<<"Compute Azmlz(l) = A*z(l) - l*z(l)"<<endl;
+TMatrix< complex<TYPER> > Azmlz(N,N); Azmlz = (complex<TYPER>) 0;
+for(int l=0;l<N;l++) { // eigen value
+  complex<TYPER> Eval_l = complex<TYPER>(Eval(l).real(),Eval(l).imag());
+  for(int i=0;i<N;i++) {
+    complex<TYPER> Evec_il;
+    #if defined(COMPLEX)
+    Evec_il = Evec(i,l);
+    #else
+    Evec_il = complex<TYPER>(Evec(i,l),0.);
+    if(Evalconj(l)==1)        Evec_il = complex<TYPER>(Evec(i,l),Evec(i,l+1));
+      else if(Evalconj(l)==2) Evec_il = complex<TYPER>(Evec(i,l-1),-Evec(i,l));
+    #endif
+    for(int j=0;j<N;j++) {
+      complex<TYPER> Evec_jl;
+      #if defined(COMPLEX)
+      Evec_jl = Evec(j,l);
+      #else
+      Evec_jl = complex<TYPER>(Evec(j,l),0.);
+      if(Evalconj(l)==1)        Evec_jl = complex<TYPER>(Evec(j,l),Evec(j,l+1));
+        else if(Evalconj(l)==2) Evec_jl = complex<TYPER>(Evec(j,l-1),-Evec(j,l));
+      #endif
+      Azmlz(i,l) += Ainput(i,j) * Evec_jl;
+    }
+    Azmlz(i,l) -= Eval_l*Evec_il;
+  }
+}
+if(nprline>0) {cout<<Azmlz; cout<<endl;} 
+//-- Check
+Check_Mat_VecCol_2(Azmlz);
+PrtTim("--- End of LapackEigen Test ---");
+}
+#endif
+
+
+////////////////////////////////////////////////
+///////// Test avec Lapack sym pour EV /////////
+////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_EV_SYM)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ Eigen decompositon LapackEigenSym "<<endl;
+TMatrix< TYPE > Aher(N,N); Aher=Ainput; Hermitian(Aher); A=Aher;
+TVector<r_8> Eval;
+//-- Decompositon
+int_4 info = LapackEigenSym(A,Eval,true);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackEigenSym decompositon ---");
+if(nprline>0) {cout<<Eval; cout<<endl; cout<<A; cout<<endl;} 
+//-- Azmlz = A*z(l) - l*z(l)
+// le vecteur propre z pour la l-ieme valeur propre est dans A(.,l):
+//    z_i = A(i,l)  ou "l" est la l-ieme valeur propre
+cout<<"Compute Azmlz(l) = A*z(l) - l*z(l)"<<endl;
+TMatrix< TYPE > Azmlz(N,N); Azmlz = (TYPE) 0;
+for(int l=0;l<N;l++)  // eigen value
+  for(int i=0;i<N;i++)
+    {for(int j=0;j<N;j++) Azmlz(i,l)+=Aher(i,j)*A(j,l); Azmlz(i,l)-=(TYPER)Eval(l)*A(i,l);}
+if(nprline>0) {cout<<Azmlz; cout<<endl;} 
+//-- Check
+Check_Mat_VecCol_0(Azmlz);
+PrtTim("--- End of LapackEigenSym Test ---");
+}
+#endif
+
+
+////////////////////////////////////////////////
+///////////// Test avec Lapack SVD /////////////
+////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_SVD)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ SVD decompositon LapackSVD "<<endl;
+A=Ainput;
+TVector< TYPE > S; TMatrix< TYPE > U; TMatrix< TYPE > VT; 
+//-- Decompositon
+int_4 info = LapackSVD(A,S,U,VT);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackSVD decompositon ---");
+if(nprline>0) {cout<<S; cout<<endl;}
+double smax = ABS_VAL(S(0)), smin = ABS_VAL(S(N-1));
+cout<<" Smin = |"<<S(N-1)<<"| = "<<smin<<", "
+    <<" Smax = |"<<S(0)<<"| = "<<smax<<", "
+    <<" --> Smin/Smax = "<<smin/smax<<endl;
+//-- A = U*S*VT
+cout<<"Compute A = U*S*VT"<<endl;
+TMatrix< TYPE > AmUSVt(N,N); AmUSVt = U;
+for(int i=0;i<N;i++) for(int j=0;j<N;j++) AmUSVt(i,j) *= S(j);
+AmUSVt = AmUSVt * VT; AmUSVt -= Ainput;
+if(nprline>0) {cout<<AmUSVt; cout<<endl;} 
+//-- Check
+Check_Mat_Zero(AmUSVt);
+PrtTim("--- End of LapackSVD Test ---");
+}
+#endif
+
+
+///////////////////////////////////////////////////
+///////////// Test avec Lapack SVD_DC /////////////
+///////////////////////////////////////////////////
+#if defined(USE_LAPACK) && defined(ALSO_LAPACK_SVD_DC)
+{
+cout<<"\n=========================================="<<endl;
+cout<<"------------ SVD decompositon LapackSVD_DC "<<endl;
+A=Ainput;
+TVector< r_8 > S; TMatrix< TYPE > U; TMatrix< TYPE > VT; 
+//-- Decompositon
+int_4 info = LapackSVD_DC(A,S,U,VT);
+cout<<"info="<<info<<endl;
+PrtTim("--- End of LapackSVD_DC decompositon ---");
+if(nprline>0) {cout<<S; cout<<endl;}
+double smax = fabs(S(0)), smin = fabs(S(N-1));
+ cout<<"CMV: "<<S(0)<<endl;
+//cout<<" Smin = |"<<S(N-1)<<"| = "<<smin<<", "
+//    <<" Smax = |"<<S(0)<<"| = "<<smax<<", "
+//    <<" --> Smin/Smax = "<<smin/smax<<endl;
+//-- A = U*S*VT
+cout<<"Compute A = U*S*VT"<<endl;
+TMatrix< TYPE > AmUSVt(N,N); AmUSVt = U;
+for(int i=0;i<N;i++) for(int j=0;j<N;j++) AmUSVt(i,j) *= (TYPE) S(j);
+AmUSVt = AmUSVt * VT; AmUSVt -= Ainput;
+if(nprline>0) {cout<<AmUSVt; cout<<endl;} 
+//-- Check
+Check_Mat_Zero(AmUSVt);
+PrtTim("--- End of LapackSVD_DC Test ---");
+}
+#endif
+
+
+///////////////////////////////////////////////
+///////// Test Inversion avec GausPiv /////////
+///////////////////////////////////////////////
+#if defined(USE_GAUSPIV)
+{
+cout<<"\n==========================================\n"
+    <<"------------ Inversion GausPiv"<<endl;
+SimpleMatrixOperation< TYPE >::SetGausPivScal(tscal);
+A = Ainput;
+//-- Inversion
+TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N);
+TYPE det = GausPiv(A,InvA,detok);
+PrtTim("--- End of GausPiv Inversion ---");
+cout<<"Det = "<<det<<endl;
+cout<<"------------ TMatrix InvA = A^(-1):"<<endl;
+//-- AiA = A * InvA
+cout<<"Compute AiA = A * InvA"<<endl;
+TMatrix< TYPE > AiA(N,N); AiA = Ainput * InvA;
+cout<<"------------ TMatrix AiA = A * InvA:"<<endl;
+if(nprline>0) {cout<<AiA; cout<<endl;}
+//-- Check
+Check_Mat_Ident(AiA);
+PrtTim("--- End of GausPiv Test ---");
+}
+#endif
+
+
+PrtTim("--- End of Job ---");
+exit(0);
+}
+
+
+
+////////////////////////////////////////////////////////////
+////-------------------------------------------------------
+void Symetrize(TMatrix< TYPE >& A)
+// Symetrize A
+{
+ int_4 N = A.NRows();
+ for(int i=0;i<N-1;i++) for(int j=i+1;j<N;j++) A(j,i) = A(i,j);
+}
+
+////-------------------------------------------------------
+void Hermitian(TMatrix< TYPE >& A)
+// Put A hermitian
+{
+ int_4 N = A.NRows();
+ for(int i=0;i<N-1;i++) for(int j=i+1;j<N;j++) A(j,i) = CONJ_VAL(A(i,j));
+ for(int i=0;i<N;i++) A(i,i) = REAL_PART(A(i,i));
+}
+
+////-------------------------------------------------------
+r_8  Check_Mat_Ident(TMatrix< TYPE >& A)
+// Compute the biggest difference element by element of A / Identity
+{
+ int_4 N = A.NRows();
+ r_8 vmaxd=-1.;
+ for(int i=0;i<N;i++)
+   if( ABS_VAL((TYPER)1.-A(i,i)) > vmaxd ) vmaxd = ABS_VAL((TYPER)1.-A(i,i));
+ cout<<"Ecart maximum par rapport a 1 sur diagonale = "<<vmaxd<<endl;
+ r_8 vmaxh = -1.;
+ for(int i=0;i<N;i++) for(int j=0;j<N;j++) {
+   if(i==j) continue;
+   if( ABS_VAL(A(i,j)) > vmaxh ) vmaxh = ABS_VAL(A(i,j));
+ }
+ cout<<"Ecart maximum par rapport a 0 hors diagonale = "<<vmaxh<<endl;
+ return (vmaxd>vmaxh)? vmaxd: vmaxh;
+}
+
+////-------------------------------------------------------
+r_8  Check_Mat_Zero(TMatrix< TYPE >& A)
+// Compute the biggest difference element by element of A / Zero matrix
+{
+ int_4 N = A.NRows();
+ r_8 vmax = -1.;
+ for(int i=0;i<N;i++) for(int j=0;j<N;j++)
+   if( ABS_VAL(A(i,j)) > vmax ) vmax = ABS_VAL(A(i,j));
+ cout<<"Ecart maximum par rapport a zero = "<<vmax<<endl;
+ return vmax;
+}
+
+////-------------------------------------------------------
+r_8  Check_Mat_VecCol_0(TMatrix< TYPE >& A)
+// Return the biggest norm of the N vectors column of matrix
+{
+ int_4 N = A.NRows();
+ r_8 vmax=-1.;
+ for(int l=0;l<N;l++) {
+   r_8 absv = 0.;
+   for(int i=0;i<N;i++) absv += ABS_VAL(A(i,l)) * ABS_VAL(A(i,l));
+   if( absv > vmax ) vmax = absv;
+ }
+ vmax = sqrt(vmax);
+ cout<<"Longueur max de ||A*z-l*z|| pour tous l = "<<vmax<<endl;
+ return vmax;
+}
+
+////-------------------------------------------------------
+void  Check_Mat_VecCol_2(TMatrix< complex<TYPER> >& A)
+// Return the biggest norm of :
+//   - the real part of the N vectors column of matrix
+//   - the imaginary part of the N vectors column of matrix
+//   - the module of the N vectors column of matrix
+{
+ int_4 N = A.NRows();
+ r_8 vmaxr=-1., vmaxi=-1., vmaxn=-1.;
+ for(int l=0;l<N;l++) {
+   double absvr = 0., absvi = 0., absvn = 0.;
+   for(int i=0;i<N;i++) {
+     absvr += A(i,l).real()*A(i,l).real();
+     absvi += A(i,l).imag()*A(i,l).imag();
+     absvn += A(i,l).real()*A(i,l).real() + A(i,l).imag()*A(i,l).imag();
+   }
+   if( absvr > vmaxr ) vmaxr = absvr;
+   if( absvi > vmaxi ) vmaxi = absvi;
+   if( absvn > vmaxn ) vmaxn = absvn;
+ }
+ vmaxr=sqrt(vmaxr); vmaxi=sqrt(vmaxi); vmaxn=sqrt(vmaxn);
+ cout<<"Longueur max de ||A*z-l*z|| pour tous l, reel = "<<vmaxr
+     <<", imag = "<<vmaxi<<", module = "<<vmaxn<<endl;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/tsttvec.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tsttvec.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tsttvec.cc	(revision 3445)
@@ -0,0 +1,115 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <iostream>
+#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_Nov2007/SophyaProg/Tests/tswfits.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/tswfits.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/tswfits.cc	(revision 3445)
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+
+#include "sopnamsp.h"
+#include "histinit.h"
+#include "dvlist.h"
+#include "fitsswapper.h"
+#include "fiosinit.h"
+#include "swfitsdtable.h"
+
+#include "datatable.h"
+#include "fitshdtable.h"
+
+void test_fdtable() ; 
+static long NROW = 64;
+static long NPRT = 10;
+
+int main(int narg, char *arg[])
+{
+  SophyaInit();
+  FitsIOServerInit();
+  if (narg < 3) {
+    cout << "Erreur arg/Usage: tswfits NRowTable NPRT" << endl;
+    return 1;
+  }
+  NROW = atoi(arg[1]);
+  NPRT = atoi(arg[2]);
+  try {
+    test_fdtable();
+  }
+  catch(PThrowable exc ) {
+    cerr << "tswfits-main() , Catched exception: \n" << exc.Msg() << endl;
+  }
+  catch(std::exception ex) {
+    cerr << "tswfits-main() , Catched exception ! " << (string)(ex.what()) << endl;
+  }
+  catch(...) {
+    cerr << "tswfits-main() , Catched ... ! " << endl;
+  }
+  
+}
+
+
+void test_fdtable() 
+{
+  cout << "======= test_fdtable:  simple SwapOnFits test ======= " << endl;
+    int SWSEGSZ = 4;
+    vector<int_8> tags;
+    {
+      cout << "1/ Creation FITSDataSwapper<double> swout(so) avec swseg.fits " << endl;
+      vector<string> ttype, tform, tunit;
+      ttype.push_back("D-Col1");
+      tform.push_back("D");
+      tunit.push_back("");
+      //      ttype.push_back("I-Col2");
+      //      tform.push_back("J");
+      //      tunit.push_back("");
+      string tblnm = "SwapMyExt";
+      FitsInOutFile fiosc("!swseg.fits", FitsInOutFile::Fits_Create);
+      //      fiosc.MoveAbsToHDU(2);
+      cout << " DBG-Appel CreateTable ... " << endl;
+      fiosc.CreateTable(BINARY_TBL, "rzbintbl", ttype, tform, tunit);
+      cout << " ---- Appel a FITSDataSwapper<double> --- " << endl;
+      FITSDataSwapper<double> swout(fiosc, 1);
+      SwSegDataBlock<double> swsd(swout, SWSEGSZ, 3);
+      //      FITSDataSwapper<int_4> swout(&fiosc, 1);
+      //      SwSegDataBlock<int_4> swsd(swout, SWSEGSZ, 3);
+      double * fp = swsd.GetSegment(0);
+      fp[0] = 6.54321;   fp[1] = 65.4321;  fp[2] = 654.321;  fp[3] = 6543.21;
+      fp = swsd.GetSegment(1);
+      fp[0] = 2.56789;   fp[1] = 25.6789;  fp[2] = 256.789;  fp[3] = 2567.89;
+      fp = swsd.GetSegment(2);
+      fp[0] = 12.567;   fp[1] = 225.67;  fp[2] = 3256.7;  fp[3] = 42567.;
+      tags = swsd.GetSwapPosTagTable();
+      cout << " Les pos-tags du FITS NbTag=" << tags.size() << endl;
+      for (int kk=0; kk<tags.size(); kk++)  cout << tags[kk] << " ," ;
+      cout << endl;
+    }
+    {
+      cout << "2/ Creation FITSDataSwapper<double> avec lecture depuis swseg.fits" << endl;
+      FitsInOutFile si("swseg.fits", FitsInOutFile::Fits_RO);
+      si.MoveAbsToHDU(2);
+      FITSDataSwapper<double> swin(si, 1);
+      SwSegDataBlock<double> swsd(swin, tags, SWSEGSZ);
+      cout <<"2.b/ Recopie ds SegDataBlock<double> depuis SwSegDataBlock<double> et print" << endl;
+      SegDataBlock<double> segd;
+      segd = swsd;
+      segd.Print(cout, 4, "  ");
+    }
+
+    {
+      cout << " ------------------------------------------------ " << endl;
+      cout << "3/ Creation SwFitsDataTable sur myswtable.fits " << endl;
+      FitsInOutFile so("!myswtable.fits", FitsInOutFile::Fits_Create);
+      SwFitsDataTable dt(so, 45);
+      // define table columns
+      dt.AddFloatColumn("X0_f");
+      dt.AddFloatColumn("X1_f");
+      dt.AddDoubleColumn("X0X0pX1X1_d");
+      cout << "3.b/ start fill " << endl;
+      // Fill the table
+      r_8 x[5];
+      int pmod = NROW/50;
+      if (pmod < 10) pmod = 10;
+      for(int i=0; i<NROW; i++) {
+	//	if (i%pmod == 0)  cout << " DBG - i= " << i << endl;
+	x[0] = (i%9)-4.;  x[1] = (i/9)-3.;  x[2] = x[0]*x[0]+x[1]*x[1];
+	dt.AddLine(x);
+      }
+      cout << "3.c/ End fill " << endl;
+      
+      // Printing table info
+      cout << dt ;
+      for(int k = 0; k<NPRT; k++) 
+	cout << "Line[" << k << "] " << dt.LineToString(k) << endl ; 
+     
+    }
+    {
+      cout << " ------------------------------------------------ " << endl;
+      cout << "4/ Lecture SwFitsDataTable depuis myswtable.fits " << endl;
+      FitsInOutFile si("myswtable.fits", FitsInOutFile::Fits_RO);
+      si.SkipEmptyFirstHDU();
+      SwFitsDataTable dt(si,40,false);
+      //      si >> dt;
+      // Printing table info
+      cout << dt ;
+      for(int k = 0; k<NPRT; k++) 
+	cout << "Line[" << k << "] " << dt.LineToString(k) << endl ; 
+    }
+
+  cout << "============ FIN  test_fdtable ======== ======= " << endl;  
+}
+
+
+
+
Index: /tags/V_Nov2007/SophyaProg/Tests/ttimestamp.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/ttimestamp.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/ttimestamp.cc	(revision 3445)
@@ -0,0 +1,142 @@
+#include "sopnamsp.h"
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <typeinfo>
+#include "timing.h"
+#include "timestamp.h"
+#include "histinit.h"
+#include "pexceptions.h"
+#include "ppfwrapstlv.h" 
+
+/*  Programme test de la classe TimeStamp             */
+/*  SOPHYA - R. Ansari (LAL)  -   Mars 2005           */
+
+int main(int narg, char* arg[])
+{
+  cout << " ---- Programme ttimestamp.cc - Test classe TimeStamp --- " << endl;
+  int rc = 0;
+  try {
+      SophyaInit();
+//    PPRegister(FIO_SphereECP<r_8>);
+//    DObjRegister(FIO_SphereECP<r_8>, SphereECP<r_8>);
+    
+    InitTim(); 
+    cout << " Sizeof(TimeStamp=) " << sizeof(TimeStamp) << endl;
+    TimeStamp ts; 
+    cout << "ts: Now : " << ts << "(->double: " << (double)ts << " )" << endl; 
+    TimeStamp ts2("26/8/1974","14:22:35.65"); 
+    cout << "ts2: 26/8/1974 14:22:35.65 : " << ts2  
+	 << " double->TimeStamp: " << TimeStamp(ts2.ToDays()) << endl; 
+    TimeStamp ts3("08/05/1905","00:00:00"); 
+    cout << "ts3: 8/05/1905 , 00:00:00 : " << ts3 << " (double): " 
+	 << (double)ts3 << " double->TimeStamp: " << TimeStamp(ts3.ToDays()) << endl; 
+    TimeStamp ts4("01/01/1901","03:00:20"); 
+    cout << "ts3: 01/01/1901 , 03:00:20 : " << ts4 << " (double): " 
+	 << (double)ts4 << " double->TimeStamp: " << TimeStamp(ts4.ToDays()) << endl; 
+
+    TimeStamp ts5("01/12/1899","00:00:00"); 
+    cout << "ts5: 01/12/1899 , 00:00:00 : " << ts5 << " (double): " 
+	 << (double)ts5 << " double->TimeStamp: " << TimeStamp(ts5.ToDays()) << endl; 
+    TimeStamp ts6("01/12/1899","15:30:00"); 
+    cout << "ts6: 01/12/1899 , 15:30:00 : " << ts6 << " (double): " 
+	 << (double)ts6 << " double->TimeStamp: " << TimeStamp(ts6.ToDays()) << endl; 
+
+    cout << " ts.ToString(bool, bool) test : " << endl;
+    cout << " ts.ToString()= " << ts.ToString() << endl;
+    cout << " ts.ToString(FmtDateOnly)= " << ts.ToString(TimeStamp::FmtDateOnly) << endl;
+    cout << " ts.ToString(FmtTimeOnly)= " << ts.ToString(TimeStamp::FmtTimeOnly) << endl;
+    cout << " ts.ToString(FmtDateTime)= " << ts.ToString(TimeStamp::FmtDateTime) << endl;
+
+    TimeStamp ts12("1974-08-26T14:22:35.65"); 
+    cout << "ts12: 1974-08-26T14:22:35.65 : " << ts12  
+	 << " double->TimeStamp: " << TimeStamp(ts12.ToDays()) << endl; 
+    TimeStamp ts13("1905-05-08T00:00:00"); 
+    cout << "ts13: 1905-05-08T00:00:00  " << ts13 << " (double): " 
+	 << (double)ts13 << " double->TimeStamp: " << TimeStamp(ts13.ToDays()) << endl; 
+
+    double diff;
+    diff = ts12.ToDays()-ts2.ToDays();
+    if (fabs(diff) > 1.e-6) {
+      cout << "ttimestamp/Erreur Diff t12-t2 : Rc+=1 " << endl;
+      rc += 1;
+    }
+    diff = ts13.ToDays()-ts3.ToDays();
+    if (fabs(diff) > 1.e-6) {
+      cout << "ttimestamp/Erreur Diff t13-t3 : Rc+=2 " << endl;
+      rc += 2;
+    }
+    TimeStamp tsa("1901-1-1T14:0:0"); 
+    diff = tsa.ToDays()-38./24.;
+    if (fabs(diff) > 1.e-6) {
+      cout << "ttimestamp/Erreur Diff tsa-38/24. : Rc+=4 " << endl;
+      rc += 4;
+    }
+    tsa.Set("1901-02-07T18:00:00");
+    diff = tsa.ToDays()-38.75;
+    if (fabs(diff) > 1.e-6) {
+      cout << "ttimestamp/Erreur Diff tsa-38.75 : Rc+=8 " << endl;
+      rc += 8;
+    }
+    tsa.Set("2004-08-24T18:00:00");
+    TimeStamp tsb("2004-09-03T21:00:00");
+    diff = tsb.ToDays()-tsa.ToDays();
+    if (fabs(diff-10.125) > 1.e-6) {
+      cout << "ttimestamp/Erreur Diff tsb-tsa : Rc+=16 " << endl;
+      rc += 16;
+    }
+    if (rc == 0)
+      cout << "ttimestamp/Info CheckDiffs OK (Rc=" << rc << ")" << endl;
+    else 
+      cout << "ttimestamp/Erreur Pb Diffs  (Rc=" << rc << ")" << endl;
+
+    cout << "ttimestamp/Info: Test PPF , vector<TimeStamp> " << endl;
+    vector<TimeStamp> vts, vtsr;
+    vts.push_back(ts);
+    vts.push_back(ts2);
+    vts.push_back(ts3);
+    {
+      POutPersist so("tts.ppf");
+      so << vts;
+    }
+    cout << "ttimestamp/Info: Reading from tts.ppf " << endl;
+    PInPersist si("tts.ppf");
+    
+    si >> vtsr;
+    for(int kk=0; kk<vtsr.size(); kk++) {
+      cout << " vtsr[" << kk << "] : " << vtsr[kk] << endl;
+      diff = vtsr[kk].ToDays()-vts[kk].ToDays();
+      if (fabs(diff) > 1.e-6) {
+	cout << "ttimestamp/Erreur Diff   vtsr[kk]-vts[kk] : Rc+=32 " << endl;
+	rc += 32;
+      }
+    }
+    if (rc >= 32) 
+      cout << "ttimestamp/Info Pb Diffs vector<TimeStamp>/PPF (Rc=" 
+	   << rc << ")" << endl;
+    else 
+      cout << "ttimestamp/Erreur  Diffs vector<TimeStamp>/PPF OK" << endl; 
+  }
+  catch (PThrowable & exc) {
+    cerr << " ttimestamp.cc: Catched Exception (PThrowable)" << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+    rc = 99;
+  }
+  catch (std::exception & e) {
+    cerr << " ttimestamp.cc: Catched std::xception "  
+	 << " - what()= " << e.what() << endl;
+    rc = 98;
+  }
+  catch (...) {
+    cerr << " ttimestamp.cc: some other exception (...) was caught ! " << endl;
+    rc = 97;
+  }
+  PrtTim("End ttimestamp " );
+  cout << " ---- Programme ttimestamp.cc-  FIN  (Rc=" << rc << ") --- " << endl;
+  return rc;
+}
Index: /tags/V_Nov2007/SophyaProg/Tests/usedslibs
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/usedslibs	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/usedslibs	(revision 3445)
@@ -0,0 +1,3 @@
+PI
+sophya
+extsophya
Index: /tags/V_Nov2007/SophyaProg/Tests/zthr.cc
===================================================================
--- /tags/V_Nov2007/SophyaProg/Tests/zthr.cc	(revision 3445)
+++ /tags/V_Nov2007/SophyaProg/Tests/zthr.cc	(revision 3445)
@@ -0,0 +1,495 @@
+#include "sopnamsp.h"
+#include "zthread.h"
+#include "resusage.h"
+
+#include <iostream>
+#include <vector>
+
+#include "tmatrix.h"
+#include "tvector.h"
+#include "matharr.h"
+#include "tarrinit.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* -------------------------------------------------
+  Programme de test des classes de threads de SOPHYA
+  SOPHYA::ZThread SOPHYA::ZMutex ...
+  Exemples d'execution
+  csh> time zthr mtx 2 500     
+  csh> time zthr arr 2 500
+  csh> time zthr arrdl 2 500
+  csh> time zthr arrmf 2 500
+  csh> time zthr sync 4 1000
+  csh> time zthr syncp 4 1000
+*/
+ 
+#include <time.h>
+#include <unistd.h>
+
+#include "timing.h"
+#include "ctimer.h"
+
+
+// --- Structure d'argument pour fonction d'execution dans les threads de test
+typedef struct  {
+  int_4 thid, NTh;
+  int_4 M, VSz;
+} ztarg;
+
+// --- fonction de test simple avec boucle de sleep
+void funzt(void *arg)
+{
+time_t t0, t1;
+int i;
+
+ztarg * za = (ztarg *)arg;
+
+t0 = time(NULL);
+printf("+++++ funzt(ThId=%d) Entry to funzt (za.M=%d) +++++\n", za->thid, za->M);
+int imax = za->M;
+for(i=0; i<imax; i++)
+  {
+  sleep(3);
+  t1 = time(NULL)-t0;
+  printf("++funzt(ThId=%d)  Dt= %d \n", za->thid, (int)t1);
+  }
+
+return;
+}
+
+// --- fonction de test simple avec calcul matriciel (produit de 2 matrices double)
+void mtx_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  cout << ">>>> mtx-funzt(ThId=" << za->thid << ") - Matrix size= " << za->M << endl;
+  
+  sa_size_t m = za->M;
+  Matrix a1(m,m), a2(m,m), mxprod; 
+  a1 = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+  a2 = RandomSequence(RandomSequence::Gaussian, 0., 3.);
+  char buff[128];
+  sprintf(buff, "mtx-funzt(ThId=%d) EndOfInit", za->thid); 
+  PrtTim(buff);
+  mxprod = a1*a2;
+  sprintf(buff, "mtx-funzt(ThId=%d) EndOfMxProd", za->thid); 
+  PrtTim(buff);
+  return;
+}
+// --- fonction de test simple avec calcul sur tableaux entier I4
+void arr_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  cout << ">>>> arr-funzt(ThId=" << za->thid << ") - Matrix size= " << za->M << endl;
+  
+  sa_size_t m = za->M;
+  TMatrix<int_4> a1(m,m), a2(m,m), ares; 
+  a1 = RegularSequence(1.,1.);
+  a2 = RegularSequence(5.,3.);
+  char buff[128];
+  sprintf(buff, "arr-funzt(ThId=%d) EndOfInit", za->thid); 
+  PrtTim(buff);
+  //  ares = 4*a1*12*a2;  correction le 23/05/2007 - * (prod.mtx par erreur)
+  ares = (4*a1)+(12*a2);
+  sprintf(buff, "arr-funzt(ThId=%d) EndOfOper", za->thid); 
+  PrtTim(buff);
+  return;
+}
+// --- fonction de test simple avec calcul de type DL sur tableaux double 1D
+void arrdl_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  sa_size_t vsz = za->M*za->M;
+  sa_size_t EXS = 10;
+
+  cout << ">>>> arrdl-funzt(ThId=" << za->thid << " DataBlock_Sz=M*M " << vsz  
+       << " V2=DLO4(V1) , NOp ~= 10*10*vsz=" << 10*EXS*vsz << endl;
+  
+  TVector<r_8> v1(vsz), v2(vsz); 
+  TVector<r_8> coeff(EXS); 
+  coeff = RandomSequence();
+  //  v1 = RegularSequence(1.,0.001);  --- ATTENTION , couteux en temps
+  //  NDataBlock<r_8> v1(vsz, false), v2(vsz, false); 
+  for(sa_size_t i=0; i<vsz; i++)   v1(i) = i*0.001; 
+  char buff[128];
+  sprintf(buff, "arrdl-funzt(ThId=%d) EndOfInit", za->thid); 
+  PrtTim(buff);
+
+  double c2 = 0.5;
+  double c3 = 1./6.;
+  double c4 = 1./24;
+  for(sa_size_t k=0; k<EXS; k++) {
+    for(sa_size_t i=0; i<vsz; i++) {
+      register double x = v1(i)*coeff(k); 
+      v2(i) = x*(1+x*(x*c2+x*(x*c3+x*x*c4)));
+    }
+  }
+  sprintf(buff, "arrdl-funzt(ThId=%d) EndOfOper", za->thid); 
+  PrtTim(buff);
+  return;
+}
+// --- fonction de test simple avec calcul de type fonction mathematique sur tableaux double 1D
+void arrmf_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  sa_size_t vsz = za->M*za->M;
+
+  cout << ">>>> arrmf-funzt(ThId=" << za->thid << " VecSz=M*M " << vsz  
+       << " V2=Sin(V1) , NOp ~= 50*vsz=" << 50*vsz << endl;
+  
+  TVector<r_8> v1(vsz), v2(vsz); 
+  //--  v1 = RegularSequence(1.,0.001);  COUTEUX en TCPU
+  for(sa_size_t i=0; i<vsz; i++)  v1(i) = i*0.001; 
+  char buff[128];
+  sprintf(buff, "arrmf-funzt(ThId=%d) EndOfInit", za->thid);
+  PrtTim(buff);
+
+  v2 = Sin(v1);
+  v2 += Cos(v1);
+  sprintf(buff, "arrmf-funzt(ThId=%d) EndOfOper", za->thid); 
+  PrtTim(buff);
+  return;
+}
+
+
+// Structure de gestion utilisee par la classe MTVecPool
+typedef struct {
+  bool busy;
+  int stat;
+} St_VecPool;
+
+// -------------------------------------------------------------------
+// Structure de gestion de zones memoire partagee (des vecteurs) entre
+// threads - qui doivent operer successivement sur les vecteurs
+// -------------------------------------------------------------------
+class MTVecPool {
+public:
+  MTVecPool(uint_4 nth, uint_4 vsz, uint_4 nvec)
+  {
+    if (nth > 60) throw ParmError("MTVecPool::MTVecPool() nth > 60");
+    if ((nth < 1) || (vsz < 2))
+	throw ParmError("MTVecPool::MTVecPool() nth<1 OR vsz<2 ");
+    _vmx.SetSize(vsz, nvec);
+    _nth = nth;
+    _vsz = vsz; 
+    TVector<int_8> xx(2);
+    for(int k=0; k<nth; k++) _vecp.push_back(xx);
+    cout << "-- MTVecPool(nth=" << nth << ")" << endl;
+    _vmx.Show();
+  }
+  ~MTVecPool()   { }
+  // Renvoie un pointeur de vecteur pour thread tid
+  TVector<int_8>*  GetVecP(uint_4 tid, uint_4& idx)
+  {
+    if (tid >= _nth) ParmError("MTVecPool::GetVecP() tid > _nth");
+    //DBG  cout << "DBG-GetVecP(tid= " << tid << ")" << endl;
+    if (tid == 0) {
+      mex.lock();
+      St_VecPool stv;
+      idx = _vecs.size();
+      _vecp[tid].Share(_vmx.Column(idx));
+      stv.busy = true;
+      stv.stat = 0;
+      _vecs.push_back(stv);
+      mex.unlock();
+      //DBG cout << "DBG-GetVecP(tid= " << tid << ") -> Idx=" << idx << " VecSz=" << &(_vecs[idx].vv) << endl;
+      return (&(_vecp[tid]));
+    }
+    else {
+      mex.lock();
+      bool found = false;
+      while (!found) {
+	for(uint_4 k=0; k<_vecs.size(); k++) {
+	  if ( (_vecs[k].stat == tid) && (! _vecs[k].busy) ) {
+	    found = true;  idx = k;
+	    _vecs[k].stat = tid; _vecs[k].busy = true; 
+	    break;
+	  }
+	}
+	if (found) {
+	  _vecp[tid].Share(_vmx.Column(idx));
+	  mex.unlock();
+	  //DBG  cout << "DBG-GetVecP(tid= " << tid << ") -> nv=" << hex << rv << dec << endl;
+	  return (&(_vecp[tid]));
+	}
+	else { 
+	  mex.broadcast();
+	  mex.wait();
+	}
+      }
+    }
+  }
+  // Renvoie un vecteur pour thread tid
+  TVector<int_8>  GetVec(uint_4 tid, uint_4& idx)
+  {
+    if (tid >= _nth) ParmError("MTVecPool::GetVec() tid > _nth");
+    //DBG  cout << "DBG-GetVec(tid= " << tid << ")" << endl;
+    if (tid == 0) {
+      mex.lock();
+      St_VecPool stv;
+      idx = _vecs.size();
+      stv.busy = true;
+      stv.stat = 0;
+      _vecs.push_back(stv);
+      mex.unlock();
+      //DBG cout << "DBG-GetVec(tid= " << tid << ") -> Idx=" << idx << " VecSz=" << &(_vecs[idx].vv) << endl;
+      return (_vmx.Column(idx));
+    }
+    else {
+      mex.lock();
+      bool found = false;
+      while (!found) {
+	for(uint_4 k=0; k<_vecs.size(); k++) {
+	  if ( (_vecs[k].stat == tid) && (! _vecs[k].busy) ) {
+	    found = true;  idx = k;
+	    _vecs[k].stat = tid; _vecs[k].busy = true; 
+	    break;
+	  }
+	}
+	if (found) {
+	  mex.unlock();
+	  //DBG  cout << "DBG-GetVec(tid= " << tid << ") -> nv=" << hex << rv << dec << endl;
+	  return (_vmx.Column(idx));
+	}
+	else { 
+	  mex.broadcast();
+	  mex.wait();
+	}
+      }
+    }
+  }
+
+  // Retourne l'index du vecteur au gestionnaire, qui le marque comme disponible
+  void RetVec(uint_4 idx)
+  {
+    //DBG cout << "DBG-RetVec(idx= " << idx << ")" << endl;
+    ZSync zs(mex, 2);
+    _vecs[idx].busy = false; _vecs[idx].stat++; 
+    zs.NOp();
+  }
+
+  // Verifie l'etat memoire de tous les vecteurs et fait des print
+  int Check()
+  {
+    cout << "MTVecPool::Check() NVec=" << _vecs.size() << " VSz=" 
+	 << _vsz << " NThreads=" << _nth << endl;
+    int nerr = 0;
+    int_8 sum = 0;
+    int_8 p2 = 1;
+    int_8 min,max;
+    for(int i=0; i<_nth; i++) { sum += p2; p2 *= 2; }
+    for(uint_4 k=0; k<_vecs.size(); k++) {
+      if ( (_vecs[k].busy) || (_vecs[k].stat != _nth) ) {
+	cout << " Check()/Pb Busy Or Stat  for k=" << k << endl;
+	nerr++;
+      }
+      _vmx.Column(k) -= sum;
+      _vmx.Column(k).MinMax(min, max);
+      if ((min!=0) || (max!=0)) {
+	cout << " Check()/Pb vec[k=" << k << "] != (sum=" << sum << ")" << endl;
+	nerr++;
+      }
+    }
+    if (nerr == 0) cout << "MTVecPool::Check()  - OK (NErr=0)" << endl;
+    else cout << "MTVecPool::Check() PB NErr=" << nerr << endl;
+    return nerr;
+  }
+
+  // ... variables membres
+  ZMutex mex;
+  uint_4 _vsz;
+  uint_4 _nth;
+  TMatrix<int_8> _vmx;
+  vector< St_VecPool> _vecs;
+  vector< TVector<int_8> > _vecp;
+};
+
+
+static MTVecPool* mtvp = NULL;
+
+// --- fonction de test avec synchronisation entre threads en utilisant pointeur de vecteurs
+void syncp_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  cout << ">>>> syncp_funzt(ThId=" << za->thid << ") - NVec/NLoop= " << za->M << endl;
+  
+  if (mtvp == NULL) 
+    throw NullPtrError("syncp_funzt: MTVecPool* mtvp = NULL");
+
+  int_4 L = za->M;
+  int_4 VS = za->VSz;
+  int_8 p2 = 1;
+  uint_4 k, ii, tid;
+  tid = za->thid;
+  for(k=0; k<tid; k++) p2 *= 2;
+
+  char buff[128];
+  sprintf(buff, "syncp_funzt(ThId=%d) StarOfLoop", za->thid); 
+  PrtTim(buff);
+  uint_4 idx;
+  for(k=0; k<L; k++) {
+    *(mtvp->GetVecP(tid, idx)) += p2;
+    //DBG cout << "DBG-syncp_funzt(tid=" << tid << ", idx=" << idx << endl;
+      mtvp->RetVec(idx);
+  }
+  sprintf(buff, "syncp_funzt(ThId=%d) EndOfLoop", za->thid); 
+  PrtTim(buff);
+  return;
+}
+// --- fonction de test avec synchronisation entre threads
+void sync_funzt(void *arg)
+{
+  ztarg * za = (ztarg *)arg;
+  cout << ">>>> sync_funzt(ThId=" << za->thid << ") - NVec/NLoop= " << za->M << endl;
+  
+  if (mtvp == NULL) 
+    throw NullPtrError("sync_funzt: MTVecPool* mtvp = NULL");
+
+  int_4 L = za->M;
+  int_4 VS = za->VSz;
+  int_8 p2 = 1;
+  uint_4 k, ii, tid;
+  tid = za->thid;
+  for(k=0; k<tid; k++) p2 *= 2;
+
+  char buff[128];
+  sprintf(buff, "sync_funzt(ThId=%d) StarOfLoop", za->thid); 
+  PrtTim(buff);
+  uint_4 idx;
+  for(k=0; k<L; k++) {
+    mtvp->GetVec(tid, idx) += p2;
+    //DBG cout << "DBG-sync_funzt(tid=" << tid << ", idx=" << idx << endl;
+    mtvp->RetVec(idx);
+  }
+  sprintf(buff, "sync_funzt(ThId=%d) EndOfLoop", za->thid); 
+  PrtTim(buff);
+  return;
+}
+
+class CountLock : public ZMutex {
+  int count;
+public:
+  CountLock() { count = 0; }
+  inline int Count() { lock(); int rc = ++count; unlock(); return(rc); 
+  }
+};
+
+
+static int N = 1;
+static int M = 5;
+static int VSZ = 32;
+
+int main(int narg, char *arg[])
+
+{
+
+  if (narg < 4) {
+    cout << " Usage: zthr select N LM [Sz] " << endl;
+    cout << "  select= sl -> simple loop with sleep " << endl;
+    cout << "  select= mtx -> matrix<r_8> init and multiply mx1*mx2" << endl;
+    cout << "  select= arr -> array/matrix<int_4> init and operation c1*a1+c2*a2 " << endl;
+    cout << "  select= arrdl -> vectorOpe V2 ~= DLO4(V1), VSz=LM*LM " << endl;
+    cout << "  select= arrmf -> vectorOpe V2 = Sin(V1), VSz=LM*LM " << endl;
+    cout << "  select= clk -> Mutex lock count  " << endl;
+    cout << "  select= sync -> Thread synchronisation using ZMutex" << endl;
+    cout << "  select= syncp -> Thread synchronisation using ZMutex , Vector pointers" << endl;
+    cout << "  N= Number of threads (sl/mtx) or CountLock " << endl;
+    cout << "  LM = Loop limit (sl/sync) or Matrix size (mtx) " << endl;
+    cout << "  Sz = Vector size for select=sync,syncp (default=32) " << endl;
+    return(1);
+  }
+
+  string sel = arg[1];
+  if ((sel != "sl") && (sel != "mtx") && (sel != "arr") && 
+      (sel != "arrdl") && (sel != "arrmf") && 
+      (sel != "sync") && (sel != "syncp") && (sel != "clk")) {
+    cout << "zthr/erreur argument sel (!= sl / mtx / arr / clk) " << endl;
+    return 2;
+  }
+
+  //--  Decodage arguments
+  N = atoi(arg[2]);
+  M = atoi(arg[3]);
+  if (narg > 4) VSZ = atoi(arg[4]);
+  cout << "zthr/Info: select=" << sel << " N=" << N << " M= " << M 
+       << " VSz=" << VSZ << endl;
+ 
+  
+  InitTim();
+  SophyaInit();
+
+  int rc = 0;
+  try {
+    ResourceUsage res(ResourceUsage::RU_All);
+    if ((sel == "mtx") || (sel == "arr") || (sel == "sl") || 
+	(sel == "arrdl") || (sel == "arrmf") ||
+	(sel == "sync") || (sel == "syncp")) {
+      if ( (sel == "sync") || (sel == "syncp"))  mtvp = new MTVecPool(N,VSZ,M);
+      vector<ztarg *> vza;
+      vector<ZThread *> vzth;
+      for(int i=0; i<N; i++) {
+	cout << "*****zthr: Creating Thread " << i+1 << " /" << N << endl;
+	ZThread * pzt = new ZThread();
+	ztarg* zap = new ztarg;
+	vzth.push_back(pzt);
+	// ATTENTION : il faut que le thid = 0 ... N-1 (et pas 1)
+	zap->thid = i;  zap->M = M;
+	zap->NTh = N;   zap->VSz = VSZ;
+	vza.push_back(zap);
+	if (sel == "mtx")  pzt->setAction(mtx_funzt, vza[i]);
+	else if (sel == "arr")  pzt->setAction(arr_funzt, vza[i]);
+	else if (sel == "arrdl")  pzt->setAction(arrdl_funzt, vza[i]);
+	else if (sel == "arrmf")  pzt->setAction(arrmf_funzt, vza[i]);
+	else if (sel == "sync")  pzt->setAction(sync_funzt, vza[i]);
+	else if (sel == "syncp")  pzt->setAction(syncp_funzt, vza[i]);
+	else pzt->setAction(funzt, vza[i]);
+      }
+      cout << "***zthr: Starting threads ... " << endl;
+      PrtTim("***zthr/StarThr");
+      for(int i=0; i<N; i++) vzth[i]->start();
+      sleep(1);
+      cout << "***ResourceUsage before thr[i].join()" << endl;
+      cout << res;
+      cout << "***zthr Joining Threads ..." << endl;
+      for(int i=0; i<N; i++) vzth[i]->join();
+      cout << "***zthr Threads Z1 ... Z" << N << " Finished OK" << endl;
+      cout << " zthr/Resusage: getDataSize() = " << res.getDataSize() << "  getStackSize()=" 
+	   << res.getStackSize() << endl;
+      cout << res;
+      for(int i=0; i<N; i++) {
+	delete vzth[i];
+	delete vza[i];
+      }
+      if (mtvp) {
+	Timer tm("MTVecPool::Check()");
+	mtvp->Check();
+	tm.Nop();
+	delete mtvp;
+      }
+    }
+    else {
+      PrtTim("BeginOfCount");
+      CountLock clk;
+      int kk;
+      for(kk=0; kk<atoi(arg[3]); kk++) {
+	clk.Count();
+      }
+      cout << " End CountLock-Test Count= " << clk.Count() << endl;
+    }
+  }
+  catch (PThrowable exc) {
+    cerr << "zthr: catched Exception " << exc.Msg() << endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception (lpk.cc) " << endl; 
+    rc = 78; 
+  } 
+  
+  return(rc);
+  
+}
+
+
+
