diff --git a/src/yapsut/__init__.py b/src/yapsut/__init__.py
index b8965bab1d40f772a123b013696b959f7ce734e3..708e8b6a827b56f94a494c8d5a877c2bcbc82ac2 100644
--- a/src/yapsut/__init__.py
+++ b/src/yapsut/__init__.py
@@ -17,6 +17,9 @@ from .periodic_stats import periodic_stats, periodic_centroid
 from .stats import CumulativeOfData
 from .colored_noise import gaussian_colored_noise
 
+# planck legacy is under editing
+#from .planck_legacy import cosmological_dipole
+
 #from import .grep
 #import .intervalls
 
diff --git a/src/yapsut/planck_legacy/cgs_blackbody.py b/src/yapsut/planck_legacy/cgs_blackbody.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ed7b3402d8b937c026648bf5c96f68d04abb468
--- /dev/null
+++ b/src/yapsut/planck_legacy/cgs_blackbody.py
@@ -0,0 +1,301 @@
+__DESCRIPTION__=""" 
+CGS       = an object returning the CGS units and constants
+BlackBody = an object returning black body fluxes and conversion facilities
+WMAP_CMB  = a specialized blackbody for CMB using WMAP parameters
+CMB       = a specialized blackbody for CMB using LFI parameters
+
+See: 
+   import blackbody 
+   help(blackbody.CGS)
+   help(blackbody.BlackBody)
+   help(blackbody.CMB)
+
+The package manages numpy.array().
+
+Version 1.1 - 2011 Set 1 - 2012 Apr 5 - 2017 Jun 29 - M.Maris
+"""
+
+class Singleton(object):
+  """
+  Class implementing the Singleton design pattern. There are several ways to implement
+  the singleton pattern in python. The most elegant way is to use the decorators but such
+  construct has been introduced only starting from python 2.6
+  """
+  def __new__(cls, *args, **kwds):
+    if not '_the_instance' in cls.__dict__:
+      cls._the_instance =  object.__new__(cls)
+      cls._the_instance.init(*args, **kwds)
+    return cls._the_instance
+  def init(self, *args, **kwds):
+    pass
+
+class __physical_parameters_cgs(Singleton) :
+   def init(self) :
+      self.K = 1.380658e-16    # erg/K
+      self.c = 2.99792458e10   # cm/sec
+      self.h = 6.6260755e-27   # erg / sec i.e. erg Hz
+      self.flux_Jansky = 1e23  # (cm2 sec cm sterad)/erg * Jansky
+      self.ScaleToMJ = 1.e17   # 1.e23 Jy/erg cm2 sec * 1e-6 MJy/Jy
+   def keys(self) :
+      return self.__dict__.keys()
+   def __call__(self,name) :
+      units = {}
+      units['K'] = 'erg/K'
+      units['c'] = 'cm/sec'
+      units['h'] = 'erg/sec'
+      units['flux_Jansky'] = '(cm2 sec cm sterad)/erg * Jansky'
+      units['ScaleToMJ'] = '1.e23 Jy/erg cm2 sec * 1e-6 MJy/Jy'
+      units['TCMB'] = 'K'
+      return "%s = %e : %s "%(name,self.__dict__[name],units[name])
+CGS=__physical_parameters_cgs()
+
+#class __physical_parameters_mks(Singleton) :
+   #def init(self) :
+      #from release_setup import RELEASE
+      #self.K = RELEASE['K_BOLTZMAN']  # J/K
+      #self.c = RELEASE['SPEED_OF_LIGHT']   # m/sec
+      #self.h = RELEASE['H_PLANCK']   # j / sec i.e. erg Hz
+      #self.flux_Jansky = 1e26  # (cm2 sec cm sterad)/erg * Jansky
+      ##self.ScaleToMJ = 1.e17   # 1.e23 Jy/erg m2 sec * 1e-6 MJy/Jy
+   #def keys(self) :
+      #return self.__dict__.keys()
+   #def __call__(self,name) :
+      #units = {}
+      #units['K'] = 'J/K'
+      #units['c'] = 'm/sec'
+      #units['h'] = 'J/sec'
+      #units['flux_Jansky'] = '(m2 sec m sterad)/J * Jansky'
+      #units['ScaleToMJ'] = '1.e26 Jy/J m2 sec * 1e-6 MJy/Jy'
+      #units['TCMB'] = 'K'
+      #return "%s = %e : %s "%(name,self.__dict__[name],units[name])
+#MKS=__physical_parameters_mks()
+
+class __black_body(Singleton) :
+   def init(self) : 
+      self.ScaleToMJ = CGS.ScaleToMJ
+      return
+   def __call__(self,FreqGHz,T) :
+      import numpy as np
+      return self.bbn_cgs(FreqGHz*1e9,T)*1e23*self.valid(FreqGHz,T)
+   def valid(self,FreqGHz,T) :
+      return (FreqGHz >= 0.) * (T >= 0.)
+   def bbl_cgs(self,Lambda,T) :
+      """
+!
+! BB(lambda,T) thermal radiance function cgs
+!
+! lambda in cm
+!
+! bbl_cgs = erg/(cm2 sec cm sterad)
+!
+"""
+      import numpy as np
+      FT = Lambda*Lambda*Lambda*Lambda*Lambda
+      FT = 2.*CGS.h*CGS.c*CGS.c/FT;
+      ET = np.exp( CGS.h*CGS.c/(Lambda*CGS.K*T) );
+      ET = ET - 1.
+      return FT / ET
+   def bbn_cgs(self,nu,T) :
+      """
+!
+! BB(nu,T) thermal radiance function cgs
+!
+! nu in Hz
+!
+! bbn_cgs = erg/(cm2 sec cm sterad)
+!
+      """
+      import numpy as np
+      FT = nu*nu*nu
+      ET = CGS.c*CGS.c
+      FT = 2.*CGS.h*FT/ET
+      ET = CGS.h*nu/(CGS.K*T)
+      ET = np.exp(ET)
+      ET = ET - 1
+      return FT / ET
+   def bbl_rj_cgs(self,Lambda,T) :
+      """
+!
+! BB thermal radiance function cgs in Rayleight-Jeans approx
+!
+! lambda in cm
+! T in K
+! rj_cgs = erg/(cm2 sec cm sterad)
+!
+      """
+      FT = Lambda*Lambda*Lambda*Lambda
+      return 2.*CGS.K*T*CGS.c/FT 
+   def bbn_rj_cgs(self,nu,T) :
+      """
+!
+! BB thermal radiance function cgs in Rayleight-Jeans approx
+!
+! nu in Hz
+! T in K
+!
+! rj_cgs = erg/(cm2 sec Hz sterad)
+!
+      """
+      FT = (nu/CGS.c)
+      FT = FT*FT
+      return 2.* CGS.K*T*FT
+   def Krj2MJysr(self,nu_ghz,Hz=False) :
+      """generates the conversion factor from K_rj to MJy/sr for a given frequency in GHz (Hz=True to pass it in Hz)"""
+      if Hz :
+         return self.bbn_rj_cgs(nu_ghz,1.)*CGS.ScaleToMJ
+      return self.bbn_rj_cgs(nu_ghz*1e9,1.)*CGS.ScaleToMJ
+   def Tb(self,nu,Bn,FreqGHz=False,MJySr=False) :
+      """returns for a given CGS brightness the correspondiing temperature"""
+      # B=2*h*n^3/c^2 /(exp(h*nu/K/T)-1)
+      # 1/(log( 1/(B/(2*h*nu^3/c^2)+1 )/(h*nu)*K)
+      import numpy as np
+      if FreqGHz : 
+         f=nu*1e9
+      else :
+         f=nu
+      if MJySr :
+         B=Bn/CGS.ScaleToMJ
+      else :
+         B=Bn
+      a=CGS.h*f/(CGS.K*np.log((2*CGS.h*f**3/CGS.c**2)/B+1))
+      return a
+   def bbn_diff(self,nu_ghz,T,Hz=False,MJySr=True) :
+      """
+%
+% [bbn_diff,bbn_diff_ratio]=bbn_diff_mks(nu_hz,T)
+%
+% bbn_diff =  derivative of the BB thermal radiance in mks
+%             for a temperature change
+%
+% bbn_diff_ratio = bbn_diff/bbn
+%
+% nu_hz in Hz
+% T in K
+%
+% bbn_diff_mks = erg/(cm2 sec Hz sterad)/K
+% bbn_diff_ratio = 1/K
+%
+% 1 Jy/sterad = 1e-23 erg/(cm2 sec Hz sterad)
+%
+% the derivative is defines as:
+%
+%     d(Bnu(T))/dT = Bnu(T) X exp(X)/(exp(X)-1) / T
+%
+% the variation is defined as
+%
+%     DeltaBnu(T) = Bnu(T) X exp(X)/(exp(X)-1) DeltaT/ T
+%
+      """
+      import numpy as np
+      if not Hz :
+         _nu=nu_ghz*1e9
+      else :
+         _nu=nu_ghz
+      if MJySr :
+         cf = CGS.ScaleToMJ
+      else :
+         cf = 1.
+      FT = 2.*CGS.h*(_nu**3)/CGS.c**2;
+      X =  CGS.h*_nu/(CGS.K*T);
+      ET = np.exp(X);
+      Lbbn = FT / (ET - 1);
+      FACT = X*ET/(ET-1)/T;
+      return {'bbn_diff':cf*Lbbn*FACT,'bbn_diff_ratio':cf*FACT,'bbn':cf*Lbbn}
+BlackBody=__black_body()
+
+class __cmb_wmap(Singleton) :
+   """CMB parameters for WMAP"""
+   def init(self) :
+      import numpy as np
+      self.Tcmb=2.72548 #Fixsen, D. J. 1999, Volume 707, Issue 2, pp. 916-920 (2009) #2.725 # K 
+      self.DeltaTDipole = 3.3e-3; #K
+      self.sqC2 = np.sqrt(211)*1e-6/np.sqrt(2*(2+1)/(2*np.pi)); #K sqrt of Cl derived from quadrupole moment = l*(l  +1)/(2pi)*Cl
+      self.sqC3 = np.sqrt(1041)*1e-6/np.sqrt(3*(3+1)/(2*np.pi)); #K
+      self.sqC100 = np.sqrt(3032.9299)*1e-6/np.sqrt(100*(100+1)/(2*np.pi)); #K
+      self.source = "Source: WMAP"
+      self.ScaleToMJ=CGS.ScaleToMJ
+   def __call__(self,FreqGHz,MJySr=True) :
+      if MJySr :
+         return BlackBody.bbn_cgs(FreqGHz*1e9,self.Tcmb)*1e23/1e6
+      return BlackBody.bbn_cgs(FreqGHz*1e9,self.Tcmb)
+      #return "Source: WMAP"
+   def fluctuations(self,FreqGHz) :
+      """Return a dictionary with the list of most important cmb components"""
+      D=BlackBody.bbn_diff(FreqGHz*1e9,self.Tcmb,Hz=True);
+      cmbf={}
+      cmbf['FreqGHz'] = FreqGHz;
+      cmbf['Inu'] = D['bbn']/1e-23/1e6;
+      cmbf['dInu_dT'] = D['bbn_diff']/1e-23/1e6;
+      cmbf['dlogInu_dT'] = D['bbn_diff_ratio'];
+      cmbf['Dipole'] = cmbf['dInu_dT']*self.DeltaTDipole;
+      cmbf['sqC2'] = cmbf['dInu_dT']*self.sqC2;
+      cmbf['sqC3'] = cmbf['dInu_dT']*self.sqC3;
+      cmbf['sqC100'] = cmbf['dInu_dT']*self.sqC100;
+      return cmbf
+   def Kcmb2MJysr(self,FreqGHz,TKCMB) :
+      """Converts Kcmb to MJy/sr"""
+      c=BlackBody.bbn_diff(FreqGHz,self.Tcmb)['bbn_diff']
+      return c*TKCMB
+   def MJysr2Kcmb(self,FreqGHz,IMJY_Sr) :
+      """Converts MJy/sr to Kcmb"""
+      c=BlackBody.bbn_diff(FreqGHz,self.Tcmb)['bbn_diff']
+      return IMJY_Sr/c
+   def etaDeltaT(self,FreqGHz) :
+      """Computes EtaDeltaT(nu) (see Eq.(34) of Zacchei et al. (2011), A&A, 536, A5) 
+      defined as (\partial B(\nu,T) / \partial T)_{T=Tcmb} / (2 K \nu^2/c^2)
+      """
+      import numpy as np
+      X=CGS.h*FreqGHz*1e9/(CGS.K*self.Tcmb)
+      eX=np.exp(X)
+      return eX*(X/(eX-1.))**2
+WMAP_CMB=__cmb_wmap()
+
+class __cmb(Singleton) :
+   """CMB parameters for LFI for the current release"""
+   def init(self) :
+      import numpy as np
+      from release_setup import RELEASE
+      self.Tcmb,self.DeltaTDipole =RELEASE.LFI_CMB_PARAMS()
+      self.sqC2 = np.sqrt(211)*1e-6/np.sqrt(2*(2+1)/(2*np.pi)); #K sqrt of Cl derived from quadrupole moment = l*(l  +1)/(2pi)*Cl
+      self.sqC3 = np.sqrt(1041)*1e-6/np.sqrt(3*(3+1)/(2*np.pi)); #K
+      self.sqC100 = np.sqrt(3032.9299)*1e-6/np.sqrt(100*(100+1)/(2*np.pi)); #K
+      self.source = "Source: LFI %s and WMAP for multipoles"%RELEASE.release
+      self.ScaleToMJ=CGS.ScaleToMJ
+   def __call__(self,FreqGHz,MJySr=True) :
+      if MJySr :
+         cf = CGS.ScaleToMJ
+      else :
+         cf = 1.
+      #if MJySr :
+         #return BlackBody.bbn_cgs(FreqGHz*1e9,self.Tcmb)*1e23/1e6
+      return BlackBody.bbn_cgs(FreqGHz*1e9,self.Tcmb)*cf
+   def fluctuations(self,FreqGHz) :
+      """Return a dictionary with the list of most important cmb components"""
+      D=BlackBody.bbn_diff(FreqGHz*1e9,self.Tcmb,Hz=True);
+      cmbf={}
+      cmbf['FreqGHz'] = FreqGHz;
+      cmbf['Inu'] = D['bbn']/1e-23/1e6;
+      cmbf['dInu_dT'] = D['bbn_diff']/1e-23/1e6;
+      cmbf['dlogInu_dT'] = D['bbn_diff_ratio'];
+      cmbf['Dipole'] = cmbf['dInu_dT']*self.DeltaTDipole;
+      cmbf['sqC2'] = cmbf['dInu_dT']*self.sqC2;
+      cmbf['sqC3'] = cmbf['dInu_dT']*self.sqC3;
+      cmbf['sqC100'] = cmbf['dInu_dT']*self.sqC100;
+      return cmbf
+   def Kcmb2MJysr(self,FreqGHz,TKCMB) :
+      """Converts Kcmb to MJy/sr"""
+      c=BlackBody.bbn_diff(FreqGHz,self.Tcmb)['bbn_diff']
+      return c*TKCMB
+   def MJysr2Kcmb(self,FreqGHz,IMJY_Sr) :
+      """Converts MJy/sr to Kcmb"""
+      c=BlackBody.bbn_diff(FreqGHz,self.Tcmb)['bbn_diff']
+      return IMJY_Sr/c
+   def etaDeltaT(self,FreqGHz) :
+      """Computes EtaDeltaT(nu) (see Eq.(34) of Zacchei et al. (2011), A&A, 536, A5) 
+      defined as (\partial B(\nu,T) / \partial T)_{T=Tcmb} / (2 K \nu^2/c^2)
+      """
+      import numpy as np
+      X=CGS.h*FreqGHz*1e9/(CGS.K*self.Tcmb)
+      eX=np.exp(X)
+      return eX*(X/(eX-1.))**2
+CMB=__cmb()
diff --git a/src/yapsut/planck_legacy/cosmological_dipole.py b/src/yapsut/planck_legacy/cosmological_dipole.py
new file mode 100644
index 0000000000000000000000000000000000000000..6258a9783cafa963b5de979fdbf16505e0ccd258
--- /dev/null
+++ b/src/yapsut/planck_legacy/cosmological_dipole.py
@@ -0,0 +1,370 @@
+__DESCRIPTION__="""
+Simulates a cosmological dipole
+"""
+
+from numpy import pi as PI
+from numpy import zeros, cos, sin, array, sqrt, arange
+
+from .cgs_blackbody import CMB
+from .vec3dict import vec3dict
+
+try :
+  from healpy.pixelfunc import pix2ang
+except :
+  print("Warning: no healpy support")
+
+class CosmologicalDipole(object) :
+  def __init__(self,TK,lat_deg,lon_deg,Tcmb=None) :
+    self.Tcmb=2.725 if Tcmb == None else Tcmb*1
+    try :
+       self.TK = TK[0]*1.
+       self.Err_TK = TK[1]*1.
+    except :
+       self.TK = TK*1.
+       self.Err_TK = 0.
+    try :
+       self.lat_deg = lat_deg[0]*1.
+       self.Err_lat_deg = lat_deg[1]*1.
+    except :
+       self.lat_deg = lat_deg*1.
+       self.Err_lat_deg = 0.
+    try :
+       self.long_deg = lon_deg[0]*1.
+       self.Err_long_deg = lon_deg[1]*1.
+    except :
+       self.long_deg = lon_deg*1.
+       self.Err_long_deg = 0.
+    self.long = self.long_deg/180.*PI
+    self.Err_long = self.Err_long_deg/180.*PI
+    self.lat = self.lat_deg/180.*PI
+    self.Err_lat = self.Err_lat_deg/180.*PI
+    self.vers=vec3dict()
+    self.vers['x'] = cos(self.long) * cos(self.lat)
+    self.vers['y'] = sin(self.long) * cos(self.lat)
+    self.vers['z'] = sin(self.lat)
+    vv = 0.
+    for k in ['x','y','z'] :
+      vv += self.vers[k]**2
+    vv = sqrt(vv)
+    for k in ['x','y','z'] :
+      self.vers[k] = self.vers[k]/vv
+    self.Dip = vec3dict()
+    for k in ['x','y','z'] :
+       self.Dip[k] = self.TK*self.vers[k]
+    self.Vsun = vec3dict()
+    for k in ['x','y','z'] :
+       self.Vsun[k] = self.Dip[k]/self.Tcmb
+  def __call__(self,PList) :
+    return self.toi(PList)
+  def amplitude(self,SpinAxis) :
+     import numpy as np
+     return self.TK*np.sin(np.arccos(self.vers['x']*SpinAxis['x']+self.vers['y']*SpinAxis['y']+self.vers['z']*SpinAxis['z']))
+  def TemperatureCMB_K(self) :
+     return self.Tcmb
+  def verErr(self,dx,dy,asArray=False) :
+    from vec3dict import vec3dict
+    vers=vec3dict()
+    vers['x'] = cos(self.long+self.Err_long*dx) * cos(self.lat+self.Err_lat*dy)
+    vers['y'] = sin(self.long+self.Err_long*dx) * cos(self.lat+self.Err_lat*dy)
+    vers['z'] = sin(self.lat+self.Err_lat*dy)
+    if asArray :
+       return array([vers['x'],vers['y'],vers['z']])
+    return vers
+  def cordErr(self,dx,dy,asArray=False,deg=True) :
+    if deg :
+      if asArray :
+         return array([self.long_deg+self.Err_long_deg*dx,self.lat_deg+self.Err_lat_deg*dy])
+      return {'long_deg':self.long_deg+self.Err_long_deg*dx,'lat_deg':self.lat_deg+self.Err_lat_deg*dy}
+    if asArray :
+       return array([self.long+self.Err_long*dx,self.lat+self.Err_lat*dy])
+    return {'long_rad':self.long+self.Err_long*dx,'lat_rad':self.lat+self.Err_lat*dy}
+  def toi(self,PList,Vsun=False) :
+     if Vsun :
+        return self.Vsun['x']*PList['x']+self.Vsun['y']*PList['y']+self.Vsun['z']*PList['z']
+     return self.Dip['x']*PList['x']+self.Dip['y']*PList['y']+self.Dip['z']*PList['z']
+  def quadrupole(self,PListBeamRF) :
+     """Needs pointing list in beam reference frame, with Z the beam center direction
+      This is just a bare approx, do not use for serious calculations
+     """
+     toi=self.toi(PListBeamRF,Vsun=True)
+     return self.TemperatureCMB()*0.5*toi**2
+  def convolution_effect(self,phase,dipole_spin_angle,boresight,dump,coscan_shift,croscan_shift,deg=True) :
+     """computes the effect of convolution causing a shift and a dump of the dipole """
+     import numpy as np
+     out = {'phase':phase,'boresight':boresight,'dipole_spin_angle':dipole_spin_angle,'dump':dump,'coscan_shift':coscan_shift,'croscan_shift':croscan_shift}
+     fact=np.pi/180. if deg else 1.
+     cb=np.cos(boresight*fact)
+     sb=np.sin(boresight*fact)
+     ct=np.cos(dipole_spin_angle*fact)
+     st=np.sin(dipole_spin_angle*fact)
+     cphi=np.cos(phase*fact)
+     out['Aver']=self.TK*ct*cb
+     out['Amp']=self.TK*st*sb
+     out['Var']=out['Amp']*cphi
+     out['Dipole']=out['Aver']+out['Var']
+     cbp=np.cos((boresight+croscan_shift)*fact)
+     sbp=np.sin((boresight+croscan_shift)*fact)
+     cphiP=np.cos((phase+coscan_shift)*fact)
+     out['Aver-cross-scan']=self.TK*ct*cbp
+     out['Amp-cross-scan']=self.TK*st*sbp
+     out['DeltaAver-cross-scan']=self.TK*ct*cbp-out['Aver']
+     out['DeltaAmp-cross-scan']=self.TK*st*sbp-out['Amp']
+     out['Var-coscan']=out['Amp']*cphiP
+     out['DeltaVar-coscan']=out['Var-coscan']-out['Var']
+     out['DipoleConvolved']=dump*(out['Aver-cross-scan']+out['Amp-cross-scan']*cphiP)
+     out['DeltaDipole']=out['DipoleConvolved']-out['Dipole']
+     return out
+  def Map(self,Nside) : 
+    npix = 12*Nside**2
+    ipix = arange(npix,dtype=int)
+    theta,phi = pix2ang(Nside,ipix)
+    x = cos(phi) * sin(theta)
+    y = sin(phi) * sin(theta)
+    z = cos(theta)
+    vv = sqrt(x**2+y**2+z**2)
+    x = x/vv
+    y = y/vv
+    z = z/vv
+    return self.TK*(x*self.vers['x']+y*self.vers['y']+z*self.vers['z'])
+    
+class CosmologicalDipoleGalactic(CosmologicalDipole) :
+  def __init__(self,TK = [3.355e-3,8e-6],lat_deg = [48.26,0.03],lon_deg = [263.99,0.14]) :
+    #CosmologicalDipole.__init__(self,TK = [3.355e-3,8e-6],lat_deg = [48.26,0.03],lon_deg = [263.99,0.14])
+    CosmologicalDipole.__init__(self,TK = TK,lat_deg = lat_deg,lon_deg = lon_deg)
+    self.Source =     """WMAP5 solar system dipole parameters, from: http://arxiv.org/abs/0803.0732"""
+    
+class CosmologicalDipoleEcliptic(CosmologicalDipole) :
+  def __init__(self,TK = 3.355e-3,lat_deg = -11.14128,lon_deg = 171.64904) :
+    CosmologicalDipole.__init__(self,TK = TK,lat_deg = lat_deg,lon_deg = lon_deg)
+    self.Source =     """WMAP5 solar system dipole parameters, from: http://arxiv.org/abs/0803.0732"""
+    
+def wmap5_parameters():
+    """WMAP5 solar system dipole parameters, 
+    from: http://arxiv.org/abs/0803.0732"""
+    # 369.0 +- .9 Km/s
+    SOLSYSSPEED = 369e3
+    ## direction in galactic coordinates
+    ##(d, l, b) = (3.355 +- 0.008 mK,263.99 +- 0.14,48.26deg +- 0.03)
+    SOLSYSDIR_GAL_THETA = np.deg2rad( 90 - 48.26 )
+    SOLSYSDIR_GAL_PHI = np.deg2rad( 263.99 )
+    SOLSYSSPEED_GAL_U = healpy.ang2vec(SOLSYSDIR_GAL_THETA,SOLSYSDIR_GAL_PHI)
+    SOLSYSSPEED_GAL_V = SOLSYSSPEED * SOLSYSSPEED_GAL_U
+    SOLSYSSPEED_ECL_U = gal2ecl(SOLSYSSPEED_GAL_U)
+    SOLSYSDIR_ECL_THETA, SOLSYSDIR_ECL_PHI = healpy.vec2ang(SOLSYSSPEED_ECL_U)
+    ########## /WMAP5
+    return SOLSYSSPEED, SOLSYSDIR_ECL_THETA, SOLSYSDIR_ECL_PHI
+
+
+class DynamicalDipole :
+   def __init__(self,ObsEphemeridsFile,AU_DAY=True,Tcmb=None) :
+      """ephmerids must be either in AU_DAY or KM_SEC
+         set AU_DAY = True if in AU_DAY (default) or False if in KM_SEC
+      """ 
+      from readcol import readcol 
+      import numpy as np
+      import copy
+      from scipy import interpolate
+      import pickle
+      #from matplotlib import pyplot as plt
+      self.Tcmb=2.725 if Tcmb == None else Tcmb*1
+      self.ObsEphemeridsFile=ObsEphemeridsFile
+      try :
+         f=open(ObsEphemeridsFile,'r') 
+      except :
+         print("Error: %s file not foud." % ObsEphemeridsFile)
+         return
+      try :
+         self.eph=pickle.load(f)
+         f.close()
+      except :
+         f.close()
+         eph=readcol(ObsEphemeridsFile,fsep=',',asStruct=True).__dict__
+         self.eph={}
+         for k in ['VY', 'VX', 'seconds', 'Month', 'hours', 'Y', 'Year', 'JD', 'X', 'VZ', 'Z', 'minutes', 'day'] :
+            self.eph[k]=copy.deepcopy(eph[k])
+      self.JD0=self.eph['JD'][0]
+      self.JDMax=self.eph['JD'].max()
+      self.itp={}
+      self.tscale = self.JDMax-self.JD0
+      self.AU_km=149597870.691
+      self.DAY_sec=86400.0  
+      lU=self.AU_km if AU_DAY else 1.
+      lT=self.DAY_sec if AU_DAY else 1.
+      for k in ['X','Y','Z'] :
+         self.itp[k]=interpolate.interp1d((self.eph['JD']-self.eph['JD'][0])/self.tscale,lU*self.eph[k])
+      for k in ['VX','VY','VZ'] :
+         self.itp[k]=interpolate.interp1d((self.eph['JD']-self.eph['JD'][0])/self.tscale,lU/lT*self.eph[k])
+      for k in ['X','Y','Z'] :
+         self.itp['Dip'+k]=interpolate.interp1d((self.eph['JD']-self.eph['JD'][0])/self.tscale,lU/lT*self.TemperatureCMB_K()/self.speed_of_light_kmsec()*self.eph['V'+k])
+   def test(self) :
+      "returns the value for dipole parallel to V, result must be order 30/3e5*2.75 Kcmb"
+      px=self.itp['VX'](0.)
+      py=self.itp['VY'](0.)
+      pz=self.itp['VZ'](0.)
+      v=(px**2+py**2+pz**2)**0.5
+      px*=1/v
+      py*=1/v
+      pz*=1/v
+      return self.Dipole(0.,px,py,pz)
+   def __len__(self) :
+      return len(self.eph('JD'))
+   def speed_of_light_kmsec(self) :
+      return 2.99792458e5
+   def TemperatureCMB_K(self) :
+      return self.Tcmb
+   def pickle(self,filename) :
+      import pickle
+      try :
+         f=open(filename,'w')
+      except :
+         print("Error: %s file not foud." % filename)
+         return
+      pickle.dump(self.eph,f)
+      f.close()
+   def Vel(self,t) :
+      from vec3dict import vec3dict
+      vx=self.itp['DipX'](t)
+      vy=self.itp['DipY'](t)
+      vz=self.itp['DipZ'](t)
+      return vec3dict(vx,vy,vz)
+   def DotVel(self,t,px,py,pz) :
+      vx = self.itp['DipX'](t)
+      vy=self.itp['DipX'](t)
+      vz=self.itp['DipZ'](t)
+      acc = vx*px
+      acc += vy*py
+      acc += vz*pz
+      return acc/((vx**2+vy**2+vz**2)*(px**2+py**2+pz**2))**0.5
+   def VelVersor(self,t) :
+      return self.Vel(t).versor()
+   def DotVelVersor(self,t,px,py,pz) :
+      return self.DotVel(t,px,py,pz)/self.Vel(t).norm()
+   def Dipole(self,t,px,py,pz) :
+      """Returns the DD dipole for given t and p where p = p['x'],p['y'],p['z'] at times t (t = days since JD0)"""
+      acc = self.itp['DipX'](t)*px
+      acc += self.itp['DipY'](t)*py
+      acc += self.itp['DipZ'](t)*pz
+      return acc
+   def __call__(self,JD,p,versor=False) :
+      if versor :
+         return self.Vel((JD-self.JD0)/self.tscale).versor().dot(p)
+      return self.Dipole((JD-self.JD0)/self.tscale,p['x'],p['y'],p['z'])
+
+if __name__=="__main__" :
+   from readcol import readcol
+   from sky_scan import ScanCircle
+   import numpy as np
+   import time
+   DD=DynamicalDipole('../DB/planck_2009-04-15T00:00_2012-08-04T00:00_ssb_1hour.csv')
+   
+   LFIEffectiveBoresightAngles=readcol('../DB/lfi_effective_boresight_angles.csv',asStruct=True,fsep=',').__dict__
+   PointingList=readcol('../DB/ahf_pointings.csv',asStruct=True,fsep=',').__dict__
+   
+   PLL = {}
+   idx = np.where(PointingList['pointID_PSO'] < 90000000)
+   PLL['PID'] = PointingList['pointID_unique'][idx]
+   PLL['JD'] = PointingList['midJD'][idx]
+   PLL['spin_ecl_lat_rad'] = PointingList['spin_ecl_lat'][idx]/180.*np.pi
+   PLL['spin_ecl_lon_rad'] = PointingList['spin_ecl_lon'][idx]/180.*np.pi
+   PLL['spin_x'] = np.cos(PLL['spin_ecl_lon_rad'])*np.cos(PLL['spin_ecl_lat_rad'])
+   PLL['spin_y'] = np.sin(PLL['spin_ecl_lon_rad'])*np.cos(PLL['spin_ecl_lat_rad'])
+   PLL['spin_z'] = np.sin(PLL['spin_ecl_lat_rad'])
+   
+   fh=27
+   beta_rad = LFIEffectiveBoresightAngles['beta_fh'][fh-18]*np.pi/180.
+
+
+   #for iipid in range(10) :
+      #ipid = 1000*iipid
+      
+
+
+   #stats = {}
+   #for k in ['t','d','c'] :
+      #for arg in ['min','max','amp'] :
+         
+   
+   ddmax=np.zeros(len(PLL['JD']))
+   ddmin=np.zeros(len(PLL['JD']))
+   cdmax=np.zeros(len(PLL['JD']))
+   cdmin=np.zeros(len(PLL['JD']))
+   tdmax=np.zeros(len(PLL['JD']))
+   tdmin=np.zeros(len(PLL['JD']))
+   tic = time.time()    
+   SC = ScanCircle(PLL['spin_ecl_lon_rad'][0],PLL['spin_ecl_lat_rad'][0],beta_rad,NSMP=360)
+   SC.generate_circle()
+   Cphi = np.cos(SC.phi)
+   Sphi = np.sin(SC.phi)
+   SumCC=(Cphi*Cphi).sum()
+   SumCS=(Cphi*Sphi).sum()
+   SumSS=(Sphi*Sphi).sum()
+   ArgVSpin = np.zeros(len(PLL['JD']))
+   ArgRSpin = np.zeros(len(PLL['JD']))
+   ArgVR = np.zeros(len(PLL['JD']))
+   ArgVPmax = np.zeros(len(PLL['JD']))
+   ArgVPmin = np.zeros(len(PLL['JD']))
+   for ipid in range(len(PLL['JD'])) :
+      SC = ScanCircle(PLL['spin_ecl_lon_rad'][ipid],PLL['spin_ecl_lat_rad'][ipid],beta_rad,NSMP=360)
+      SC.generate_circle()
+      dd=DD(PLL['JD'][ipid],SC.r)
+
+      t=(PLL['JD'][ipid]-DD.JD0)/DD.tscale
+      
+      #ArgVSpin[ipid]=DD.DotVel((PLL['JD'][ipid]-DD.JD0)/DD.tscale,PLL['spin_x'][ipid],PLL['spin_y'][ipid],PLL['spin_z'][ipid])
+      
+      sx=PLL['spin_x'][ipid]
+      sy=PLL['spin_y'][ipid]
+      sz=PLL['spin_z'][ipid]
+      vx=DD.itp['VX'](t)
+      vy=DD.itp['VY'](t)
+      vz=DD.itp['VZ'](t)
+      rx=DD.itp['X'](t)
+      ry=DD.itp['Y'](t)
+      rz=DD.itp['Z'](t)
+      
+      ArgVSpin[ipid] = 180./np.pi*np.arccos((sx*vx+sy*vy+sz*vz)/(((sx*sx+sy*sy+sz*sz)*(vx*vx+vy*vy+vz*vz))**0.5))
+      ArgRSpin[ipid] = 180./np.pi*np.arccos((sx*rx+sy*ry+sz*rz)/(((sx*sx+sy*sy+sz*sz)*(rx*rx+ry*ry+rz*rz))**0.5))
+      ArgVR[ipid] = 180./np.pi*np.arccos((vx*rx+vy*ry+vz*rz)/(((vx*vx+vy*vy+vz*vz)*(rx*rx+ry*ry+rz*rz))**0.5))
+      
+      dp=180./np.pi*np.arccos((SC.r['x']*vx+SC.r['y']*vy+SC.r['z']*vz)/(((SC.r['x']**2+SC.r['y']**2+SC.r['z']**2)*(vx**2+vy**2+vz**2))**0.5))
+      ArgVPmax[ipid]=dp.max()
+      ArgVPmin[ipid]=dp.min()
+
+
+      #ArgRSpin[ipid]=DD.DotVel((PLL['JD'][ipid]-DD.JD0)/DD.tscale,PLL['spin_x'][ipid],PLL['spin_y'][ipid],PLL['spin_z'][ipid])
+      cd = CosmologicalDipoleEcliptic().toi(SC.r)
+      td=cd+dd
+      ddmax[ipid]=dd.max()
+      ddmin[ipid]=dd.min()
+      cdmax[ipid]=cd.max()
+      cdmin[ipid]=cd.min()
+      tdmax[ipid]=td.max()
+      tdmin[ipid]=td.min()
+   print("Elapsed %e sec",time.time()-tic)
+   
+   import matplotlib.pyplot as plt
+   
+   plt.close('all')
+   plt.figure(1)
+   plt.plot(PLL['PID'],ArgVSpin,'.',label='Spin,Velocity')
+   plt.plot(PLL['PID'],ArgRSpin,'.',label='Spin,Radius')
+   plt.plot(PLL['PID'],ArgVR,'.',label='Radius,Velocity')
+   plt.legend(loc=5)
+   plt.title('Sol.Syst.Bar. Angles')
+   plt.xlabel('PID')
+   plt.ylabel('Angle [deg]')
+   plt.savefig('geometry_angles.png',dpi=300)
+   plt.show()
+      
+   plt.figure(2)
+   plt.plot(PLL['PID'],ArgVPmin,'.',label='min Pointing,Velocity angle')
+   plt.plot(PLL['PID'],ArgVPmax,'.',label='max Pointing,Velocity angle')
+   plt.legend(loc=5)
+   plt.title('Angles between Pointing direction and Velocity')
+   plt.xlabel('PID')
+   plt.ylabel('Angle [deg]')
+   plt.savefig('pointing_velocity_angles_minimax.png',dpi=300)
+   plt.show()
+   
+   
+   
diff --git a/src/yapsut/planck_legacy/time_support.py b/src/yapsut/planck_legacy/time_support.py
new file mode 100644
index 0000000000000000000000000000000000000000..88b62af6f20257ed72ef0b4c9108d47018342454
--- /dev/null
+++ b/src/yapsut/planck_legacy/time_support.py
@@ -0,0 +1,918 @@
+#!/usr/bin//python
+import time
+import datetime
+import struct
+import array
+import os.path
+import sys
+
+import numpy as np
+
+from juldate import juldate as _juldate
+from juldate import caldate as _caldate
+
+"""
+  Module to handle different time scales used by Planck, in particular:
+
+  UTC in ISO and ZULU format by using classes ISO, ZULU
+
+  UTC in seconds by using class UTCsec
+
+  TAI, PsudoOBT, SCET by using the classes TAI, OBT, SCET
+
+  it uses Python modules: time and datetime
+
+  Python ASSUMES UTCsec starts from 1970 Jan 01, 01:00:00.
+
+  Conversions are described by the following conversion ring:
+
+                        ZULU ---  ISO
+                          \        /
+                          JulianDay ------- PseudoOD
+                         /         \
+                        TAI     PseudoOBT
+                         \         /
+                         SCET - UTCsec
+                          
+  where /,\,- denotes interconversion possibility.
+
+  PseudoOBT is OBT calculate ASSUMING 
+    -- onboard clock properly set at zero time
+    -- onboard clock advancing at a constant rate of 1sec/sec
+    -- onboard clodk without drifts.
+
+  Differences between PseudoOBT and true OBT are expected to be of the order of some second.
+
+  Note that since Python Datetime class assumes use of UTCsec, the only method
+  returnin a Datetime object is UTCsec.datetime() use to convert an UTCsec into
+  a Datetime.
+
+  PseudoOD is calculate ASSUMING to count the number of days after the launch epoch.
+  So PseudoOD is interconnected just to JulianDay, since PseudoOD is nothing else than 
+  Julian Day with a different starting time.
+  
+  WARNING OD DEPRECATED:
+     To avoid confusion with the true OD (Level1 OD) which can not be computed but which can be
+  tabulated from AHF the class OD should be avoided. The class OD and JuliandDay-OD conversion
+  methods are DEPRECATED. 
+  
+  USE PseudoOD instead.
+
+  Author: 
+    Michele Maris, Issue 1.0, 30 Mar 2010
+                   Issue 1.1, 14 May 2010 - added management of ODs
+                   Issue 1.2, 25 Jun 2010 - corrected OD zero point
+                                            OD is now deprecated USE PseudoOD instead
+                                            added the possibility to use it as a command lines tool
+"""
+
+class _TIME_SCALE_BASE() :
+   """ base class to handle times: private class
+       for each base: TAI, SCET, PseudoOBT, UTC defines:
+       zero point (example ZERO_TAI) and if needed TICKS number of tickes per second
+
+       It provides methods to recover such quantities,
+       a __str__ method and a set method.
+
+       Basic representation of times is Julian Dates:
+   """
+   ZERO_MJD = _juldate((1858,11,17,12,0,0))
+   ZERO_TAI = _juldate((1958,1,1,0,0,0,0))
+   ZERO_SCET = _juldate((1958,1,1,0,0,0,0))
+   ZERO_UTC = _juldate((1970,1,1,0,0,0,0))
+   ZERO_PseudoOBT = _juldate((1958,1,1,0,0,0,0))
+
+   #ZERO_OD = _juldate((2009,5,14,10,13,00))
+
+   ZERO_OD = _juldate((2009,5,13,13,12,00))
+
+   TICKS_SCET_SEC = 1e6
+   TICKS_PseudoOBT_SEC = float(2**16)
+
+   TICKS_PseudoOBT_DAY = float(86400)*TICKS_PseudoOBT_SEC
+   TICKS_SCET_DAY = float(86400)*TICKS_SCET_SEC
+   TICKS_UTC_DAY = float(86400)
+   TICKS_TAI_DAY = float(86400)
+
+   def __init__(self,v=0.) :
+      """ creator accepts scalars, strings, and lists 
+          
+          scalar (float, int, long): saves the value as double
+
+          list : assumes a tuple of type: (YYYY, MM, DD, HH, MM, SS_DEC) and converts in Julian Day
+
+          string : assumes a string of type: "YYYY-MM-DDTHH:MM:SS.DEC" and converts in Julian Day
+                   if empty is equal to put v = 0
+          use method set(v) to change value to a scalar, time() to return value
+      """
+      if self._isNumericScalar(v) : 
+         self.v = np.float64(v)
+         return
+
+      if type(v) == type(()) or type(v) == type([]) :
+         if len(v) == 3 :
+            self.v = _juldate((v[0],v[1],v[2],0.,0.,0.))
+            return
+         if len(v) == 5 :
+            self.v = _juldate((v[0],v[1],v[2],v[3],v[4],0.))
+            return
+         else :
+            self.v = _juldate(v)
+            return
+     
+      if type(v) == type('') : 
+         if v == '' :
+            self.v = 0
+            return
+         else :
+            self.v = _juldate((float(v[0:4]), float(v[5:7]), float(v[8:10]), float(v[11:13]), float(v[14:16]), float(v[17:len(v)])))
+            return
+
+      print "unrecognized input type"
+      return
+
+   def __str__(self) :
+       return str(self.v)
+
+   def _isNumericScalar(self,v) :
+      tv = type(v)
+      return tv == type(0.) or tv == type(0) or tv == type(long(0)) or tv == type(np.float64(0))
+
+   def _tuple2isostring(self,tp) :
+      """ converts a tuple to an ISO time string """
+      if len(tp) == 6 :
+         return "%04d-%02d-%02dT%02d:%02d:%010.7f" % tp
+      return ""
+
+   def set(self,v) :
+      self.v = float(v)
+
+   def time(self) :
+       return self.v
+
+   def kind(self,test='') :
+       return False
+
+   def zero_tai(self) :
+       return self.__class__.ZERO_TAI
+
+   def zero_utc(self) :
+       return self.__class__.ZERO_UTC
+
+   def zero_pseudoObt(self) :
+       return self.__class__.ZERO_PseudoOBT
+
+   def zero_od(self) :
+       return self.__class__.ZERO_OD
+
+   def step_scet_sec(self) :
+       return 1./self.__class__.TICKS_SCET_SEC
+
+   def step_pseudoObt_sec(self) :
+       return 1./self.__class__.TICKS_PseudoOBT_SEC
+
+class _TIME_SCALE_PART(_TIME_SCALE_BASE) :
+    """ base class to handle times divided into two parts: 
+        - a coarse part (long)
+        - a fine part (double)
+    """
+    def __init__(self,coarse=0,fine=-1.) :
+       if fine < 0 :
+          self.coarse = floor(coarse)
+          self.fine   = coarse-self.coarse
+       else :
+          self.coarse = coarse
+          self.fine   = fine
+
+    def tuple(self) :
+       """ returns a tuple """
+       return (self.coarse, self.fine)
+
+    def __str__(self,sept=':') :
+       return "%s%s%s" % (self.coarse,sept,self.fine)
+
+    def getTime(self,fine_ticks_sec=1.) :
+       """ getTime([ticks_fine=1.]) combines coarse and fine part into a float 
+           getTime = float(coarse)+self_fine/float(fine_ticks_sec)
+       """
+       return self.coarse+self.fine/float(fine_ticks_sec)
+
+class _TIME_SCALE_STRING(_TIME_SCALE_BASE) : 
+   """ base class to handle times in form of strings """
+   def __init__(self,v='') :
+      self.v=str(v)
+
+   def __str__(self) :
+       return str(self.v)
+
+   def set(self,v) :
+      self.v=str(v)
+
+
+class CalendarDate(_TIME_SCALE_BASE) :
+   def __init__(self,v) :
+      if type(v) == type(()) or type(v) == type([]) :
+         if len(v) == 3 :
+            self.v = (long(v[0]),long(v[1]),long(v[2]),long(0),long(0),float(0.))
+            return
+         if len(v) == 5 :
+            self.v = (long(v[0]),long(v[1]),long(v[2]),long(v[3]),long(v[4]),float(0.))
+            return
+         else :
+            self.v = v
+            return
+         print "unrecongnized ntuple format ",v
+         return 
+
+      if type(v) == type('') : 
+         if v == '' :
+            self.v = (long(0), long(0), long(0), long(0), long(0), float(0.))
+            return
+         else :
+            self.v = ((long(v[0:4]), long(v[5:7]), long(v[8:10]), long(v[11:13]), long(v[14:16]), float(v[17:len(v)])))
+            return
+         print "unrecognized string format ",v
+         return 
+
+      if type(v) == type(JulianDay(0.)) :
+         self.v=_caldate(v.v)
+
+      print "unrecognized format ",v
+      return 
+
+   def kind(self,test='') :
+      """ returns kind of object """
+      if test == '' :
+          return 'CalendarDate'
+      return test == 'CalendarDate'
+
+   def julianday(self) :
+      """ conversion to julian day """
+      return JulianDay(self.v)
+
+   def iso(self) :
+      """ Conversion in ISO format """
+      return ISO(self._tuple2isostring(self.v))
+
+   def zulu(self) :
+      """ Conversion in ISO format """
+      return ISO(self._tuple2isostring(self.v)).zulu()
+
+   def tuple(self) :
+      """ returns the tuple """
+      return self.v
+
+class ISO(_TIME_SCALE_STRING) : 
+   """ class to handle times in form of ISO strings YYYY-MM-DDTHH:MM:SS   """
+   def kind(self,test='') :
+      """ returns kind of object """
+      if test == '' :
+          return 'ISO'
+      return test == 'ISO'
+
+   def julianday(self) :
+      """ returns Julian Day """
+      return JulianDay(self.v)
+
+   def calendardate(self) :
+      """ returns the calendar date """
+      return CalendarDate(self.v)
+
+   def tuple(self) : 
+      """ returns the tuple for the date"""
+      return (long(self.v[0:4]), long(self.v[5:7]), long(self.v[8:10]), long(self.v[11:13]), long(self.v[14:16]), float(self.v[17:len(self.v)]))
+
+   def zulu(self) :
+      """ returns Zulu """
+      return ZULU(self.v+'Z')
+
+class ZULU(_TIME_SCALE_STRING) : 
+   """ class to handle times in form of ISO ZULU strings YYYY-MM-DDTHH:MM:SSZ  """
+   def __init__(self,v='Z') :
+      _TIME_SCALE_STRING.__init__(self,v)
+      if not (self.v[len(self.v)-1] == 'Z') :
+         self.v=self.v+'Z'
+
+   def kind(self,test='') :
+      """ returns kind of object """
+      if test == '' :
+          return 'ZULU'
+      return test == 'ZULU'
+
+   def julianday(self) :
+      """ returns Julian Day """
+      return JulianDay(self.v[0:(len(self.v)-1)])
+
+   def calendardate(self) :
+      """ returns the calendar date """
+      return self.iso().calendardate()
+
+   def tuple(self) : 
+      """ returns the tuple for the date"""
+      return (long(self.v[0:4]), long(self.v[5:7]), long(self.v[8:10]), long(self.v[11:13]), long(self.v[14:16]), long(self.v[17:(len(self.v)-1)]))
+
+   def iso(self) :
+      """ returns Zulu """
+      return ISO(self.v[0:(len(self.v)-1)])
+
+class JulianDay(_TIME_SCALE_BASE) :
+   """ class to handle JulianDay """
+   def kind(self,test='') :
+      if test == '' :
+         return 'JulianDay'
+      return test == 'JulianDay'
+
+   def pseudoObt(self) :
+      return PseudoOBT((self.v-self.__class__.ZERO_PseudoOBT)*self.__class__.TICKS_PseudoOBT_DAY)
+
+   def utcsec(self) :
+      return UTCsec((self.v-self.__class__.ZERO_UTC)* self.__class__.TICKS_UTC_DAY)
+
+   def scet(self) :
+      return SCET((self.v-self.__class__.ZERO_SCET)* self.__class__.TICKS_SCET_DAY)
+
+   def tai(self) :
+      return TAI((self.v-self.__class__.ZERO_TAI)* self.__class__.TICKS_TAI_DAY)
+
+   def calendardate(self) :
+      return CalendarDate(_caldate(self.v))
+
+   def tuple(self) :
+      return CalendarDate(_caldate(self.v)).tuple()
+
+   def iso(self) : 
+       return ISO("%04d-%02d-%02dT%02d:%02d:%010.7f" % _caldate(self.v))
+
+   def zulu(self) : 
+       return ZULU("%04d-%02d-%02dT%02d:%02d:%010.7f" % _caldate(self.v))
+
+   def od(self) :
+      return OD(self.v - self.__class__.ZERO_OD)
+
+   def pseudoOd(self) :
+      return PseudoOD(self.v - self.__class__.ZERO_OD)
+
+class OD(_TIME_SCALE_BASE) :
+   """ class to handle OD 
+       (a different way to handle a Julian Day)
+       Note, the only operations allowed are: JulianDay <-> OD conversions
+       
+       DEPRECATED 
+          This class is deprecated, use PseudoOD instead
+   """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      if self.v < 0. :
+         print "Waning: negative od"
+
+   def kind(self,test='') :
+      if test == '' :
+         return 'OD'
+      return test == 'OD'
+
+   def julianday(self) :
+      return JulianDay( self.v+self.__class__.ZERO_OD)
+
+   def pseudoObt(self) :
+      return 
+
+   def utcsec(self) :
+      return 
+
+   def scet(self) :
+      return 
+
+   def tai(self) :
+      return 
+
+   def calendardate(self) :
+      return 
+
+   def tuple(self) :
+      return 
+
+   def iso(self) : 
+       return 
+
+   def zulu(self) : 
+       return 
+
+class PseudoOD(_TIME_SCALE_BASE) :
+   """ class to handle PseudoOD 
+       (a different way to handle a Julian Day)
+       Note, the only operations allowed are: JulianDay <-> PseudoOD conversions
+   """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      if self.v < 0. :
+         print "Waning: negative od"
+
+   def kind(self,test='') :
+      if test == '' :
+         return 'PseudoOD'
+      return test == 'PseudoOD'
+
+   def julianday(self) :
+      return JulianDay( self.v+self.__class__.ZERO_OD)
+
+   def pseudoObt(self) :
+      return 
+
+   def utcsec(self) :
+      return 
+
+   def scet(self) :
+      return 
+
+   def tai(self) :
+      return 
+
+   def calendardate(self) :
+      return 
+
+   def tuple(self) :
+      return 
+
+   def iso(self) : 
+       return 
+
+   def zulu(self) : 
+       return 
+
+class PseudoOBT(_TIME_SCALE_BASE) :
+   """ class to handle PseudoOBT : in 2^-16 seconds since 1958 Jan 01, 00:00:00 
+       
+       PseudoOBT is OBT calculate ASSUMING 
+         -- onboard clock properly set at zero time
+         -- onboard clock advancing at a constant rate of 1sec/sec
+         -- onboard clodk without drifts.
+
+       Differences between PseudoOBT and true OBT are expected to be of the order of some second.
+   """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      # if v is not a numeric scalar then v has been coded as a JD and it has to be converted
+      if not self._isNumericScalar(v) :
+         self.v = (self.v - self.ZERO_PseudoOBT)*self.TICKS_PseudoOBT_DAY
+         
+   def kind(self,test='') :
+      if test == '' :
+         return 'PseudoOBT'
+      return test == 'PseudoOBT'
+
+   def utcsec(self) :
+      return UTCsec((self.v/self.__class__.TICKS_PseudoOBT_DAY+self.__class__.ZERO_PseudoOBT-self.__class__.ZERO_UTC)* self.__class__.TICKS_UTC_DAY)
+
+   def scet(self) :
+      return SCET((self.v/self.__class__.TICKS_PseudoOBT_DAY+self.__class__.ZERO_PseudoOBT-self.__class__.ZERO_SCET)*self.__class__.TICKS_SCET_DAY)
+
+   def tai(self) :
+      return TAI( (self.v/self.__class__.TICKS_PseudoOBT_DAY+self.__class__.ZERO_PseudoOBT-self.__class__.ZERO_TAI)*self.__class__.TICKS_TAI_DAY)
+
+   def julianday(self) :
+      return JulianDay( (self.v/self.__class__.TICKS_PseudoOBT_DAY+self.__class__.ZERO_PseudoOBT))
+
+   def iso(self) :
+      return self.julianday().iso()
+    
+   def zulu(self) :
+      return self.julianday().zulu()
+
+
+class UTCsec(_TIME_SCALE_BASE) :
+   """ class to handle UTC times in seconds since 1970 Jan 01, 00:00:00 """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      # if v is not a numeric scalar then v has been coded as a JD and it has to be converted
+      if not self._isNumericScalar(v) :
+         self.v = (self.v - self.ZERO_UTC)*86400
+
+   def kind(self,test='') :
+      if test == '' :
+          return 'UTCsec'
+      return test == 'UTCsec'
+
+   def datetime(self) :
+      """ Returns a Datetime object from UTCsec """
+      return datetime.datetime.fromtimestamp(self.v,None)
+
+   def scet(self) :
+      return SCET( (self.v/self.__class__.TICKS_UTC_DAY+self.__class__.ZERO_UTC-self.__class__.ZERO_SCET) * self.__class__.TICKS_SCET_DAY )
+
+   def tai(self) :
+      return TAI( (self.v/self.__class__.TICKS_UTC_DAY+self.__class__.ZERO_UTC-self.__class__.ZERO_TAI)*self.__class__.TICKS_TAI_DAY )
+
+   def julianday(self) :
+      return JulianDay( (self.v/self.__class__.TICKS_UTC_DAY+self.__class__.ZERO_UTC))
+
+   def pseudoObt(self) :
+      return PseudoOBT((self.v/self.__class__.TICKS_UTC_DAY+self.__class__.ZERO_UTC-self.__class__.ZERO_PseudoOBT)*self.__class__.TICKS_PseudoOBT_DAY)
+
+   def iso(self) :
+      return self.julianday().iso()
+    
+   def zulu(self) :
+      return self.julianday().zulu()
+
+
+class SCET(_TIME_SCALE_BASE) :
+   """ class to handle SCET : in microseconds since 1958 Jan 01, 00:00:00 """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      # if v is not a numeric scalar then v has been coded as a JD and it has to be converted
+      if not self._isNumericScalar(v) :
+         self.v = (self.v - self.__class__.ZERO_SCET)*self.__class__.TICKS_SCET_DAY
+
+   def kind(self,test='') :
+       if test == '' :
+           return 'SCET'
+       return test == 'SCET'
+
+   def tai(self) :
+      return TAI( (self.v/self.__class__.TICKS_SCET_DAY+self.__class__.ZERO_SCET-self.__class__.ZERO_TAI) * self.__class__.TICKS_TAI_DAY )
+
+   def julianday(self) :
+      return JulianDay( (self.v/self.__class__.TICKS_SCET_DAY+self.__class__.ZERO_SCET))
+
+   def pseudoObt(self) :
+      return PseudoOBT((self.v/self.__class__.TICKS_SCET_DAY+self.__class__.ZERO_SCET-self.__class__.ZERO_PseudoOBT)*self.__class__.TICKS_PseudoOBT_DAY)
+
+   def utcsec(self) :
+      return UTCsec( (self.v/self.__class__.TICKS_SCET_DAY+self.__class__.ZERO_SCET-self.__class__.ZERO_UTC)*self.__class__.TICKS_UTC_DAY )
+
+   def iso(self) :
+      return self.julianday().iso()
+    
+   def zulu(self) :
+      return self.julianday().zulu()
+
+
+
+class TAI(_TIME_SCALE_BASE) :
+   """ class to handle TAI : same than UTC but from 1958 Jan 01, 00:00:00 """
+   def __init__(self,v=0.) :
+      _TIME_SCALE_BASE.__init__(self,v)
+      # if v is not a numeric scalar then v has been coded as a JD and it has to be converted
+      if not self._isNumericScalar(v) :
+         self.v = (self.v - self.__class__.ZERO_TAI)*self.__class__.TICKS_TAI_DAY
+
+   def kind(self,test='') :
+      if test == '' :
+         return 'TAI'
+      return test == 'TAI'
+
+   def julianday(self) :
+      return JulianDay( (self.v/self.__class__.TICKS_TAI_DAY+self.__class__.ZERO_TAI))
+
+   def pseudoObt(self) :
+      return PseudoOBT((self.v/self.__class__.TICKS_TAI_DAY+self.__class__.ZERO_TAI-self.__class__.ZERO_PseudoOBT)*self.__class__.TICKS_PseudoOBT_DAY)
+
+   def utcsec(self) :
+      return UTCsec( (self.v/self.__class__.TICKS_TAI_DAY+self.__class__.ZERO_TAI-self.__class__.ZERO_UTC)*self.__class__.TICKS_UTC_DAY )
+
+   def scet(self) :
+      return SCET( (self.v/self.__class__.TICKS_TAI_DAY+self.__class__.ZERO_TAI-self.__class__.ZERO_SCET) * self.__class__.TICKS_SCET_DAY )
+
+   def iso(self) :
+      return self.julianday().iso()
+    
+   def zulu(self) :
+      return self.julianday().zulu()
+
+
+
+def _TEST_time_support() :
+   """ test and examples """
+
+   x = JulianDay(2400000.5)
+   print
+   print x.kind(),x, "input ad number "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.calendardate().kind()),x.calendardate()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+
+   x = JulianDay((1858,11,17,0,0,0))
+   print
+   print x.kind(),x,"input as tuple "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.calendardate().kind()),x.calendardate()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+
+   x = JulianDay("1858-11-17T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.calendardate().kind()),x.calendardate()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+
+   x = PseudoOBT(0)
+   print
+   print x.kind(),x,"input as number  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+
+
+   x = PseudoOBT((1958,1,1,0,0,0))
+   print
+   print x.kind(),x,"input as tuple  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+
+
+   x = PseudoOBT("1958-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+
+
+   x = UTCsec(0)
+   print
+   print x.kind(),x,"input as number  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+
+
+   x = UTCsec((1970,1,1,0,0,0))
+   print
+   print x.kind(),x,"input as tuple  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+
+
+   x = UTCsec("1970-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+
+
+   x = SCET(0)
+   print
+   print x.kind(),x,"input as number  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+
+
+   x = SCET((1970,1,1,0,0,0))
+   print
+   print x.kind(),x,"input as tuple  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+
+
+   x = SCET("1970-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.tai().kind()),x.tai()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+
+
+   x = TAI(0)
+   print
+   print x.kind(),x,"input as number  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+
+
+   x = TAI((1970,1,1,0,0,0))
+   print
+   print x.kind(),x,"input as tuple  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+
+
+   x = TAI("1970-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.pseudoObt().kind()),x.pseudoObt()
+   print " %10s -> %10s : " % (x.kind(),x.utcsec().kind()),x.utcsec()
+   print " %10s -> %10s : " % (x.kind(),x.scet().kind()),x.scet()
+
+
+   x = ISO("1970-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.calendardate().kind()),x.calendardate()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+
+   x = ZULU("1970-01-01T00:00:00")
+   print
+   print x.kind(),x,"input as string  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.calendardate().kind()),x.calendardate()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+
+   x = CalendarDate((1970,1,1,0,0,0.))
+   print
+   print x.kind(),x,"input as tuple  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+
+   x = CalendarDate((2009,5,14,10,13,0.)).julianday()
+   print
+   print x.kind(),x,"input as scalar  "
+   print " %10s -> %10s : " % (x.kind(),x.iso().kind()),x.iso()
+   print " %10s -> %10s : " % (x.kind(),x.zulu().kind()),x.zulu()
+ #  print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),type(x.tuple())),x.tuple()
+   print " %10s -> %10s : " % (x.kind(),x.od().kind()),x.od()
+
+   x = CalendarDate((2009,5,14,10,13,0.)).julianday().od()
+   print
+   print x.kind(),x,"input as scalar  "
+   print " %10s -> %10s : " % (x.kind(),x.julianday().kind()),x.julianday()
+   print " %10s -> %10s : " % (x.kind(),x.julianday().calendardate().kind()),x.julianday().calendardate()
+
+# end
+#_TEST_time_support()
+
+if __name__ == '__main__' :
+   # creates the obj by od database
+   import os
+   import sys
+   import shutil
+   from optparse import OptionParser
+
+   class _CmdLine() :
+      def __init__(self) :
+         self.ArgList = ['in','out']
+         
+         cmdln = OptionParser(usage="usage: %prog [options] "+
+            " ".join(self.ArgList)
+            +"[options]",version='1.0 - 2010 Jun 25 - M.Maris')
+         cmdln.add_option("-d","--dry-run",dest="DryRun", action = 'store_true',default=False,help='Performs a dry run')
+         cmdln.add_option("-T","--test",dest="ACTION_TEST", action = 'store_true',default=False,help='run a test')
+         
+         (self.Options,self.Args) = cmdln.parse_args()
+         
+         if len(self.Args) != len(self.ArgList) and not self.Options.ACTION_TEST :
+            print
+            print "TIME_SUPPORT "
+            cmdln.print_version()
+            cmdln.print_help()
+            print
+            print "Allowed codes for times (not case sensitive): "
+            print "   ISO, ZULU, JD, SCET, TAI, PseudoOBT, PseudoOD"
+            print
+            print "Example:"
+            print "   > time_support.py PseudoOD=0 ISO "
+            print "   2009-05-14T13:11:59.9999839"
+            print "   > time_support.py PseudoOD=0 Z "
+            print "   2009-05-14T13:11:59.9999839Z"
+            print
+            sys.exit(1)
+         else :
+            if len(self.Args) > 0 :
+               self.IN = self.Args[0]
+               self.OUT = self.Args[1]
+            else :
+               self.IN = ""
+               self.OUT = ""
+               
+            if len(self.IN) == 0 :
+               self.IN_TYPE = ''
+               self.IN_VALUE = ''
+            else :
+               ll = self.IN.split('=')
+               if len(ll) != 2 :
+                  sys.exit(1)
+               else :
+                  self.IN_TYPE = ll[0]
+                  self.IN_VALUE = ll[1]
+            self.DryRun()
+      
+      def DryRun(self) :
+         if self.Options.DryRun :
+            print "Dry Run\nExit\n"
+            sys.exit(1)
+   
+   
+   # execution of commands
+   cmdline = _CmdLine()
+   if cmdline.Options.ACTION_TEST :
+      _TEST_time_support()
+      sys.exit(1)
+   
+   JD = None
+   if cmdline.IN_TYPE.lower() == 'ISO'.lower() :
+      JD = JulianDay(cmdline.IN_VALUE) 
+      
+   if cmdline.IN_TYPE.lower() == 'ZULU'.lower() :
+      JD = ZULU(cmdline.IN_VALUE).julianday()
+      
+   if cmdline.IN_TYPE.lower() == 'JD'.lower() :
+      JD = JulianDay(float(cmdline.IN_VALUE))
+   
+   if cmdline.IN_TYPE.lower() == 'PseudoOBT'.lower() :
+      JD = PseudoOBT(float(cmdline.IN_VALUE)).julianday()
+   
+   if cmdline.IN_TYPE.lower() == 'TAI'.lower() :
+      JD = TAI(float(cmdline.IN_VALUE)).julianday()
+   
+   if cmdline.IN_TYPE.lower() == 'SCET'.lower() :
+      JD = SCET(float(cmdline.IN_VALUE)).julianday()
+   
+   if cmdline.IN_TYPE.lower() == 'PseudoOD'.lower() :
+      JD = OD(float(cmdline.IN_VALUE)).julianday()
+
+   if JD == None :
+      print "Unknown input type"
+      
+   if cmdline.OUT.lower() == 'ISO'.lower() :
+      print JD.iso()
+      sys.exit(1)
+   
+   if cmdline.OUT.lower() == 'PseudoOBT'.lower() :
+      print JD.pseudoObt()
+      sys.exit(1)
+   
+   if cmdline.OUT.lower() == 'TAI'.lower() :
+      print JD.tai()
+      sys.exit(1)
+   
+   if cmdline.OUT.lower() == 'SCET'.lower() :
+      print JD.scet()
+      sys.exit(1)
+   
+   if cmdline.OUT.lower() == 'ZULU'.lower() :
+      print JD.zulu()
+      sys.exit(1)
+   
+   if cmdline.OUT.lower() == 'PseudoOD'.lower() :
+      print JD.od()
+      sys.exit(1)
+      
+   if cmdline.OUT.lower() == 'JD'.lower() :
+      print JD.v
+      sys.exit(1)
+   
+   print "Unknown output type"
+   
diff --git a/src/yapsut/planck_legacy/vec3dict.py b/src/yapsut/planck_legacy/vec3dict.py
new file mode 100644
index 0000000000000000000000000000000000000000..95596066511a7b145deae4198c19015bf896a514
--- /dev/null
+++ b/src/yapsut/planck_legacy/vec3dict.py
@@ -0,0 +1,320 @@
+import numpy as _np
+class vec3dict :
+   """ handles a 3d vector both as a dictionary and an indexed array """
+   def __init__(self,*karg) :
+      """ vec3dict() : empty vector 3d (Values are None)
+          vec3dict(0) : vector 3d with all the elements [int(0), int(0), int(0)]
+          vec3dict(5) : vector 3d with all the elements int(5)
+          vec3dict(1,3,5) : vector 3d with all elements [int(1), int(3), int(5)]
+          vec3dict('x') : vector 3d [1.,0.,0.]
+      """
+      import numpy as np
+      self.v=[None,None,None]
+      if len(karg) == 0 :
+         return 
+      if type(karg[0]) == type('') :
+         self.v=[0.,0.,0.]
+         if karg[0] == 'x' or karg[0] == 'X' :
+            self.v[0]=1.
+         elif karg[0] == 'y' or karg[0] == 'Y' :
+            self.v[1]=1.
+         elif karg[0] == 'z' or karg[0] == 'Z' :
+            self.v[2]=1.
+         else :
+            raise Exception('invalid versor name')
+         self.v=np.array(self.v)
+         return
+      if type(karg[0]) == type(vec3dict()) :
+         self.v[0] = karg[0][0]
+         self.v[1] = karg[0][1]
+         self.v[2] = karg[0][2]
+         self.v=np.array(self.v)
+         return
+      if len(karg) < 3 :
+         for k in range(3) :
+            self.v[k]=karg[0]
+         self.v=np.array(self.v)
+      else :
+         self.v[0]=karg[0]
+         self.v[1]=karg[1]
+         self.v[2]=karg[2]
+         self.v=np.array(self.v)
+   def name2index(self,key):
+      "return the index for a given component name"
+      if key=='x' :
+         return 0
+      elif key=='y' :
+         return 1
+      elif key=='z' :
+         return 2
+      else :
+         raise Exception('invalid keyword')
+   def index2name(self,idx):
+      "return the name for a given component index"
+      try :
+         return ['x','y','z'][idx]
+      except :
+         raise Exception('invalid index')
+   def ismybrother(self,that) :
+      return that.__class__.__name__ == self.__class__.__name__ 
+   def __len__(self) :
+      try :
+         return self.v.shape[1]
+      except :
+         return 1
+   def linterp(self,t,left=-_np.inf,right=_np.inf,noTest=False) :
+      import numpy as np
+      from scipy import interpolate
+      if noTest :
+         it=np.array(np.floor(t),dtype='int')
+         dt=t-it
+         x=(self['x'][it+1]-self['x'][it])*dt+self['x'][it]
+         y=(self['y'][it+1]-self['y'][it])*dt+self['y'][it]
+         z=(self['z'][it+1]-self['z'][it])*dt+self['z'][it]
+         return vec3dict(x,y,z)
+      x=np.zeros(t.shape)
+      y=np.zeros(t.shape)
+      z=np.zeros(t.shape)
+      it=np.array(np.floor(t),dtype='int')
+      idx=np.where(it < 0)[0]
+      if len(idx) > 0 :
+         x[idx]=left
+         y[idx]=left
+         z[idx]=left
+      idx=np.where(it > len(self)-1)[0]
+      if len(idx) > 0 :
+         x[idx]=right
+         y[idx]=right
+         z[idx]=right
+      idx=np.where(it == len(self)-1)[0]
+      if len(idx) > 0 :
+         x[idx]=self['x'][-1]
+         y[idx]=self['x'][-1]
+         z[idx]=self['x'][-1]
+      idx=np.where((0<=it)*(it<len(self)-1))[0]
+      if len(idx) > 0 :
+         dt=t[idx]-it[idx]
+         it=it[idx]
+         x[idx]=(self['x'][it+1]-self['x'][it])*dt+self['x'][it]
+         y[idx]=(self['y'][it+1]-self['y'][it])*dt+self['y'][it]
+         z[idx]=(self['z'][it+1]-self['z'][it])*dt+self['z'][it]
+      return vec3dict(x,y,z)
+   def argslice(self,idx) :
+      out=vec3dict()
+      out['x']=self['x'][idx]
+      out['y']=self['y'][idx]
+      out['z']=self['z'][idx]
+      return out
+   def __getitem__(self,idx) :
+      import numpy as np
+      if (idx.__class__ == np.zeros(2).__class__) :
+         return self.argslice(idx)
+      try :
+         idx = int(idx)
+         try :
+            return self.v[idx]
+         except :
+            raise Exception('out of bounds')
+      except :
+         if idx=='x' :
+            i=0
+         elif idx=='y' :
+            i=1
+         elif idx=='z' :
+            i=2
+         else :
+            raise Exception('invalid keyword')
+         return self.v[i]
+   def __setitem__(self,idx,that) :
+      try :
+         idx = int(idx)
+         try :
+            self.v[idx] = that
+         except :
+            raise Exception('out of bounds')
+      except :
+         if idx=='x' :
+            i=0
+         elif idx=='y' :
+            i=1
+         elif idx=='z' :
+            i=2
+         else :
+            raise Exception('invalid keyword')
+         self.v[i] = that
+   def __add__(self,that) :
+      new = vec3dict(self)
+      if self.ismybrother(that):
+         for k in range(3) :
+            new.v[k]+=that[k]
+      else :
+         for k in range(3) :
+            new.v[k]+=that
+      return new
+   def __sub__(self,that) :
+      new = vec3dict(self)
+      if self.ismybrother(that) :
+         for k in range(3) :
+            new.v[k]-=that[k]
+      else :
+         for k in range(3) :
+            new.v[k]-=that
+      return new
+   def __div__(self,that) :
+      new = vec3dict(self)
+      if not self.ismybrother(that) :
+         for k in range(3) :
+            new.v[k]=new.v[k]/that
+      else :
+         raise Exception('right side not a scalar')
+      return new
+   def __mul__(self,that) :
+      if not self.ismybrother(that) :
+         new = vec3dict(self)
+         for k in range(3) :
+            new.v[k]*=that
+         return new
+      else :
+         raise Exception('right side not a scalar')
+   def __rmul__(self,that) :
+      if not self.ismybrother(that) :
+         new = vec3dict(self)
+         for k in range(3) :
+            new.v[k]*=that
+         return new
+      else :
+         raise Exception('left side not a scalar')
+   def __neg__(self) :
+      return vec3dict(-self.v[0],-self.v[1],-self.v[2])
+   def __str__(self) :
+      return 'x : '+str(self.v[0])+', y : '+str(self.v[1])+', z : '+str(self.v[2])
+   def mul_by_array(self,that) :
+      """
+         multiplies by an array, component by component
+         it is used as an example to generate a multicomponent vec3dict
+         Example:
+            arange(10)*vec3dict(1,0,0) 
+         will result in a list of vec3dict objects with one component, while
+            vec3dict(1,0,0).by_array(arange(10)) 
+         will result in a single vec3dict objects with 10 elements in each column
+         BeWare: the resulting Vec3Dict is not granted to work with all the methods
+      """
+      return vec3dict(self.v[0]*that,self.v[1]*that,self.v[2]*that)
+   def add_array(self,that) :
+      """
+         add an array, component by component
+         it is used as an example to generate a multicomponent vec3dict
+         Example:
+            arange(10)+vec3dict(1,0,0) 
+         will result in an error
+            vec3dict(1,0,0).add_array(arange(10)) 
+         will result in a single vec3dict objects with 10 elements in each column
+         which are the sum of 
+            vec3dict(1,0,0)['x'], vec3dict(1,0,0)['y'], vec3dict(1,0,0)['z']
+         with the array
+      """
+      return vec3dict(self.v[0]+that,self.v[1]+that,self.v[2]+that)
+   def dot(self,that) :
+      """ dot product """
+      if not self.ismybrother(that) :
+         raise Exception('right side not a vector')
+      else :
+         return self.v[0]*that.v[0]+self.v[1]*that.v[1]+self.v[2]*that.v[2]
+   def norm(self) :
+      """ returns the norm """
+      return (self.v[0]*self.v[0]+self.v[1]*self.v[1]+self.v[2]*self.v[2])**0.5
+   def keys(self) :
+      """ return names of elements """
+      return ['x','y','z']
+   def array(self,dtype=None) :
+      """ returns an array """
+      from numpy import array
+      if dtype == None :
+         return array(self.v)
+      return array(self.v,dtype=dtype)
+   def dict(self) :
+      """ returns a dictionary """
+      return {'x':self.v[0],'y':self.v[1],'z':self.v[2]}
+   def ext(self,that) :
+      if not self.ismybrother(that) :
+         raise Exception('right side not a vector')
+      else :
+         new = vec3dict(0)
+         new[0]=self.v[1]*that.v[2]-self.v[2]*that.v[1]
+         new[1]=-self.v[0]*that.v[2]+self.v[2]*that.v[0]
+         new[2]=self.v[0]*that.v[1]-self.v[1]*that.v[0]
+         return new
+   def norm_ext(self,that) :
+      "norm of an external product"
+      if not self.ismybrother(that) :
+         raise Exception('right side not a vector')
+      else :
+         new=(self.v[1]*that.v[2]-self.v[2]*that.v[1])**2
+         new+=(self.v[0]*that.v[2]-self.v[2]*that.v[0])**2
+         new+=(self.v[1]*that.v[0]-self.v[0]*that.v[1])**2
+         return new**0.5
+   def angle(self,that) :
+      "angle between two vectors, radiants"
+      import numpy as np
+      if not self.ismybrother(that) :
+         raise Exception('right side not a vector')
+      else :
+         Dot=self.dot(that)
+         Ext=self.norm_ext(that)
+         return np.arctan2(Ext,Dot)
+   def copy(self) :
+      import copy
+      return copy.deepcopy(self)
+   def versor(self) :
+      "returns the versor"
+      new=self.copy()
+      nn=new.norm()
+      for k in new.keys() : new[k]=new[k]/nn
+      return new
+   def mean(self) :
+      "returns the averaged vector"
+      return vec3dict(self.v[0].mean(),self.v[1].mean(),self.v[2].mean())
+         
+#class matr3dict :
+   #""" handles a 3x3 matrix vector both as a dictionary and an indexed array , note rows are 3d matrices"""
+
+if __name__=='__main__' :
+   import numpy as np
+   v1=vec3dict()
+   print v1
+   
+   v2=vec3dict(1)
+   print v2
+
+   v3=vec3dict(1,2,3)
+   print v3
+   
+   v4=vec3dict(v3)
+   print v4
+   
+   print -v4
+   
+   print 2.*v4
+   print v4+3.
+   print v4.norm()
+   print v4 - v4
+   print v4.dot(v4)
+   print v4.ext(v4+vec3dict(0.,0.,1.))
+   print v4+vec3dict(0.,0.,1.)
+   
+   vx=vec3dict(1.,0.,0.)
+   vy=vec3dict(0.,1.,0.)
+   vz=vec3dict(0.,0.,1.)
+   
+   print
+   print "||VX x VY|| ",vx.norm_ext(vy)
+   print "||VX x V45degXY|| ",vx.norm_ext(vec3dict(np.cos(np.pi/4),np.cos(np.pi/4),0.))
+   print "||VX x V45degXZ|| ",vx.norm_ext(vec3dict(np.cos(np.pi/4),0.,np.cos(np.pi/4)))
+   print
+   print "angle(vx,vy) = ",vx.angle(vy)*180./np.pi
+   print "angle(vx,vz) = ",vx.angle(vz)*180./np.pi
+   print "angle(vy,vz) = ",vy.angle(vz)*180./np.pi
+   print
+   print "angle(vx,V45degXY) = ",vx.angle(vec3dict(np.cos(np.pi/4),np.cos(np.pi/4),0.))*180./np.pi
+   print "angle(vx,V45degXZ) = ",vx.angle(vec3dict(np.cos(np.pi/4),0.,np.cos(np.pi/4)))*180./np.pi
+