Index: trunk/SophyaLib/BaseTools/Makefile
===================================================================
--- trunk/SophyaLib/BaseTools/Makefile	(revision 4053)
+++ trunk/SophyaLib/BaseTools/Makefile	(revision 4056)
@@ -4,109 +4,114 @@
  
 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)randtmt64.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)dSFMT.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
+	 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)pqnumber.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randtmt64.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)sunitpcst.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)dSFMT.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
 	rm -f $(SOPHYALIBP)libBaseTools.a
  
-$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dSFMT.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)randtmt64.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
+$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)dSFMT.o $(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)pqnumber.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randtmt64.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)sunitpcst.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
 	$(AR) $(ARFLAGS) $@ $? 
 	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
  
-$(SOPHYAOBJP)datatype.o: datatype.cc datatype.h \
- $(SOPHYAINCP)machdefs.h
+$(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
+$(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
+  $(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
+$(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
+  $(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
+  $(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
+$(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
+  $(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
+$(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)pqnumber.o: pqnumber.cc $(SOPHYAINCP)machdefs.h pqnumber.h \
+  pexceptions.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pqnumber.cc
  
-$(SOPHYAOBJP)randfmt.o: randfmt.cc randfmt.h \
-  $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)randfmt.o: randfmt.cc randfmt.h $(SOPHYAINCP)machdefs.h \
   objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
   rawstream.h ppfnametag.h randinterf.h dsfmtflags.h dSFMT.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randfmt.cc
  
+$(SOPHYAOBJP)randinterf.o: randinterf.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h randinterf.h \
+  anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randinterf.cc
+ 
+$(SOPHYAOBJP)randr48.o: randr48.cc $(SOPHYAINCP)machdefs.h thsafeop.h \
+  pexceptions.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h ndatablock.h anydataobj.h randr48.h objfio.h \
+  randinterf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randr48.cc
+ 
 $(SOPHYAOBJP)randtmt32.o: randtmt32.cc randtmt32.h \
-  $(SOPHYAINCP)machdefs.h \
-  objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
-  rawstream.h ppfnametag.h randinterf.h tinymt32.h
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h ppersist.h \
+  pexceptions.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  randinterf.h tinymt32.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randtmt32.cc
  
 $(SOPHYAOBJP)randtmt64.o: randtmt64.cc randtmt64.h \
-  $(SOPHYAINCP)machdefs.h \
-  objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
-  rawstream.h ppfnametag.h randinterf.h tinymt64.h
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h ppersist.h \
+  pexceptions.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  randinterf.h tinymt64.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randtmt64.cc
  
-$(SOPHYAOBJP)randinterf.o: randinterf.cc sopnamsp.h \
- $(SOPHYAINCP)machdefs.h pexceptions.h \
- randinterf.h anydataobj.h
-	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randinterf.cc
- 
-$(SOPHYAOBJP)randr48.o: randr48.cc $(SOPHYAINCP)machdefs.h \
- thsafeop.h pexceptions.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h \
- rawstream.h ppfnametag.h ndatablock.h anydataobj.h randr48.h objfio.h \
- randinterf.h
-	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randr48.cc
- 
 $(SOPHYAOBJP)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
- $(SOPHYAINCP)machdefs.h pexceptions.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 randr48.h randinterf.h randfmt.h randtmt32.h randtmt64.h fiosegdb.h \
- segdatablock.h thsafeop.h ppftpointerio.h ppfwrapstlv.h sversion.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 randr48.h randinterf.h randfmt.h randtmt32.h randtmt64.h \
+  fiosegdb.h segdatablock.h thsafeop.h ppftpointerio.h ppfwrapstlv.h \
+  sunitpcst.h pqnumber.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
+$(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)sunitpcst.o: sunitpcst.cc $(SOPHYAINCP)machdefs.h \
+  sunitpcst.h pqnumber.h pexceptions.h ppersist.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h objfio.h anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sunitpcst.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
+  timestamp.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timestamp.cc
  
@@ -114,6 +119,6 @@
 	$(CCOMPILE) -o $@  dSFMT.c
  
-$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h \
- bithelp.h gnumd5.h
+$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h bithelp.h \
+  gnumd5.h
 	$(CCOMPILE) -o $@  gnumd5.c
  
Index: trunk/SophyaLib/BaseTools/objlist.list
===================================================================
--- trunk/SophyaLib/BaseTools/objlist.list	(revision 4053)
+++ trunk/SophyaLib/BaseTools/objlist.list	(revision 4056)
@@ -1,4 +1,4 @@
+dSFMT.o
 datatype.o
-dSFMT.o
 dvlist.o
 fiondblock.o
@@ -10,12 +10,14 @@
 ppfbinstream.o
 ppftpointerio.o
+pqnumber.o
 randfmt.o
+randinterf.o
+randr48.o
 randtmt32.o
 randtmt64.o
-randinterf.o
-randr48.o
 rawstream.o
 sophyainit.o
 stsrand.o
+sunitpcst.o
 timestamp.o
 tinymt32.o
Index: trunk/SophyaLib/BaseTools/pqnumber.cc
===================================================================
--- trunk/SophyaLib/BaseTools/pqnumber.cc	(revision 4056)
+++ trunk/SophyaLib/BaseTools/pqnumber.cc	(revision 4056)
@@ -0,0 +1,362 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include "pqnumber.h"
+#include "pexceptions.h"
+#include "thsafeop.h"  //  for ThreadSafe operations (Ref.Count/Share) 
+#include <iostream>
+
+namespace SOPHYA {
+
+/*!
+   \class PrimeNumbers
+   \ingroup BaseTools
+   A simple class for class for manipulating prime naumbers. This class is thread safe
+   
+   \code
+   // Create a PrimeNumbers object 
+   PrimeNumbers primes;
+   // Print the first 15 primes ...
+   for(size_t k=0; k<15; k++) 
+     cout << primes(k) << endl; 
+   // Print all prime numbers less than some max values
+   uint_8 pmax = 223;
+   uint_8 p = primes.Next();
+   while (p<pmax) {
+     cout << p << endl;
+     p = primes.Next();
+   }
+   \endcode
+*/
+
+
+//---------------------  Classe PrimeNumbers   ------------------------
+static ThSafeOp* primes_gThsop = NULL;  // Mutex global pour thread-safety
+std::vector<uint_8> * PrimeNumbers::prime_list_p_ = NULL;  // global prime number list  
+
+/* --Methode-- */ 
+PrimeNumbers::PrimeNumbers()
+  : my_prime_idx_(0)
+{
+  Init();  
+}
+
+/* --Methode-- */ 
+PrimeNumbers::PrimeNumbers(PrimeNumbers const& p)
+  : my_prime_idx_(p.my_prime_idx_)
+{
+  Init();
+}
+
+
+/* --Methode-- */ 
+uint_8 PrimeNumbers::Get(size_t k)  const 
+{
+  uint_8 rp=2;
+  while (k>=prime_list_p_->size()) {
+    size_t nxt=k-prime_list_p_->size()+1;
+    if ((nxt<5)||(nxt < prime_list_p_->size()/16))  Extend(nxt);
+    else { 
+      double dnl,dnh;
+      if (k<40000) encadre6(k, dnl,dnh);
+      else encadre40k(k, dnl,dnh);
+      uint_8 n = (uint_8)dnh+1;
+      //DBG      cout << " DBG*PrimeNumbers::Get(" << k << ")  dnh=" << dnh << " ->int=" << n << " nxt=" << nxt << endl;
+      Extend2(n);
+    }
+  }
+  rp= prime_list_p_->at(k);
+  return(rp);
+}
+
+/* --Methode-- */ 
+bool PrimeNumbers::CheckIfPrim(uint_8 n)
+{
+  if (n<4) return true;
+  // On verifie et etend la liste des nombres premiers si besoin
+  uint_8 pe=prime_list_p_->at(prime_list_p_->size()-1);
+  while (pe*pe<(n+1)) {
+    uint_8 pet=pe;
+    while (pet*pet<(n+1))  pet+=pe/4;
+    Extend2(pet);
+    pe=prime_list_p_->at(prime_list_p_->size()-1);
+  }
+  // On verifie si n est premier 
+  PrimeNumbers primes;
+  uint_8 p=primes.Next();
+  while (p*p<=n) {
+    if (n%p==0)  return false;
+    p=primes.Next();
+  }
+  return true;
+}
+
+/* --Methode-- */ 
+vector<uint_8> PrimeNumbers::PrimeFactors(uint_8 n, bool fgprt)
+{
+  PrimeNumbers primes;
+  std::vector<uint_8> fact;
+  if (n<4) {
+    if (n==0) fact.push_back(0);
+    else if (n==1) fact.push_back(1);
+    else if (n==2) fact.push_back(2);
+    else fact.push_back(3);
+    if (fgprt) cout << "  PrimeFactors(" << n << ")= " << fact[0] << endl;
+    return fact;
+  }
+  uint_8 n0=n;
+  uint_8 p=primes.Next();  
+  while(n>1) {
+    if (n%p==0) { fact.push_back(p); n/=p; }
+    else p=primes.Next();
+  }
+  if (fgprt) { 
+    cout << "  PrimeFactors(" << n0 << ")= " << fact[0]; 
+    if (fact.size()>1)  {
+      for(size_t k=1; k<fact.size(); k++) {
+	cout << " x " << fact[k];
+	if (k%20==0)  cout << "\n ...   ";
+      }
+    }
+    cout << endl;
+  }
+  return fact;
+}
+
+/* --Methode-- */ 
+void PrimeNumbers::encadre6(size_t nieme,double &nlow,double &nhigh)
+// encadrement du N-ieme (>=6) nombre premier
+// warning: dump if n==1
+{
+  double n = (double)nieme, ln = log(n), lln = log(log(n));
+  nlow  = n * (ln + lln - 1.);
+  nhigh = n * (ln + lln);
+  return;
+}
+
+/* --Methode-- */ 
+void PrimeNumbers::encadre40k(size_t nieme,double &nlow,double &nhigh)
+// encadrement du N-ieme (>=40000) nombre premier
+//     (rigoureusement nieme>=38691)
+// warning: dump if n==1
+{
+  double n = (double)nieme, ln = log(n), lln = log(log(n));
+  nlow =  n * (ln + lln - 1.);
+  nhigh = n * (ln + lln - 0.948);
+  return;
+}
+
+/* --Methode-- */ 
+double PrimeNumbers::approx(unsigned int nieme)
+// approximation du N-ieme
+// warning: dump if n==1
+{
+  double n = nieme, ln = log(n), lln = log(log(n));
+  return n * (ln + lln - 1. + (lln-2.)/ln);
+}
+
+/* --Methode-- */ 
+void PrimeNumbers::Init()
+{
+  if (primes_gThsop != NULL)  return;
+  primes_gThsop = new ThSafeOp;
+  primes_gThsop->lock();
+  prime_list_p_ = new std::vector<uint_8>(10,1);
+  uint_8 firstp[10]={2,3,5,7,11,13,17,19,23,29};
+  for(size_t k=0; k<10; k++)  prime_list_p_->at(k)=firstp[k];
+  primes_gThsop->unlock();
+  return;
+}
+
+/* --Methode-- */ 
+void PrimeNumbers::Extend(size_t nxt)
+{
+  primes_gThsop->lock();
+  //DBG  cout << "\n DBG*Extend Sz=" << prime_list_p_->size() << " nxt= " << nxt << endl;
+
+  for(size_t i=0; i<nxt; i++) {
+    uint_8 n = prime_list_p_->at(prime_list_p_->size()-1)+2;
+    bool fgp=false;  
+    while(!fgp) {
+      fgp=CheckIfPrim_P(n);
+      if (fgp) { prime_list_p_->push_back(n);  break; }
+      else n+=2;
+    }
+  }
+  primes_gThsop->unlock();
+  return;
+}
+
+/* --Methode-- */ 
+void PrimeNumbers::Extend2(uint_8 P)
+{
+  uint_8 P0=prime_list_p_->at(prime_list_p_->size()-1);
+  if (P0>=P)  return;
+  primes_gThsop->lock();
+  //DBG cout << "\n DBG*Extend2 Sz=" << prime_list_p_->size() << " P0=" << P0 << " ->P=" << P;
+  size_t npremiers;
+  unsigned char* liste=eratosthene(P,npremiers);
+  for(uint_8 i=P0+1; i<P; i+=2) 
+    if (liste[i])  prime_list_p_->push_back(i+1);
+  delete[] liste; 
+  //DBG cout << "  NewSz=" << prime_list_p_->size() << " LastP=" << prime_list_p_->at(prime_list_p_->size()-1) << endl;
+  primes_gThsop->unlock();
+  return;
+}
+
+
+/* --Methode-- */ 
+bool PrimeNumbers::CheckIfPrim_P(uint_8 n)
+{
+  size_t k=0;
+  uint_8 p=prime_list_p_->at(k);
+  while (p*p<=n) {
+    if (n%p==0)  return false;
+    k++; p=prime_list_p_->at(k);
+  }
+  return true;
+}
+
+
+/* --Methode-- */ 
+unsigned char* PrimeNumbers::eratosthene(uint_8 P, size_t& npremiers)
+/*
+ -- Le crible d'Eratosthene --
+ Trouver tous les nombres premiers inferieurs a un entier P
+ - Methode:
+   On ecrit tous les nombres de 1 a P
+   On elimine tous ceux qui sont divisibles par 2
+   On elimine tous ceux qui sont divisibles par 3
+   ...
+   Ainsi de suite pour tous les nombres les plus petits qui restent.
+   Les nombres successifs qui restent sont des nombres premiers.
+ - Implementation: routine eratosthene()
+     P : on cherche les nombres premiers <= P
+     liste : liste[i]=1 si "i+1" est un nombre premier
+                     =0 sinon
+     Retourne le nombre de nombres premiers <= P
+   Attention "liste" est alloue par la routine eratosthene
+     et doit etre detruite par le programme appelant
+*/
+{
+  uint_8 i,j,p,pp;
+  npremiers=0;
+  unsigned char* liste = new unsigned char[P]; 
+  for(i=0;i<P;i++) liste[i]=1;
+
+  npremiers = 1;
+  for(i=1;i<P;i++) {
+    // On teste la primarite du nombre "p" = "i+1"
+    p = i+1;
+    /* printf("test i=%llu p=%llu liste[i]=%d\n",i,p,(*liste)[i]); */
+    if(liste[i]==0) continue;
+    npremiers++; pp=2*p; j=pp-1;
+    while(j<P) {
+      /* printf("  kill j=%llu pp=%llu\n",j,pp); */
+      liste[j]=0;
+      pp+=p; j=pp-1;
+    }
+  }
+ return liste;
+}
+
+/*!
+   \class QNumber
+   \ingroup BaseTools
+   Class representing rational number (q \in Q). All operations are thread-safe.
+   
+   \code
+   // Create rational numbers from integers
+   QNumber q1(3,4), q2(5,6), q3(6,8);
+   // Operations and comparsion
+   QNumber q4 = q1+q2; 
+   cout << q1 << " + " << q2 << " = " << q4 << endl;
+   QNumber qa(q1), qb(q2);
+   cout " Test qa==qb : -> " << qa << " ?== " << qb;
+   if (qa == qb)  cout << " -> true " << endl;
+   else cout << " -> false " << endl;
+   qb = q3;
+   cout " Test qa==qb : -> " << qa << " ?== " << qb;
+   if (qa == qb)  cout << " -> true " << endl;
+   else cout << " -> false " << endl;
+   QNumber qq(3*7*17*5,(-5)*7*11*2);
+   cout << " qq= " << qq << "  qq.Simplify() = " << qq.Simplify() << endl;
+   \endcode
+*/
+
+/* --Methode-- */ 
+QNumber QNumber::Simplify() const
+{
+  if (num_==den_) return QNumber(1);
+  if (num_==(-den_))  return QNumber(-1);
+  uint_8 m=(num_>0)?(uint_8)num_:(uint_8)(-num_);
+  uint_8 n=(den_>0)?(uint_8)den_:(uint_8)(-den_);
+  QNumber qs=*this;
+  PrimeNumbers primes;
+  uint_8 p=primes.Next();
+  uint_8 petit=(m<n)?m:n;
+  while (p*p<=petit) {
+    if ((m%p==0)&&(n%p==0)) { m/=p; n/=p; }
+    else p=primes.Next();
+  }
+  int_8 nu=(int_8)m;
+  int_8 de=(int_8)n;
+  if (num_<0) nu= -nu;
+  if (den_<0) de= -de;
+  return QNumber(nu,de);
+}
+
+/* --Methode-- */ 
+std::string QNumber::ToString()
+{
+  char buff[128];
+  if (den_==1)  sprintf(buff,"%ld",(long)num_);
+  else sprintf(buff,"(%ld/%ld)",(long)num_,long(den_));
+  return buff;
+}
+
+/* --Methode-- */ 
+QNumber QNumber::Add(QNumber const & a, QNumber const & b, bool fgsimp)
+{
+  QNumber rq=QNumber(a.num_*b.den_+b.num_*a.den_, a.den_*b.den_);
+  if (fgsimp) return rq.Simplify();
+  else return rq;
+}
+
+/* --Methode-- */ 
+QNumber QNumber::Subtract(QNumber const & a, QNumber const & b, bool fgsimp)
+{
+  QNumber rq=QNumber(a.num_*b.den_-b.num_*a.den_, a.den_*b.den_);
+  if (fgsimp) return rq.Simplify();
+  else return rq;
+}
+
+/* --Methode-- */ 
+QNumber QNumber::Multiply(QNumber const & a, QNumber const & b, bool fgsimp)
+{
+  QNumber rq=QNumber(a.num_*b.num_, a.den_*b.den_);
+  if (fgsimp) return rq.Simplify();
+  else return rq;
+}
+
+/* --Methode-- */ 
+QNumber QNumber::Divide(QNumber const & a, QNumber const & b, bool fgsimp)
+{
+  if (b.num_==0)  throw MathExc("QNumber::Divide(a,b) b=0->divide by zero");  
+  QNumber rq=QNumber(a.num_*b.den_, a.den_*b.num_);
+  if (fgsimp) return rq.Simplify();
+  else return rq;
+}
+
+
+
+/* --Methode-- */ 
+int QNumber::Compare(QNumber const & a, QNumber const & b)
+{
+  QNumber diff=a-b;
+  if (diff.Numerator()==0)  return 0;
+  else if (diff.Numerator()>0)  return 1;
+  else return -1;
+}
+
+
+} // FIN namespace SOPHYA 
Index: trunk/SophyaLib/BaseTools/pqnumber.h
===================================================================
--- trunk/SophyaLib/BaseTools/pqnumber.h	(revision 4056)
+++ trunk/SophyaLib/BaseTools/pqnumber.h	(revision 4056)
@@ -0,0 +1,211 @@
+// This may look like C code, but it is really -*- C++ -*-
+//-----------------------------------------------------------
+// Class  PrimesNumbers (prime numbers)
+// Class  QNumber (Rational numbers)
+// SOPHYA class library - (C)  UPS+LAL IN2P3/CNRS  , CEA-Irfu 
+// R. Ansari      UPS+LAL IN2P3/CNRS  2012
+//-----------------------------------------------------------
+
+#ifndef PQNUMBER_H_SEEN
+#define PQNUMBER_H_SEEN
+
+
+#include "machdefs.h"
+#include <string> 
+#include <vector> 
+#include <iostream> 
+
+#include "pexceptions.h"
+#include "ppersist.h"
+
+
+namespace SOPHYA {
+
+//--------------------------------------------------------------------------------   
+//------------------------------ PrimeNumbers class ------------------------------
+//--------------------------------------------------------------------------------   
+
+//! Class providing list of prime number
+class PrimeNumbers {
+public:
+  //! Default constructor 
+  PrimeNumbers();
+  //! Copy constructor
+  PrimeNumbers(PrimeNumbers const& p);
+
+  //! return the next prime number 
+  inline uint_8 Next()
+  { uint_8 rp=Get(my_prime_idx_); my_prime_idx_++; return rp; }
+  //! rewind / reset prime number index for the Next() method
+  inline void Rewind() { my_prime_idx_=0; } 
+  //! Reset prime number index for the Next() method
+  inline void ResetIndex() { my_prime_idx_=0; } 
+
+  //! return the \b k th prime number 
+  uint_8 Get(size_t k) const;
+  //! return the \b k th prime number (operator [] overload)
+  inline uint_8 operator[](size_t k) const { return Get(k); }
+  //! return the \b k th prime number (operator () overload)
+  inline uint_8 operator()(size_t k) const { return Get(k); }
+  //! return true if the argument \b n is a prime number 
+  static bool CheckIfPrim(uint_8 n);
+  //! return the prime number factorization of \b n 
+  static std::vector<uint_8> PrimeFactors(uint_8 n, bool fgprt=false);
+
+  //! Computes an interval for the n-th (n>=6) prime number 
+  static void encadre6(size_t nieme,double &nlow,double &nhigh);
+  //! Computes an interval for the n-th (n>=40000) prime number 
+  static void encadre40k(size_t nieme,double &nlow,double &nhigh);
+  //! Return an approximate value for the n-th prime number 
+  static double approx(unsigned int nieme);
+
+private:
+  //! Global initialization (Mutex object  and prime number array creation)
+  static void Init();
+  //! Extends the prime number array by finding the next \b nxt prime numbers 
+  static void Extend(size_t nxt);
+  //! Extends the prime number array by finding all prime numbers p such as p<=n
+  static void Extend2(uint_8 n);
+
+  //! Static private member used by Extend() to check if a number is prime
+  static bool CheckIfPrim_P(uint_8 n);
+  //! Static private member to find all prime numbers less than P. return the list of flags.
+  static unsigned char* eratosthene(uint_8 P, size_t& npremiers);
+
+  size_t my_prime_idx_;   // prime number index for Next() method
+  static std::vector<uint_8> * prime_list_p_;   // global prime number array
+};
+
+//--------------------------------------------------------------------------------   
+//---------------------- QNumber class : rational numbers ------------------------
+//--------------------------------------------------------------------------------   
+
+//! Class representing rational numbers : q = m/n with m,n integers)
+class QNumber {  // : public AnyDataObj {
+public:
+  //! Default constructor, with 0 value (= 0 / 1) 
+  explicit QNumber()
+  { num_=0; den_=1; }
+  //! Constructor from two integers, numerator and denominator
+  QNumber(int_8 m, int_8 n=1)
+  { 
+    if (n==0)  throw MathExc("QNumber(m,n) n=0->null denominator");  
+    num_=m;  den_=n; 
+    if (den_<0)  { num_=-num_; den_=-den_; } 
+  }
+  //! Copy constructor
+  QNumber(QNumber const& q)
+  { num_=q.num_;  den_=q.den_; }
+
+  //! copy (equal) operator 
+  inline QNumber& operator = (QNumber const & q) 
+  { num_=q.num_;  den_=q.den_; return(*this); }   
+
+  //! Return the simplified rational number (division by all common divisors of numerator and denominator)
+  QNumber Simplify() const; 
+
+  //! Convert to decimal (double precision) number 
+  inline operator double() const { return (double)num_/(double)den_; }
+  //! Return the numerator
+  inline int_8 Numerator() const { return num_; }
+  //! Return the denominator
+  inline int_8 Denominator() const { return den_; }
+
+  //! Return the opposite (-q) of the rational number
+  inline QNumber Opposite() const 
+  { return QNumber(-num_, den_); }
+  //! Return the inverse (1/q) of the rational number
+  inline QNumber Inverse()  const 
+  { return QNumber(den_, num_); }
+
+  //! Return true if the rational number is equal to zero , false otherwise
+  inline bool isZero()  const
+  { return ( (num_==0)?true:false ); }
+  //! Return true if the rational number represents an integer , false otherwise
+  inline bool isInteger()  const
+  { return ((Simplify().Denominator()==1)?true:false); }
+
+  //! Return the rational number in string format (num/den) 
+  std::string ToString(); 
+  //! Prints the rational number on \b cout  (return the cout stream object)
+  inline ostream&  Print()  const  
+  { return Print(cout); }  
+  //! Prints the rational number on stream \b os (return the os stream object)
+  inline ostream& Print(ostream& os)  const
+  { 
+    if (den_==1)  os << num_;
+    else os << "(" << num_ << '/' << den_ <<")"; 
+    return os;
+  }   
+
+  //! Add two QNumbers (simplify the result if fgsimp true)
+  static QNumber  Add(QNumber const & a, QNumber const & b, bool fgsimp=true);
+  //! Subtract two QNumbers (simplify the result if fgsimp true)
+  static QNumber  Subtract(QNumber const & a, QNumber const & b, bool fgsimp=true);
+  //! Multiply two QNumbers (simplify the result if fgsimp true)
+  static QNumber  Multiply(QNumber const & a, QNumber const & b, bool fgsimp=true);
+  //! Divide two QNumbers (simplify the result if fgsimp true)
+  static QNumber  Divide(QNumber const & a, QNumber const & b, bool fgsimp=true);
+  //! Compare two QNumbers: return -1 (a<b), 0 (a==b), 1 (a>b)  
+  static int Compare(QNumber const & a, QNumber const & b);
+
+protected:
+  int_8 num_,den_;      // numerateur et denominateur 
+};
+
+
+/*! operator << overloading - prints the QNumber q on \b os*/
+inline ostream& operator << (ostream& s, QNumber q)
+  {  q.Print(s);  return(s);  }
+
+/*! Sum operator definition for QNumbers : r = a + b  */
+inline QNumber operator + (QNumber a, QNumber b)
+  { return QNumber::Add(a,b); }
+
+/*! Difference (subtraction) operator definition for QNumbers : r = a - b  */
+inline QNumber operator - (QNumber a, QNumber b)
+  { return QNumber::Subtract(a,b); }
+
+/*! Product (multiplication) operator definition for QNumbers : r = a * b  */
+inline QNumber operator * (QNumber a, QNumber b)
+  { return QNumber::Multiply(a,b); }
+
+/*! Divide operator definition for QNumbers : r = a / b  */
+inline QNumber operator / (QNumber a, QNumber b)
+  { return QNumber::Divide(a,b); }
+
+/*! Equality comparison operator == for QNumbers : return true if (a == b)  */
+inline bool operator == (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)==0); }
+
+/*! Not equal comparison operator != for QNumbers : return true if (a != b)  */
+inline bool operator != (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)!=0); }
+
+/*! Comparison operator < for QNumbers : return true if (a < b)  */
+inline bool operator < (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)<0); }
+
+/*! Comparison operator > for QNumbers : return true if (a > b)  */
+inline bool operator > (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)>0); }
+
+/*! Comparison operator <= for QNumbers : return true if (a <= b)  */
+inline bool operator <= (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)<=0); }
+
+/*! Comparison operator >= for QNumbers : return true if (a >= b)  */
+inline bool operator >= (QNumber a, QNumber b)
+{ return ( QNumber::Compare(a,b)>=0); }
+
+/*! Writes the two integers representing a QNumber in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, QNumber const& q)
+{ os << q.Numerator() << q.Denominator();  return(os); }
+/*! Reads the object from the PInPersist stream \b is  */
+inline PInPersist& operator >> (PInPersist& is, QNumber& q)
+{ int_8 num,den; is >> num >> den; q = QNumber(num,den);  return(is); }
+
+
+} // namespace SOPHYA
+
+#endif
Index: trunk/SophyaLib/BaseTools/smakefile
===================================================================
--- trunk/SophyaLib/BaseTools/smakefile	(revision 4053)
+++ trunk/SophyaLib/BaseTools/smakefile	(revision 4056)
@@ -4,109 +4,114 @@
  
 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)randtmt64.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)dSFMT.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
+	 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)pqnumber.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randtmt64.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)sunitpcst.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)dSFMT.o $(SOPHYAOBJP)gnumd5.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
 	rm -f $(SOPHYALIBP)libBaseTools.a
  
-$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)datatype.o $(SOPHYAOBJP)dSFMT.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)randtmt64.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
+$(SOPHYALIBP)libBaseTools.a : $(SOPHYAOBJP)dSFMT.o $(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)pqnumber.o $(SOPHYAOBJP)randfmt.o $(SOPHYAOBJP)randinterf.o $(SOPHYAOBJP)randr48.o $(SOPHYAOBJP)randtmt32.o $(SOPHYAOBJP)randtmt64.o $(SOPHYAOBJP)rawstream.o $(SOPHYAOBJP)sophyainit.o $(SOPHYAOBJP)stsrand.o $(SOPHYAOBJP)sunitpcst.o $(SOPHYAOBJP)timestamp.o $(SOPHYAOBJP)tinymt32.o $(SOPHYAOBJP)tinymt64.o
 	$(AR) $(ARFLAGS) $@ $? 
 	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
  
-$(SOPHYAOBJP)datatype.o: datatype.cc datatype.h \
- $(SOPHYAINCP)machdefs.h
+$(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
+$(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
+  $(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
+$(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
+  $(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
+  $(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
+$(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
+  $(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
+$(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)pqnumber.o: pqnumber.cc $(SOPHYAINCP)machdefs.h pqnumber.h \
+  pexceptions.h ppersist.h gnumd5.h ppfbinstream.h rawstream.h \
+  ppfnametag.h thsafeop.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pqnumber.cc
  
-$(SOPHYAOBJP)randfmt.o: randfmt.cc randfmt.h \
-  $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)randfmt.o: randfmt.cc randfmt.h $(SOPHYAINCP)machdefs.h \
   objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
   rawstream.h ppfnametag.h randinterf.h dsfmtflags.h dSFMT.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randfmt.cc
  
+$(SOPHYAOBJP)randinterf.o: randinterf.cc sopnamsp.h \
+  $(SOPHYAINCP)machdefs.h pexceptions.h randinterf.h \
+  anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randinterf.cc
+ 
+$(SOPHYAOBJP)randr48.o: randr48.cc $(SOPHYAINCP)machdefs.h thsafeop.h \
+  pexceptions.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h ndatablock.h anydataobj.h randr48.h objfio.h \
+  randinterf.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randr48.cc
+ 
 $(SOPHYAOBJP)randtmt32.o: randtmt32.cc randtmt32.h \
-  $(SOPHYAINCP)machdefs.h \
-  objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
-  rawstream.h ppfnametag.h randinterf.h tinymt32.h
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h ppersist.h \
+  pexceptions.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  randinterf.h tinymt32.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randtmt32.cc
  
 $(SOPHYAOBJP)randtmt64.o: randtmt64.cc randtmt64.h \
-  $(SOPHYAINCP)machdefs.h \
-  objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h ppfbinstream.h \
-  rawstream.h ppfnametag.h randinterf.h tinymt64.h
+  $(SOPHYAINCP)machdefs.h objfio.h anydataobj.h ppersist.h \
+  pexceptions.h gnumd5.h ppfbinstream.h rawstream.h ppfnametag.h \
+  randinterf.h tinymt64.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randtmt64.cc
  
-$(SOPHYAOBJP)randinterf.o: randinterf.cc sopnamsp.h \
- $(SOPHYAINCP)machdefs.h pexceptions.h \
- randinterf.h anydataobj.h
-	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randinterf.cc
- 
-$(SOPHYAOBJP)randr48.o: randr48.cc $(SOPHYAINCP)machdefs.h \
- thsafeop.h pexceptions.h fiondblock.h ppersist.h gnumd5.h ppfbinstream.h \
- rawstream.h ppfnametag.h ndatablock.h anydataobj.h randr48.h objfio.h \
- randinterf.h
-	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  randr48.cc
- 
 $(SOPHYAOBJP)rawstream.o: rawstream.cc sopnamsp.h rawstream.h \
- $(SOPHYAINCP)machdefs.h pexceptions.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 randr48.h randinterf.h randfmt.h randtmt32.h randtmt64.h fiosegdb.h \
- segdatablock.h thsafeop.h ppftpointerio.h ppfwrapstlv.h sversion.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 randr48.h randinterf.h randfmt.h randtmt32.h randtmt64.h \
+  fiosegdb.h segdatablock.h thsafeop.h ppftpointerio.h ppfwrapstlv.h \
+  sunitpcst.h pqnumber.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
+$(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)sunitpcst.o: sunitpcst.cc $(SOPHYAINCP)machdefs.h \
+  sunitpcst.h pqnumber.h pexceptions.h ppersist.h gnumd5.h ppfbinstream.h \
+  rawstream.h ppfnametag.h objfio.h anydataobj.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  sunitpcst.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
+  timestamp.h objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h \
+  ppfbinstream.h rawstream.h ppfnametag.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  timestamp.cc
  
@@ -114,6 +119,6 @@
 	$(CCOMPILE) -o $@  dSFMT.c
  
-$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h \
- bithelp.h gnumd5.h
+$(SOPHYAOBJP)gnumd5.o: gnumd5.c $(SOPHYAINCP)machdefs.h bithelp.h \
+  gnumd5.h
 	$(CCOMPILE) -o $@  gnumd5.c
  
Index: trunk/SophyaLib/BaseTools/sophyainit.cc
===================================================================
--- trunk/SophyaLib/BaseTools/sophyainit.cc	(revision 4053)
+++ trunk/SophyaLib/BaseTools/sophyainit.cc	(revision 4056)
@@ -22,4 +22,6 @@
 #include "fiosegdb.h" 
 #include "ppfwrapstlv.h" 
+
+#include "sunitpcst.h"
 
 #include "sversion.h"
@@ -42,6 +44,8 @@
 //    par les PPersist (fev 2010) 
 // Module version number - 2.30 ,  Fev10 
+//  - Fev 2012: Ajout classes PrimeNumbers, QNumber, Units, PhysQty 
+// Module version number - 2.40 ,  Avr12 
      
-#define MOD_VERS   2.30
+#define MOD_VERS   2.40
 
 // Pour garder la liste des modules et leurs numeros de version
@@ -181,4 +185,10 @@
   DObjRegister(PPFWrapperSTLVector< TimeStamp >, std::vector<TimeStamp>);
 
+  // Avr 2012: Enregistrement des handlers PPF pour les classes Units et PhysQty (unites et grandeurs physiques) 
+  PPRegister(ObjFileIO<Units>);
+  DObjRegister(ObjFileIO<Units>, Units);
+  PPRegister(ObjFileIO<PhysQty>);
+  DObjRegister(ObjFileIO<PhysQty>, PhysQty);
+
 
 #if (!defined(__GNUG__) && !defined(HPUX))
Index: trunk/SophyaLib/BaseTools/sunitpcst.cc
===================================================================
--- trunk/SophyaLib/BaseTools/sunitpcst.cc	(revision 4056)
+++ trunk/SophyaLib/BaseTools/sunitpcst.cc	(revision 4056)
@@ -0,0 +1,286 @@
+#include "machdefs.h"
+#include "sunitpcst.h"
+
+namespace SOPHYA {
+
+/*!
+   \class Units
+   \ingroup BaseTools
+   Class for representing physical units
+   
+   \code
+   // Create ....
+   \endcode
+*/
+
+//-------------------------------------------------------------------------
+//-------------------------  Classe Units  --------------------------
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+Units::Units()
+  : mLength_(0), mMass_(0), mTime_(0), mCurr_(0), 
+    mTemp_(0), mSubst_(0), mLumInt_(0), mSI_Value_(0.)
+{
+}
+
+/* --Methode-- */
+Units::Units(const char* nom, const char* snom, int m, int kg, int s, r_8 val, int A, int K, int mol, int cd)
+  : mLength_(m), mMass_(kg), mTime_(s), mCurr_(A), 
+    mTemp_(K), mSubst_(mol), mLumInt_(cd), mSI_Value_(val),
+    mName_(nom), mShortName_(snom)
+{
+}
+
+
+/* --Methode-- */
+Units::Units(Units const& un)
+{
+  Set(un);
+}
+
+/* --Methode-- */
+Units::~Units()
+{
+}
+
+/* --Methode-- */
+Units& Units::Set(Units const& un)
+{
+  mLength_ = un.mLength_;
+  mMass_=un.mMass_;
+  mTime_=un.mTime_; 
+  mCurr_=un.mCurr_; 
+  mTemp_=un.mTemp_; 
+  mSubst_=un.mSubst_;
+  mLumInt_=un.mLumInt_;
+  mSI_Value_=un.mSI_Value_;
+  mName_=un.mName_;
+  mShortName_=un.mShortName_;
+  return (*this);
+}
+
+/* --Methode-- */
+bool Units::isSameDimension(Units const& un)  const
+{
+  if ( (mLength_ == un.mLength_) && (mMass_==un.mMass_) && 
+       (mTime_==un.mTime_) && (mCurr_==un.mCurr_) && 
+       (mTemp_==un.mTemp_) && (mSubst_==un.mSubst_) && (mLumInt_==un.mLumInt_) ) return true;
+  else return false;
+}
+
+/* --Methode-- */
+ostream& Units::Print(ostream& os, int lev)  const
+{
+  if (lev < 2) {
+    if (lev==0) os << mShortName_;
+    else  os << mName_;
+    return os; 
+  }
+  os << mName_ << " (" << mShortName_ << ") SI_Value=" << mSI_Value_ << " [ ";
+  if (!mLength_.isZero()) os << "L" << '^' << mLength_ << ' ';
+  if (!(mMass_.isZero())) os << "M" << '^' << mMass_ << ' ';
+  if (!(mTime_.isZero())) os << "T" << '^' << mTime_ << ' ';
+  if (!mCurr_.isZero()) os << "I" << '^' << mCurr_ << ' ';
+  if (!mTemp_.isZero()) os << "K" << '^' << mTemp_ << ' ';
+  if (!mSubst_.isZero()) os << "Mol" << '^' << mSubst_ << ' ';
+  if (!mLumInt_.isZero()) os << "Lum" << '^' << mLumInt_ << ' ';
+  cout << " ]" << endl;
+  return os;
+}
+
+/* --Methode-- */
+Units Units::power(QNumber q)  const
+{
+  Units ru;
+  ru.mLength_=mLength_*q; 
+  ru.mMass_=mMass_*q;
+  ru.mTime_=mTime_*q;
+  ru.mCurr_=mCurr_*q;
+  ru.mTemp_=mTemp_*q;
+  ru.mSubst_=mSubst_*q;
+  ru.mLumInt_=mLumInt_*q;
+  ru.mSI_Value_=pow(mSI_Value_,(double)q);
+  ru.mName_=mName_ + '^' + q.ToString();
+  ru.mShortName_=mShortName_ + '^' + q.ToString();
+  return ru;
+}
+
+/* --Methode-- */
+Units Units::Multiply(Units const& u1, Units const& u2)
+{
+  Units ru;
+  ru.mLength_=u1.mLength_+u2.mLength_;
+  ru.mMass_=u1.mMass_+u2.mMass_;
+  ru.mTime_=u1.mTime_+u2.mTime_;
+  ru.mCurr_=u1.mCurr_+u2.mCurr_;
+  ru.mTemp_=u1.mTemp_+u2.mTemp_;
+  ru.mSubst_=u1.mSubst_+u2.mSubst_;
+  ru.mLumInt_=u1.mLumInt_+u2.mLumInt_;
+  ru.mSI_Value_=u1.mSI_Value_*u2.mSI_Value_;
+  ru.mName_=u1.mName_ + '.' + u2.mName_;
+  ru.mShortName_=u1.mShortName_ + '.' + u2.mShortName_;
+  return ru;
+}
+
+/* --Methode-- */
+Units Units::Divide(Units const& u1, Units const& u2)
+{
+  Units ru;
+  ru.mLength_=u1.mLength_-u2.mLength_;
+  ru.mMass_=u1.mMass_-u2.mMass_;
+  ru.mTime_=u1.mTime_-u2.mTime_;
+  ru.mCurr_=u1.mCurr_-u2.mCurr_;
+  ru.mTemp_=u1.mTemp_-u2.mTemp_;
+  ru.mSubst_=u1.mSubst_-u2.mSubst_;
+  ru.mLumInt_=u1.mLumInt_-u2.mLumInt_;
+  ru.mSI_Value_=u1.mSI_Value_/u2.mSI_Value_;
+  ru.mName_=u1.mName_ + '/' + u2.mName_;
+  ru.mShortName_=u1.mShortName_ + '/' + u2.mShortName_;
+  return ru;
+}
+
+
+//----------------------------------------------------------
+// Classe pour la gestion de persistance de Units
+// ObjFileIO<Units>
+//----------------------------------------------------------
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<Units>::WriteSelf(POutPersist& s) const
+{
+  if (dobj == NULL)
+    throw NullPtrError("ObjFileIO<Units>::WriteSelf() dobj=NULL");
+  int_4 ver;
+  ver = 1;
+  s.Put(ver);   // ecriture numero de version PPF
+  s << dobj->mLength_ << dobj->mMass_ << dobj->mTime_ << dobj->mCurr_;
+  s << dobj->mTemp_ << dobj->mSubst_ << dobj->mLumInt_;
+  s << dobj->mSI_Value_;
+  s << dobj->mName_ << dobj->mShortName_;
+}
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<Units>::ReadSelf(PInPersist& s)
+{
+  int_4 ver;
+  s.Get(ver);   // Lecture numero de version PPF
+
+  if (dobj == NULL) dobj = new Units();
+  s >> dobj->mLength_ >> dobj->mMass_ >> dobj->mTime_ >> dobj->mCurr_;
+  s >> dobj->mTemp_ >> dobj->mSubst_ >> dobj->mLumInt_;
+  s >> dobj->mSI_Value_;
+  s >> dobj->mName_ >> dobj->mShortName_;
+}
+
+/*!
+   \class PhysQty
+   \ingroup BaseTools
+   Class for representing physical quantities and constants 
+   
+   \code
+   // Create ....
+   \endcode
+*/
+
+//-------------------------------------------------------------------------
+//-------------------------  Classe PhysQty  --------------------------
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+PhysQty::PhysQty()
+  : unit_(), val_(0.), prec_(0.)
+{
+}
+
+/* --Methode-- */
+PhysQty::PhysQty(Units const & u, r_8 val, r_8 prec, const char* nom)
+  : unit_(u), val_(val), prec_(prec), name_((nom==NULL)?"":nom)
+{
+}
+
+/* --Methode-- */
+PhysQty::PhysQty(PhysQty const & qty)
+  : unit_(qty.unit_), val_(qty.val_), prec_(qty.prec_), name_(qty.name_)
+{
+}
+
+/* --Methode-- */
+PhysQty::~PhysQty()
+{
+}
+
+/* --Methode-- */
+PhysQty& PhysQty::Set(PhysQty const& qty)
+{
+  unit_=qty.unit_;
+  val_=qty.val_;
+  prec_=qty.prec_;
+  name_=qty.name_;
+  return (*this);
+}
+
+/* --Methode-- */
+PhysQty PhysQty::ConvertTo(Units const & u) const 
+{
+  if (! unit_.isSameDimension(u) )
+    throw ParmError("PhysQty::ConvertTo() - incompatible dimensions !");
+  return PhysQty(u, Value()*unit_.SIValue()/u.SIValue(), RelativePrecision(),Name().c_str());
+}
+
+/* --Methode-- */
+ostream& PhysQty::Print(ostream& os,int lev) const 
+{
+  if (lev==0) {
+    os << val_ << ' ' << unit_.ShortName();
+    return os; 
+  }
+  if (RelativePrecision()>0.) 
+    os << name_ << "= " << val_ << " (+/- " << AbsolutePrecision() << ") " << unit_.Name();
+  else os << name_ << "= " << val_ << " " << unit_.Name();
+  if (lev > 1) { os << " Unit: "; unit_.Print(os, lev); }
+  return os;
+}
+
+//----------------------------------------------------------
+// Classe pour la gestion de persistance de PhysQty
+// ObjFileIO<PhysQty>
+//----------------------------------------------------------
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<PhysQty>::WriteSelf(POutPersist& s) const
+{
+  if (dobj == NULL)
+    throw NullPtrError("ObjFileIO<PhysQty>::WriteSelf() dobj=NULL");
+  int_4 ver;
+  ver = 1;
+  s.Put(ver);   // ecriture numero de version PPF
+  // ecriture de l'objet Units et des champs valeurs associes 
+  s<< dobj->unit_ << dobj->val_ << dobj->prec_ << dobj->name_;
+}
+
+/* --Methode-- */
+DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
+void        ObjFileIO<PhysQty>::ReadSelf(PInPersist& s)
+{
+  int_4 ver;
+  s.Get(ver);   // Lecture numero de version PPF
+  if (dobj == NULL) dobj = new PhysQty();
+  // ecriture de l'objet Units et des champs valeurs associes 
+  s >> dobj->unit_ >> dobj->val_ >> dobj->prec_ >> dobj->name_;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Units>
+#pragma define_template ObjFileIO<PhysQty>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Units>;
+template class ObjFileIO<PhysQty>;
+#endif
+
+} // FIN namespace SOPHYA 
Index: trunk/SophyaLib/BaseTools/sunitpcst.h
===================================================================
--- trunk/SophyaLib/BaseTools/sunitpcst.h	(revision 4056)
+++ trunk/SophyaLib/BaseTools/sunitpcst.h	(revision 4056)
@@ -0,0 +1,318 @@
+// This may look like C code, but it is really -*- C++ -*-
+//-----------------------------------------------------------
+// Class  BasePhysQty : Base class for units and Physical Constants
+// SOPHYA class library - (C)  UPS+LAL IN2P3/CNRS  , CEA-Irfu 
+// R. Ansari      UPS+LAL IN2P3/CNRS  2012
+//-----------------------------------------------------------
+
+#ifndef SUNITPCST_H_SEEN
+#define SUNITPCST_H_SEEN
+
+
+#include "machdefs.h"
+#include <math.h> 
+#include <string> 
+#include <vector> 
+#include <iostream> 
+
+#include "pqnumber.h"
+#include "objfio.h"
+
+
+namespace SOPHYA {
+
+//--------------------------------------------------------------------------------   
+//--------------------------------  Units class  ---------------------------------
+//--------------------------------------------------------------------------------   
+
+//! Class representing physical dimensions and units  
+class Units : public AnyDataObj {
+// gestionnaire PPF
+  friend class ObjFileIO<Units>;
+
+public:
+  Units();
+  Units(Units const& un);
+  Units(const char* nom, const char* snom, int m, int kg, int s, r_8 val=1., int A=0, int K=0, int mol=0, int cd=0);
+  virtual ~Units();
+
+  //! Copy method
+  virtual Units& Set(Units const& un);
+  //! Copy (=) operator 
+  inline Units& operator = (Units const& un)  { return Set(un); }
+  //! return true if the two quantities have the same dimension 
+  bool isSameDimension(Units const& un) const;
+  //! return the value in base SI units
+  inline r_8 SIValue() const { return mSI_Value_; }
+  //! return the unit name 
+  inline string const& Name() const { return mName_; }
+  //! return the unit short name 
+  inline string const& ShortName() const { return mShortName_; }
+
+  //! Prints the object on \b cout (return the cout stream object)
+  inline ostream& Print(int lev=2)  const  
+  { return Print(cout,lev); }  
+  //! Prints the object on stream \b os (return the os stream object)
+  virtual ostream& Print(ostream& os,int lev=2)  const;
+
+  //! Return a new Unit corresponding to a rational power of the initial Unit 
+  virtual Units power(QNumber q) const;
+  //! Return a new Unit corresponding to an integer power of the initial Unit 
+  inline  Units power(int p) const 
+  { return power(QNumber(p,1)); }
+ 
+  //! Compute a new unit corresponding corresponding to the product of two units 
+  static Units Multiply(Units const& u1, Units const& u2);
+  //! Compute a new unit corresponding corresponding to the ratio of two units 
+  static Units Divide(Units const& u1, Units const& u2);
+  
+  // Unites multiples et sous-multiples 
+  inline Units micro()
+  { return this->Multiple(1.e-6,"micro","mu"); }
+  Units milli()
+  { return this->Multiple(1.e-3,"milli","m"); }
+  Units centi()
+  { return this->Multiple(1.e-2,"centi","c"); }
+  Units deci()
+  { return this->Multiple(1.e-1,"deci","d"); }
+  Units deca()
+  { return this->Multiple(1.e1,"deca","da"); }
+  Units hecto()
+  { return this->Multiple(1.e2,"hecto","h"); }
+  Units kilo()
+  { return this->Multiple(1.e3,"kilo","k"); }
+  Units mega()
+  { return this->Multiple(1.e6,"mega","M"); }
+  Units giga()
+  { return this->Multiple(1.e9,"giga","G"); }
+
+  // Les unites usuelles - Voir definition et convention sur 
+  inline static Units meter()
+  { return Units("meter","m",1,0,0); }
+  inline static Units kilometer()
+  { return Units("kilometer","km",1,0,0,1.e3); }
+  inline static Units centimeter()
+  { return Units("centimeter","cm",1,0,0,1.e-2); }
+  inline static Units millimeter()
+  { return Units("millimeter","mm",1,0,0,1.e-3); }
+
+  inline static Units kilogram()
+  { return Units("kilogram","kg",0,1,0); }
+  inline static Units gram()
+  { return Units("gram","g",0,1,0,0.001); }
+
+  inline static Units second()
+  { return Units("second","s",0,0,1);  }
+  inline static Units hour()
+  { return Units("hour","h",0,0,1,3600.);  }
+  inline static Units minute()
+  { return Units("minute","mn",0,0,1,60.);  }
+
+  inline static Units liter()
+  { return Units("liter","L",3,0,0);  }
+
+  inline static Units ampere()
+  { return Units("ampere","A",0,0,0,1.,1);  }
+  inline static Units kelvin()
+  { return Units("kelvin","K",0,0,0,1.,0,1);  }
+  inline static Units mole()
+  { return Units("mole","mol",0,0,0,1.,0,0,1);  }
+  inline static Units candela()
+  { return Units("candela","cd",0,0,0,1.,0,0,0,1);  }
+
+  inline static Units newton()
+  { return Units("newton","N",1,1,-2);  }
+
+  inline static Units pascal()
+  { return Units("pascal","Pa",-1,1,-2);  }
+
+  inline static Units joule()
+  { return Units("joule","J",2,1,-2);  }
+  inline static Units electronvolt()
+  { return Units("electronvolt","eV",2,1,-2,1.602176e-19); }
+
+  inline static Units watt()
+  { return Units("watt","W",2,1,-3);  }
+
+  inline static Units hertz()
+  { return Units("hertz","Hz",0,0,-1);  }
+
+  inline static Units coulomb()
+  { return Units("coulomb","C",0,0,1,1.,1);  }
+  inline static Units volt()
+  { return Units("volt","V",2,1,-3,1.,-1);  }
+  inline static Units tesla()
+  { return Units("tesla","T",0,1,-2,1.,-1);  }
+  inline static Units ohm()
+  { return Units("Ohm","Ohm",2,1,-3,1.,-2);  }
+  inline static Units henry()
+  { return Units("henry","H",2,1,-2,1.,-2);  }
+  inline static Units farad()
+  { return Units("farad","F",-2,-1,4,1.,2);  }
+
+  inline static Units radian()
+  { return Units("radian","rad",0,0,0,1);  }
+  inline static Units steradian()
+  { return Units("steradian","sr",0,0,0,1);  }
+
+
+protected:
+  inline void SetName(string const& nom, string const& snom)
+  { mName_=nom; mShortName_=snom; }
+  inline Units Multiple(r_8 fact, const char* pre, const char* spre) 
+  { 
+    Units ru(*this); ru.mSI_Value_*=fact; 
+    ru.mName_=pre+mName_; ru.mShortName_=spre+mShortName_; 
+    return ru; 
+  }
+
+  // International system of Units (SI) - http://physics.nist.gov/cuu/Units/bibliography.html
+  QNumber mLength_, mMass_, mTime_, mCurr_;     // Dimensions : length, mass, time and current 
+  QNumber mTemp_, mSubst_, mLumInt_;     // Dimensions : Temperature, Amount of substance, LuminousIntensity
+  r_8 mSI_Value_;  // Value in SI units (m, kg, s, A, Kelvin, mole, Candela) 
+  string mName_, mShortName_;   // Name and short name 
+};
+
+/*! operator << overloading - Prints Units in string format on \b os*/
+inline ostream& operator << (ostream& s, Units const & un)
+{  un.Print(s,0);  return(s);  }
+
+/*! Multiply operator definition for two Units objects   */
+inline Units operator * (Units const & a, Units const & b)
+  { return Units::Multiply(a,b); }
+
+/*! Divide operator definition for two Units objects  */
+inline Units operator / (Units const & a, Units const & b)
+  { return Units::Divide(a,b); }
+
+
+//! Writes the Units object in the POutPersist stream \b os
+inline POutPersist& operator << (POutPersist& os, Units & obj)
+{ ObjFileIO<Units> fio(&obj);  fio.Write(os);  return(os); }
+//! Reads the Units object from the PInPersist stream \b is 
+inline PInPersist& operator >> (PInPersist& is, Units & obj)
+{ ObjFileIO<Units> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+//--------------------------------------------------------------------------------   
+//-------------------------------  PhysQty class  --------------------------------
+//--------------------------------------------------------------------------------   
+
+//! Class representing physical quantities and constants   
+class PhysQty : public AnyDataObj {
+// gestionnaire PPF
+  friend class ObjFileIO<PhysQty>;
+
+public:
+  PhysQty();
+  PhysQty(Units const & u, r_8 val, r_8 prec=0., const char* nom=NULL);
+  PhysQty(PhysQty const & qty);
+  virtual ~PhysQty();
+
+  //! Copy method
+  virtual PhysQty& Set(PhysQty const& qty);
+  //! Copy (=) operator 
+  inline PhysQty& operator = (PhysQty const& qty)  { return Set(qty); }
+
+  //! Return a new physical quantity object after unit conversion   
+  PhysQty ConvertTo(Units const & u) const ;
+
+  //! Return the physical quantity value in SI units 
+  inline r_8 SIValue()  const { return val_*unit_.SIValue(); }
+  inline Units getUnit()  {return unit_; }
+  inline r_8 Value()  const { return val_; }
+  inline void setValue(r_8 val)  { val_=val; }
+  inline r_8 RelativePrecision()  const { return prec_; }
+  inline void setRelativePrecision(r_8 prec) { prec_=prec; }
+  inline r_8 AbsolutePrecision() const { return prec_*val_; }
+  //! return the unit name 
+  inline string const& Name() const { return name_; }
+
+  //! Prints the object on \b cout (return the cout stream object)
+  inline ostream& Print(int lev=0)  const  
+  { return Print(cout, lev); }  
+  //! Prints the object on stream \b os (return the os stream object)
+  virtual ostream& Print(ostream& os,int lev=2)  const;
+
+  //---- Constantes physiques - source NIST http://physics.nist.gov/
+  //! Return the speed of light in m/s
+  inline static PhysQty SpeedofLight() 
+  { return PhysQty(Units::meter()/Units::second(), 299792458., 0., "Speed of light (c)"); }
+  //! Return the speed of light in m/s
+  inline static PhysQty c() 
+  { return PhysQty::SpeedofLight(); }
+
+  //! Return the Newtonian constant of gravitation in m^3 kg^-1 s^-2 
+  inline static PhysQty G_Newton() 
+  { return PhysQty(Units::meter().power(3)*Units::kilogram().power(-1)*Units::second().power(-2), 
+		   6.67384e-11, 1.2e-4, "Newtonian constant of gravitation (G)"); }
+  //! Return the Newtonian constant of gravitation in m^3 kg^-1 s^-2 
+  inline static PhysQty G() 
+  { return PhysQty::G_Newton(); }
+
+  //! Return the Planck constant in joule.s
+  inline static PhysQty PlanckConstant() 
+  { return PhysQty(Units::joule()*Units::second(), 6.62606957e-34, 4.4e-8, "Planck constant (h)"); }
+  //! Return the Planck constant in joule.s
+  inline static PhysQty h() 
+  { return PhysQty::PlanckConstant(); }
+  //! Return the Planck constant divided by 2 pi (hbar = h/2pi) in joule.s
+  inline static PhysQty hbar() 
+  { return PhysQty(Units::joule()*Units::second(), 6.62606957e-34/2./M_PI, 4.4e-8, "hbar (h/2pi)"); }
+
+  //! Return the Boltzmann constant in joule/K
+  inline static PhysQty BoltzmannConstant() 
+  { return PhysQty(Units::joule()/Units::kelvin(), 1.3806488e-23, 9.1e-7, "Boltzmann constant (k)"); }
+  //! Return the Boltzmann constant in joule/K
+  inline static PhysQty k() 
+  { return PhysQty::BoltzmannConstant(); }
+  //! Return the molar gas constant (R) in joule/mol/K
+  inline static PhysQty MolarGasConstant() 
+  { return PhysQty(Units::joule()/Units::mole()/Units::kelvin(), 8.3144621, 9.1e-7, "Molar gas constant (R)"); }
+  //! Return the molar gas constant (R) in joule/mol/K
+  inline static PhysQty R() 
+  { return PhysQty::MolarGasConstant(); }
+
+  //! Return the Avogadro number (units mol^-1)
+  inline static PhysQty N_Avogradro() 
+  { return PhysQty(Units::mole().power(-1), 6.02214129e23, 4.4e-8, "Avogadro constant (N_A)"); }
+  //! Return the Avogadro number (units mol^-1)
+  inline static PhysQty N_A() 
+  { return PhysQty::N_Avogradro(); }
+
+  //! Return the electric constant in Farad/m 
+  inline static PhysQty epsilon0() 
+  { return PhysQty(Units::farad()/Units::meter(), 8.854187817e-12, 0., "Electric constant (epsilon0)"); }
+  //! Return the magnetic constant in N / A^2 
+  inline static PhysQty mu0() 
+  { return PhysQty(Units::newton()/Units::ampere().power(2), 4.*M_PI*1e-7, 0., "Magnetic constant (mu0)"); }
+
+  //! Return the electron mass in Kg 
+  inline static PhysQty electron_mass()
+  {  return PhysQty(Units::kilogram(), 9.10938291e-31, 4.4e-8, "Electron mass (m_e)"); }
+  //! Return the proton mass in Kg 
+  inline static PhysQty proton_mass()
+  {  return PhysQty(Units::kilogram(), 1.672621777e-27, 4.4e-8, "Proton mass (m_p)"); }
+
+ 
+protected:
+  Units unit_; // Unite de la grandeur physique 
+  r_8 val_;   // Valeur de la grandeur physique dans l'unite unit_
+  r_8 prec_;  // precision relative (1 sigma)
+  string name_;  // Name of the quantity / constant 
+};
+
+/*! operator << overloading - Prints PhysQty on \b os*/
+inline ostream& operator << (ostream& s, PhysQty const & qty)
+{  qty.Print(s,0);  return(s);  }
+
+//! Writes the PhysQty object in the POutPersist stream \b os
+inline POutPersist& operator << (POutPersist& os, PhysQty & obj)
+{ ObjFileIO<PhysQty> fio(&obj);  fio.Write(os);  return(os); }
+//! Reads the PhysQty object from the PInPersist stream \b is 
+inline PInPersist& operator >> (PInPersist& is, PhysQty & obj)
+{ ObjFileIO<PhysQty> fio(&obj); is.SkipToNextObject(); fio.Read(is); return(is); }
+
+
+} // namespace SOPHYA
+
+#endif
Index: trunk/SophyaLib/BaseTools/sversion.h
===================================================================
--- trunk/SophyaLib/BaseTools/sversion.h	(revision 4053)
+++ trunk/SophyaLib/BaseTools/sversion.h	(revision 4056)
@@ -3,6 +3,6 @@
 
 #define SOPHYA_VERSION   2.2
-#define SOPHYA_REVISION  11
-#define SOPHYA_TAG       "V_Nov2011"
+#define SOPHYA_REVISION  22
+#define SOPHYA_TAG       "V_Avr2012"
 
 #endif
