Index: TOOLS/WATER_BUDGET/ATM_waterbudget.py
===================================================================
--- TOOLS/WATER_BUDGET/ATM_waterbudget.py	(revision 6446)
+++ TOOLS/WATER_BUDGET/ATM_waterbudget.py	(revision 6508)
@@ -25,161 +25,123 @@
 import configparser, re
 
-## Creates parser
-config = configparser.ConfigParser()
+# Check python version
+if sys.version_info < (3, 8, 0) :
+    print ( f'Python version : {platform.python_version()}' ) 
+    raise Exception ( "Minimum Python version is 3.8" )
+
+## Import local module
+import WaterUtils as wu
+
+## Creates parser for reading .ini input file
+config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() )
 config.optionxform = str # To keep capitals
 
-## Read experiment parameters
-ATM=None ; ORCA=None ; NEMO=None ; OCE_relax=False ; OCE_icb=False ; Coupled=False ; Routing=None ;  TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None
+## Experiment parameters
+ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False ; OCE_icb=False ; Coupled=False ; Routing=None ; TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None
 
 ##
-ARCHIVE =None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None
-TmpDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None
+ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None
+TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None
 file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None
-file_restart_beg=None ; file_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None
-file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_beg=None ; file_OCE_end=None
-
-d_ATM_his=None ; d_SRF_his=None ; d_RUN_his=None ; d_OCE_his=None ;  d_ICE_his=None ; d_OCE_sca=None
-d_restart_beg=None ; d_restart_end=None ; d_ATM_beg=None ; d_ATM_end=None ; d_DYN_beg=None ; d_DYN_end=None ; d_SRF_beg=None ; d_SRF_end=None
-d_RUN_beg=None ; d_RUN_end=None ; d_RUN_end=None ; d_OCE_beg=None ; d_ICE_beg=None ; d_OCE_beg=None ; d_OCE_end=None
-
-# Arguments passed
+tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None
+file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_beg=None ; file_OCE_end=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None ; ContinueOnError=False ; ErrorCount=0
+tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None ; tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None
+tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None ; tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None
+SortIco = False
+
+# Read command line arguments
 print ( "Name of Python script:", sys.argv[0] )
 IniFile = sys.argv[1]
+# Text existence of IniFile
+if not os.path.exists (IniFile ) :
+    raise FileExistsError ( f"File not found : {IniFile = }" )
+
+if 'full' in IniFile : FullIniFile = IniFile
+else                 : FullIniFile = 'full_' + IniFile
+    
 print ("Input file : ", IniFile )
 config.read (IniFile)
 FullIniFile = 'full_' + IniFile
 
-def setBool (chars) :
-    '''Convert specific char string in boolean if possible'''
-    setBool = chars
-    for key in configparser.ConfigParser.BOOLEAN_STATES.keys () :
-        if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key]
-    return setBool
-
-def setNum (chars) :
-    '''Convert specific char string in integer or real if possible'''
-    if type (chars) == str :
-        realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$")
-        isReal = realnum.match(chars.strip()) != None
-        isInt  = chars.strip().isdigit()
-        if isReal :
-            if isInt : setNum = int   (chars)
-            else     : setNum = float (chars)
-        else : setNum = chars
-    else : setNum = chars
-    return setNum
-
-def setNone (chars) :
-    '''Convert specific char string to None if possible'''
-    if type (chars) == str :
-        if chars in ['None', 'NONE', 'none'] : setNone = None
-        else : setNone = chars
-    else : setNone = chars
-    return setNone
-
-## Reading config
-for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] :
-    if Section in config.keys() : 
-        print ( f'[{Section}]' )
+## Reading config file
+for Section in ['Config', 'Experiment', 'libIGCM', 'Files', 'Physics' ] :
+   if Section in config.keys () : 
+        print ( f'\nReading [{Section}]' )
         for VarName in config[Section].keys() :
             locals()[VarName] = config[Section][VarName]
-            locals()[VarName] = setBool (locals()[VarName])
-            locals()[VarName] = setNum  (locals()[VarName])
-            print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) )
-
-if not 'Files' in config.keys() : config['Files'] = {}
-
-def unDefined (char) :
-    if char in globals () :
-        if char == None : return True
-        else : return False
-    else : return True
-
+            exec  ( f'{VarName} = wu.setBool ({VarName})' )
+            exec  ( f'{VarName} = wu.setNum  ({VarName})' )
+            exec  ( f'{VarName} = wu.setNone ({VarName})' )
+            exec  ( f'wu.{VarName} = {VarName}' )
+            print ( f'{VarName:25} set to : {locals()[VarName]:}' )
+            #exec ( f'del {VarName}' )
+
+print ( f'\nConfig file readed : {IniFile} ' )
+            
 ##-- Some physical constants
-#-- Earth Radius
-if not 'Ra'            in locals () : Ra = 6366197.7236758135
-#-- Gravity
-if not 'Grav'          in locals () : Grav = 9.81
-#-- Ice volumic mass (kg/m3) in LIM3
-if not 'ICE_rho_ice'   in locals () : ICE_rho_ice = 917.0
-#-- Snow volumic mass (kg/m3) in LIM3
-if not 'ICE_rho_sno'   in locals () : ICE_rho_sno = 330.0
-#-- Ocean water volumic mass (kg/m3) in NEMO
-if not 'OCE_rho_liq'   in locals () : OCE_rho_liq = 1026.
-#-- Water volumic mass in atmosphere
-if not 'ATM_rho'       in locals () : ATM_rho = 1000.
-#-- Water volumic mass in surface reservoirs
-if not 'SRF_rho'       in locals () : SRF_rho = 1000.
-#-- Water volumic mass of rivers
-if not 'RUN_rho'       in locals () : RUN_rho = 1000.
-#-- Year length
-if not 'YearLength'    in locals () : YearLength = 365.25 * 24. * 60. * 60.
+if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m)
+if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s
+if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO
+if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3)
+if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3)
+if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3)
+if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3)
+if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s) - Use only to compute drif in approximate unit 
+            
+##-- Set libIGCM and machine dependant values
+if not 'Files' in config.keys () : config['Files'] = {}
 
 config['Physics'] = { 'Ra':Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno, 'OCE_rho_liq':OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}
 
-## --
-ICO  = ( 'ICO' in ATM )
-LMDZ = ( 'LMD' in ATM )
-    
-
-# Where do we run ?
-SysName, NodeName, Release, Version, Machine = os.uname ()
-TGCC  = ( 'irene'   in NodeName )
-IDRIS = ( 'jeanzay' in NodeName )
-
-## Set site specific libIGCM directories, and other specific stuff
-if TGCC :
-    CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' )
-    if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene'
-    if "AMD"                       in CPU : Machine = 'irene-amd'
-
-    if libIGCM : 
-        if ARCHIVE    == None : ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' )
-        if STORAGE    == None : STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' )
-        if SCRATCHDIR == None : SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' )
-        if R_IN       == None : R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM')
-        if rebuild    == None : rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' )
-
-    ## Specific to run at TGCC.
-    # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...)
-    import mpi4py
-    mpi4py.rc.initialize = False
-        
-    ## Creates output directory
-    if TmpDir == None :
-        TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
-        config['Files']['TmpDir'] = TmpDir
-        
-if IDRIS :
-    raise Exception ("Pour IDRIS : repertoires et chemins a definir") 
-
-config['System'] = {'SysName':SysName, 'NodeName':NodeName, 'Release':Release, 'Version':Version,'Machine':Machine, 'TGCC':TGCC,'IDRIS':IDRIS, 'CPU':CPU,
-                    'Program'  : "Generated by : " + str(sys.argv), 
-                    'HOSTNAME' : platform.node (), 'LOGNAME'  : os.getlogin (),
-                    'Python'   : f'{platform.python_version ()}',
-                    'OS'       : f'{platform.system ()} release : {platform.release ()} hardware : {platform.machine ()}',
-                    'SVN_Author'   : "$Author$", 
-                    'SVN_Date'     : "$Date$",
-                    'SVN_Revision' : "$Revision$",
-                    'SVN_Id'       : "$Id$",
-                    'SVN_HeadURL'  : "$HeadURL$"}
+config['Config'] = { 'ContinueOnError':ContinueOnError, 'SortIco':SortIco}
+
+## --------------------------
+ICO  = ( 'ICO' in wu.ATM )
+LMDZ = ( 'LMD' in wu.ATM )
+    
+with open ('SetLibIGCM.py') as f: exec ( f.read() )
+config['Files']['TmpDir'] = TmpDir
 
 if libIGCM :
     config['libIGCM'] = {'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'SCRATCHDIR':SCRATCHDIR, 'R_IN':R_IN, 'rebuild':rebuild }
 
-## Import specific module
+##-- Import specific module
 import nemo, lmdz
-## Now import needed scientific modules
+##-- Now import needed scientific modules
 import xarray as xr
 
-# Output file
-if FileOut == None : 
-    FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
-    config['Files']['FileOut'] = FileOut
+##- Output file with water budget diagnostics
+if wu.unDefined ( 'FileOut' ) : FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
+config['Files']['FileOut'] = FileOut
 
 f_out = open ( FileOut, mode = 'w' )
 
-# Function to print to stdout *and* output file
+##- Useful functions
+def kg2Sv    (val, rho=ATM_rho) :
+    '''From kg to Sverdrup'''
+    return val/dtime_sec*1.0e-6/rho
+
+def kg2myear (val, rho=ATM_rho) :
+    '''From kg to m/year'''
+    return val/ATM_aire_sea_tot/rho/NbYear
+
+def var2prt (var, small=False, rho=ATM_rho) :
+    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000.
+    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho)
+
+def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) :
+    if small :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "
+    else :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  "
+    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) )
+    return None
+
 def echo (string, end='\n') :
+    '''Function to print to stdout *and* output file'''
     print ( str(string), end=end  )
     sys.stdout.flush ()
@@ -188,62 +150,71 @@
     return None
     
-## Set libIGCM directories
-R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT')
-R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT')
-
-L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName)
-R_SAVE      = os.path.join ( R_OUT, L_EXP )
-R_BUFR      = os.path.join ( R_BUF, L_EXP )
-POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' )
-REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' )
-R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
-R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
-
-#if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir )
-if not os.path.isdir (TmpDir) : os.mkdir (TmpDir)
-TmpDirOCE = os.path.join (TmpDir, 'OCE')
-TmpDirICE = os.path.join (TmpDir, 'ICE')
-if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE )
-if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE )
+##- Set libIGCM directories
+if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' )
+if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' )
+if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName)
+if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP )
+if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP )
+if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' )
+if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
+
+config['libIGCM'] = { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR }
+
+##- Set directory to extract files
+if wu.unDefined ( 'RunDir' ) : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
+config['Files']['RunDir'] = RunDir
+
+if not os.path.isdir ( RunDir ) : os.makedirs ( RunDir )
+
+##- Set directories to rebuild ocean and ice restart files
+if wu.unDefined ( 'RunDirOCE' ) : RunDirOCE = os.path.join ( RunDir, 'OCE' )
+if wu.unDefined ( 'RunDirICE' ) : RunDirICE = os.path.join ( RunDir, 'ICE' )
+if not os.path.exists ( RunDirOCE ) : os.mkdir ( RunDirOCE )
+if not os.path.exists ( RunDirICE ) : os.mkdir ( RunDirICE )
 
 echo (' ')
-echo ( f'JobName : {JobName}' )
-echo (Comment)
-echo ( f'Working in TMPDIR : {TmpDir}' )
-
-echo ( f'\nDealing with {L_EXP}' )
-
-#-- Model output directories
+echo ( f'JobName   : {JobName}'   )
+echo ( f'Comment   : {Comment}'   )
+echo ( f'TmpDir    : {TmpDir}'    )
+echo ( f'RunDir    : {RunDir}'    )
+echo ( f'RunDirOCE : {RunDirOCE}' )
+echo ( f'RunDirICE : {RunDirICE}' )
+
+echo ( f'\nDealing with {L_EXP}'  )
+
+##-- Creates model output directory names
 if Freq == "MO" : FreqDir = os.path.join ('Output' , 'MO' )
 if Freq == "SE" : FreqDir = os.path.join ('Analyse', 'SE' )
-if dir_ATM_his == None :
+if wu.unDefined ('dir_ATM_his' ) :
     dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir )
     config['Files']['dir_ATM_his'] = dir_ATM_his
-if dir_SRF_his == None : 
+if wu.unDefined ( 'dir_SRF_his' ) : 
     dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir )
     config['Files']['dir_SRF_his'] = dir_SRF_his
     
 echo ( f'The analysis relies on files from the following model output directories : ' )
-echo ( f'{dir_ATM_his}' )
-echo ( f'{dir_SRF_his}' )
-
-#-- Files Names
-if Period == None :
+echo ( f'{dir_ATM_his = }' )
+echo ( f'{dir_SRF_his = }' )
+
+##-- Creates files names
+if wu.unDefined ( 'Period' ) :
     if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M'
     if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M'
     config['Files']['Period'] = Period
-if FileCommon == None :
+if wu.unDefined ( 'FileCommon' ) :
     FileCommon = f'{JobName}_{Period}'
     config['Files']['FileCommon'] = FileCommon
 
-if Title == None :
+if wu.unDefined ( 'Title' ) :
     Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31'
     config['Files']['Title'] = Title
      
 echo ('\nOpen history files' )
-if file_ATM_his == None : 
+if wu.unDefined ( 'file_ATM_his' ) : 
     file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' )
     config['Files']['file_ATM_his'] = file_ATM_his
-if file_SRF_his == None :
+if wu.unDefined ( 'file_SRF_his' ) :
     file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' )
     config['Files']['file_SRF_his'] = file_SRF_his
@@ -257,39 +228,38 @@
 d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
 d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
-if Routing == 'SECHIBA' :
-    d_RUN_his = d_SRF_his
-if Routing == 'SIMPLE' : 
-    d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
-
-echo ( file_ATM_his )
-echo ( file_SRF_his )
-if Routing == 'SIMPLE' : 
-    echo ( file_RUN_his )
-
-## Compute run length
+if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his
+if Routing == 'SIMPLE'  : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
+
+echo ( f'{file_ATM_his = }' )
+echo ( f'{file_SRF_his = }' )
+if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' )
+
+##-- Compute run length
 dtime = ( d_ATM_his.time_counter_bounds.max() - d_ATM_his.time_counter_bounds.min() )
 echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) )
 dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds
 
-## Compute length of each period
+##-- Compute length of each period
 dtime_per = (d_ATM_his.time_counter_bounds[:,-1] -  d_ATM_his.time_counter_bounds[:,0] )
 echo ('\nPeriods lengths (days) : {:} days'.format ( (dtime_per/np.timedelta64(1, "D")).values ) )
 dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds
 dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] )
-
-## Number of years
+dtime_per_sec.attrs['unit'] = 's'
+
+##-- Number of years (approximative)
 NbYear = dtime_sec / YearLength
 
-#-- Open restart files
-
+##-- Extract restart files from tar
 YearRes = YearBegin - 1              # Year of the restart of beginning of simulation
 YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation
 
-if TarRestartPeriod_beg == None : 
+config['Files']['YearPre'] = f'{YearBegin}'
+
+if wu.unDefined ( 'TarRestartPeriod_beg' ) : 
     echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
     TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231'
     config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg
 
-if TarRestartPeriod_end == None : 
+if wu.unDefined ( 'TarRestartPeriod_end ' ) : 
     YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation
     echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
@@ -297,46 +267,58 @@
     config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end
 
-if file_restart_beg == None :
-    file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )
-    config['Files']['file_restart_beg'] = file_restart_beg
-if file_restart_end == None :
-    file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )
-    config['Files']['file_restart_end'] = file_restart_end
-    
-echo ( f'{file_restart_beg}' )
-echo ( f'{file_restart_end}' )
-
-if file_ATM_beg == None : 
-    file_ATM_beg = f'{TmpDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc'
+if wu.unDefined ( 'tar_restart_beg' ) :
+    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )
+    config['Files']['tar_restart_beg'] = tar_restart_beg
+if wu.unDefined ( 'tar_restart_end' ) :
+    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )
+    config['Files']['tar_restart_end'] = tar_restart_end
+    
+echo ( f'{tar_restart_beg = }' )
+echo ( f'{tar_restart_end = }' )
+
+##-- Names of tar files with restarts
+if wu.unDefined ( 'SRF_HIS' ) : SRF_HIS = ATM_HIS
+
+if wu.unDefined ( 'tar_restart_beg_ATM' ) : tar_restart_beg_ATM = tar_restart_beg
+if wu.unDefined ( 'tar_restart_beg_DYN' ) : tar_restart_beg_DYN = tar_restart_beg
+if wu.unDefined ( 'tar_restart_beg_SRF' ) : tar_restart_beg_SRF = tar_restart_beg
+if wu.unDefined ( 'tar_restart_beg_RUN' ) : tar_restart_beg_RUN = tar_restart_beg
+if wu.unDefined ( 'tar_restart_beg_OCE' ) : tar_restart_beg_OCE = tar_restart_beg
+if wu.unDefined ( 'tar_restart_beg_ICE' ) : tar_restart_beg_ICE = tar_restart_beg
+
+if wu.unDefined ( 'tar_restart_end_ATM' ) : tar_restart_end_ATM = tar_restart_end
+if wu.unDefined ( 'tar_restart_end_DYN' ) : tar_restart_end_DYN = tar_restart_end
+if wu.unDefined ( 'tar_restart_end_SRF' ) : tar_restart_end_SRF = tar_restart_end
+if wu.unDefined ( 'tar_restart_end_RUN' ) : tar_restart_end_RUN = tar_restart_end
+if wu.unDefined ( 'tar_restart_end_OCE' ) : tar_restart_end_OCE = tar_restart_end
+if wu.unDefined ( 'tar_restart_end_ICE' ) : tar_restart_end_ICE = tar_restart_end
+
+if wu.unDefined ( 'file_ATM_beg' ) : 
+    file_ATM_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc'
     config['Files']['file_ATM_beg'] = file_ATM_beg
-if file_ATM_end == None :
-    file_ATM_end = f'{TmpDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc'
+if wu.unDefined ( 'file_ATM_end' ) :
+    file_ATM_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc'
     config['Files']['file_ATM_end'] = file_ATM_end
 
 liste_beg = [file_ATM_beg, ]
 liste_end = [file_ATM_end, ]
-    
-
-if file_DYN_beg == None :
-    if LMDZ :
-        file_DYN_beg = f'{TmpDir}/ATM_{JobName}_{YearRes}1231_restart.nc'
-    if ICO  :
-        file_DYN_beg = f'{TmpDir}/ICO_{JobName}_{YearRes}1231_restart.nc'
+
+if wu.unDefined ( 'file_DYN_beg' ) :
+    if LMDZ : file_DYN_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restart.nc'
+    if ICO  : file_DYN_beg = f'{RunDir}/ICO_{JobName}_{YearRes}1231_restart.nc'
     liste_beg.append (file_DYN_beg)
     config['Files']['file_DYN_beg'] = file_DYN_beg
     
-if file_DYN_end == None : 
-    if LMDZ :
-        file_DYN_end = f'{TmpDir}/ATM_{JobName}_{YearEnd}1231_restart.nc'
-    if ICO  :
-        file_DYN_end = f'{TmpDir}/ICO_{JobName}_{YearEnd}1231_restart.nc'
+if wu.unDefined ( 'file_DYN_end' ) : 
+    if LMDZ : file_DYN_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restart.nc'
+    if ICO  : file_DYN_end = f'{RunDir}/ICO_{JobName}_{YearEnd}1231_restart.nc'
     liste_end.append ( file_DYN_end )
     config['Files']['file_DYN_end'] = file_DYN_end
 
-if file_SRF_beg == None : 
-    file_SRF_beg = f'{TmpDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc'
+if wu.unDefined ( 'file_SRF_beg' ) :
+    file_SRF_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc'
     config['Files']['file_SRF_beg'] = file_SRF_beg
-if file_SRF_end == None : 
-    file_SRF_end = f'{TmpDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc'
+if wu.unDefined ( 'file_SRF_end' ) :
+    file_SRF_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc'
     config['Files']['file_SRF_end'] = file_SRF_end
     
@@ -344,50 +326,86 @@
 liste_end.append ( file_SRF_end )
 
-echo ( f'{file_ATM_beg}')
-echo ( f'{file_ATM_end}')
-echo ( f'{file_DYN_beg}')
-echo ( f'{file_DYN_end}')
-echo ( f'{file_SRF_beg}')
-echo ( f'{file_SRF_end}')
+echo ( f'{file_ATM_beg = }')
+echo ( f'{file_ATM_end = }')
+echo ( f'{file_DYN_beg = }')
+echo ( f'{file_DYN_end = }')
+echo ( f'{file_SRF_beg = }')
+echo ( f'{file_SRF_end = }')
+
+if ICO :
+    if wu.unDefined ('file_DYN_aire') : file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' )
+    config['Files'] ['file_DYN_aire'] = file_DYN_aire
 
 if Routing == 'SIMPLE' :
-    if file_RUN_beg == None : 
-        file_RUN_beg = f'{TmpDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc'
+    if wu.unDefined ( 'file_RUN_beg' ) : 
+        file_RUN_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc'
         config['Files']['file_RUN_beg'] = file_RUN_beg
-    if file_RUN_end == None : 
-        file_RUN_end = f'{TmpDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc'
+    if wu.unDefined ( 'file_RUN_end' ) : 
+        file_RUN_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc'
         config['Files']['file_RUN_end'] = file_RUN_end
         
     liste_beg.append ( file_RUN_beg )
     liste_end.append ( file_RUN_end )
-    echo ( f'{file_RUN_beg}')
-    echo ( f'{file_RUN_end}')
+    echo ( f'{file_RUN_beg = }' )
+    echo ( f'{file_RUN_end = }' )
 
 echo ('\nExtract restart files from tar : ATM, ICO and SRF')
-for resFile in liste_beg :
-    if os.path.exists ( os.path.join (TmpDir, resFile) ) :
-        echo ( f'file found : {resFile}' )
+
+def extract_and_rebuild ( file_name=file_ATM_beg, tar_restart=tar_restart_end, RunDirComp=RunDir, ErrorCount=ErrorCount ) :
+    echo ( f'----------')
+    echo ( f'file to extract : {file_name = }' )
+    if os.path.exists ( os.path.join (RunDir, file_name) ) :
+        echo ( f'file found : {file_name = }' )
     else :
-        base_resFile = os.path.basename (resFile)
-        command =  f'cd {TmpDir} ; tar xf {file_restart_beg} {base_resFile}'
-        echo ( command )
-        os.system ( command )
-        
-for resFile in liste_end :
-    if os.path.exists ( os.path.join (TmpDir, resFile) ) :
-        echo ( f'file found : {resFile}' )
-    else :
-        base_resFile = os.path.basename (resFile)
-        command =  f'cd {TmpDir} ; tar xf {file_restart_end} {base_resFile}'
-        echo ( command )
-        os.system ( command )
-       
+        echo ( f'file not found : {file_name = }' )
+        base_resFile = os.path.basename (file_name)
+        if os.path.exists ( tar_restart ) :
+            command =  f'cd {RunDir} ; tar xf {tar_restart} {base_resFile}'
+            echo ( f'{command = }' )
+            try : 
+                os.system ( command )
+            except :
+                if ContinueOnError :
+                    ErrorCount += 1
+                    echo ( f'****** Command failed : {command}' )
+                    echo ( f'****** Trying to continue' )
+                    echo ( ' ')
+                else :
+                    raise Exception ( f'**** command failed : {command} - Stopping' )
+            else :
+                echo ( f'tar done : {base_resFile}' )
+        else :
+            echo ( f'****** Tar restart file {tar_restart = } not found ' )
+            if ContinueOnError :
+                ErrorCount += 1
+            else : 
+                raise Exception ( f'****** tar file not found {tar_restart = } - Stopping' )
+    return ErrorCount
+ 
+ErrorCount += extract_and_rebuild ( file_name=file_ATM_beg, tar_restart=tar_restart_beg_ATM, RunDirComp=RunDir )
+ErrorCount += extract_and_rebuild ( file_name=file_DYN_beg, tar_restart=tar_restart_beg_DYN, RunDirComp=RunDir )
+ErrorCount += extract_and_rebuild ( file_name=file_SRF_beg, tar_restart=tar_restart_beg_SRF, RunDirComp=RunDir )
+
+ErrorCount += extract_and_rebuild ( file_name=file_ATM_end, tar_restart=tar_restart_end_ATM, RunDirComp=RunDir )
+ErrorCount += extract_and_rebuild ( file_name=file_DYN_end, tar_restart=tar_restart_end_DYN, RunDirComp=RunDir )
+ErrorCount += extract_and_rebuild ( file_name=file_SRF_end, tar_restart=tar_restart_end_SRF, RunDirComp=RunDir )
+
+if Routing == 'SIMPLE' :
+    ErrorCount += extract_and_rebuild ( file_name=file_RUN_beg, tar_restart=tar_restart_beg_RUN, RunDirComp=RunDir )
+    ErrorCount += extract_and_rebuild ( file_name=file_RUN_end, tar_restart=tar_restart_end_RUN, RunDirComp=RunDir )
+
+##-- Exit in case of error in the opening file phase
+if ErrorCount > 0 :
+    echo ( '  ' )
+    raise Exception ( f'**** Some files missing - Stopping - {ErrorCount = }' )
+
+## 
 echo ('\nOpening ATM SRF and ICO restart files')
-d_ATM_beg = xr.open_dataset ( os.path.join (TmpDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze()
-d_ATM_end = xr.open_dataset ( os.path.join (TmpDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze()
-d_SRF_beg = xr.open_dataset ( os.path.join (TmpDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze()
-d_SRF_end = xr.open_dataset ( os.path.join (TmpDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze()
-d_DYN_beg = xr.open_dataset ( os.path.join (TmpDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze()
-d_DYN_end = xr.open_dataset ( os.path.join (TmpDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze()
+d_ATM_beg = xr.open_dataset ( os.path.join (RunDir, file_ATM_beg), decode_times=False, decode_cf=True ).squeeze()
+d_ATM_end = xr.open_dataset ( os.path.join (RunDir, file_ATM_end), decode_times=False, decode_cf=True ).squeeze()
+d_SRF_beg = xr.open_dataset ( os.path.join (RunDir, file_SRF_beg), decode_times=False, decode_cf=True ).squeeze()
+d_SRF_end = xr.open_dataset ( os.path.join (RunDir, file_SRF_end), decode_times=False, decode_cf=True ).squeeze()
+d_DYN_beg = xr.open_dataset ( os.path.join (RunDir, file_DYN_beg), decode_times=False, decode_cf=True ).squeeze()
+d_DYN_end = xr.open_dataset ( os.path.join (RunDir, file_DYN_end), decode_times=False, decode_cf=True ).squeeze()
 
 for var in d_SRF_beg.variables :
@@ -396,141 +414,188 @@
 
 if Routing == 'SIMPLE' :
-    d_RUN_beg = xr.open_dataset ( os.path.join (TmpDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze()
-    d_RUN_end = xr.open_dataset ( os.path.join (TmpDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze()
-    
-echo ( file_ATM_beg )
-echo ( file_ATM_end )
-echo ( file_DYN_beg )
-echo ( file_DYN_end )
-echo ( file_SRF_beg )
-echo ( file_SRF_end )
+    d_RUN_beg = xr.open_dataset ( os.path.join (RunDir, file_RUN_beg), decode_times=False, decode_cf=True ).squeeze()
+    d_RUN_end = xr.open_dataset ( os.path.join (RunDir, file_RUN_end), decode_times=False, decode_cf=True ).squeeze()
+
+def to_cell ( dd, newname='cell' ) :
+    '''Set space dimension to 'cell' '''
+    for oldname in [ 'cell_mesh', 'y', 'points_physiques' ] :
+        try    : dd = dd.rename ( {oldname : newname} )
+        except : pass
+    return dd
+
+d_ATM_beg = to_cell ( d_ATM_beg )
+d_ATM_end = to_cell ( d_ATM_end )
+d_SRF_beg = to_cell ( d_SRF_beg )
+d_SRF_end = to_cell ( d_SRF_end )
+d_DYN_beg = to_cell ( d_DYN_beg )
+d_DYN_end = to_cell ( d_DYN_end )
+
 if Routing == 'SIMPLE' :
-    echo ( file_RUN_beg )
-    echo ( file_RUN_end )
-
-##
+    d_RUN_beg = to_cell ( d_RUN_beg )
+    d_RUN_end = to_cell ( d_RUN_end )
+
+d_ATM_his = to_cell ( d_ATM_his )
+d_SRF_his = to_cell ( d_SRF_his )
+    
+echo ( f'{file_ATM_beg = }' )
+echo ( f'{file_ATM_end = }' )
+echo ( f'{file_DYN_beg = }' )
+echo ( f'{file_DYN_end = }' )
+echo ( f'{file_SRF_beg = }' )
+echo ( f'{file_SRF_end = }' )
+if Routing == 'SIMPLE' :
+    echo ( f'{file_RUN_beg = }' )
+    echo ( f'{file_RUN_end = }' )
+
+## Write the full configuration
 config_out = open (FullIniFile, 'w')
-config.write (config_out )
+config.write ( config_out )
 config_out.close ()
 
-def Ksum (tab) :
-    '''
-    Kahan summation algorithm, also known as compensated summation
-    https://en.wikipedia.org/wiki/Kahan_summation_algorithm
-    '''
-    Ksum = 0.0                   # Prepare the accumulator.
-    comp = 0.0                   # A running compensation for lost low-order bits.
-   
-    for xx in np.where ( np.isnan(tab), 0., tab ) : 
-        yy = xx - comp           # comp is zero the first time around.
-        tt = Ksum + yy           # Alas, sum is big, y small, so low-order digits of y are lost.
-        comp = (tt - Ksum) - yy  # (tt - Ksum) cancels the high-order part of y; subtracting y recovers negative (low part of yy)
-        Ksum = tt                # Algebraically, comp should always be zero. Beware overly-aggressive optimizing compilers!
-                                 # Next time around, the lost low part will be added to y in a fresh attempt.
-    return Ksum
-
-def Ssum (tab) :
-    '''
-    Precision summation by sorting by absolute value
-    '''
-    Ssum = np.sum ( tab[np.argsort(np.abs(tab))] )
-    return Ssum
-
-def KSsum (tab) :
-    '''
-    Precision summation by sorting by absolute value, and applying Kahan summation
-    '''
-    KSsum = Ksum ( tab[np.argsort(np.abs(tab))] )
-    return KSsum
-
-# Choosing algorithm
-Psum = KSsum
-
-def ATM_stock_int (stock) :
-    '''Integrate stock on atmosphere grid'''
-    ATM_stock_int  = Psum ( (stock * DYN_aire).to_masked_array().ravel() ) 
-    return ATM_stock_int
-
-def ATM_flux_int (flux) :
-    '''Integrate flux on atmosphere grid'''
-    ATM_flux_int  = Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() )
-    return ATM_flux_int
-
-def SRF_stock_int (stock) :
-    '''Integrate stock on land grid'''
-    ATM_stock_int  = Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) )
-    return ATM_stock_int
-
-def SRF_flux_int (flux) :
-    '''Integrate flux on land grid'''
-    SRF_flux_int  = Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() )
-    return SRF_flux_int
-
-def ONE_stock_int (stock) :
-    '''Sum stock '''
-    ONE_stock_int  = Psum ( stock.to_masked_array().ravel() )
-    return ONE_stock_int
-
-def ONE_flux_int (flux) :
-    '''Sum flux '''
-    ONE_flux_int  = Psum ( (flux * dtime_per_sec ).to_masked_array().ravel() )
-    return ONE_flux_int
-
-def kg2Sv  (val, rho=ATM_rho) :
-    '''From kg to Sverdrup'''
-    return val/dtime_sec*1.0e-6/rho
-
-def kg2myear (val, rho=ATM_rho) :
-    '''From kg to m/year'''
-    return val/ATM_aire_sea_tot/rho/NbYear
-    
+if ICO :
+    if SortIco : 
+        # Creation d'une clef de tri pour les restarts (pour chaque restart !)
+        DYN_beg_keysort = np.lexsort ( (d_DYN_beg['lat_mesh'], d_DYN_beg['lon_mesh'] ) )
+        ATM_beg_keysort = np.lexsort ( (d_ATM_beg['latitude'], d_ATM_beg['longitude']) )
+        SRF_beg_keysort = np.lexsort ( (d_SRF_beg['nav_lat' ], d_SRF_beg['nav_lon']  ) )
+        DYN_end_keysort = np.lexsort ( (d_DYN_end['lat_mesh'], d_DYN_end['lon_mesh'] ) )
+        ATM_end_keysort = np.lexsort ( (d_ATM_end['latitude'], d_ATM_end['longitude']) )
+        SRF_end_keysort = np.lexsort ( (d_SRF_end['nav_lat' ], d_SRF_end['nav_lon']  ) )
+        
+        if ATM_HIS == 'ico' :
+            ATM_his_keysort = np.lexsort ( (d_ATM_his['lat'], d_ATM_his['lon'] ) )
+        if SRF_HIS == 'ico' :
+            SRF_his_keysort = np.lexsort ( (d_SRF_his['lat'], d_SRF_his['lon'] ) )
+            RUN_his_keysort = SRF_his_keysort
+    else : 
+        DYN_beg_keysort = np.arange ( len ( d_DYN_beg['lat_mesh'] ) )
+        ATM_beg_keysort = DYN_beg_keysort
+        SRF_beg_keysort = DYN_beg_keysort
+
+        DYN_end_keysort = DYN_beg_keysort
+        ATM_end_keysort = DYN_beg_keysort
+        SRF_end_keysort = DYN_beg_keysort
+    
+        ATM_his_keysort = DYN_beg_keysort
+        SRF_his_keysort = DYN_beg_keysort
+        RUN_his_keysort = SRF_his_keysort
+        
 # ATM grid with cell surfaces
+if LMDZ :
+    #ATM_lat  = lmdz.geo2point ( d_ATM_his ['lat']         , dim1D='cell' )
+    #ATM_lon  = lmdz.geo2point ( d_ATM_his ['lon']         , dim1D='cell' )
+    ATM_aire = lmdz.geo2point ( d_ATM_his ['aire']     [0], cumulPoles=True, dim1D='cell' )
+    ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell' )
+    ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell' )
+    ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell' )
+    ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell' )
+    #SRF_lat  = lmdz.geo2point ( d_SRF_his ['lat']      [0], dim1D='cell' )
+    #SRF_lon  = lmdz.geo2point ( d_SRF_his ['lon']      [0], dim1D='cell' )
+    
+    #??SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'], dim1D='cell' )
+    SRF_aire =  ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'], dim1D='cell' )
+    
 if ICO :
-    jpja, jpia = d_ATM_his['aire'][0].shape   
-    file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' )
-    config['Files']['file_ATM_aire'] = file_ATM_aire
-    echo ( f'Aire sur grille reguliere : {file_ATM_aire}' )
-    d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze()
-    ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True )
-    ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] )
-    ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] )
-    ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] )
-    ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] )
-    ATM_fsea = ATM_foce + ATM_fsic
-    ATM_flnd = ATM_fter + ATM_flic
-    SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] )
-    #SRF_aire = ATM_aire * lmdz.geo2point (d_SRF_his ['Contfrac'] )
-    #SRF_aire = ATM_aire * ATM_fter
-    
-if LMDZ :
-    ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True )
-    ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] )
-    ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] )
-    #SRF_aire = lmdz.geo2point ( d_SRF_his['Areas'] * d_SRF_his['Contfrac'] )
-    SRF_aire = ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'] )
-
-SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.)
-
+    if ATM_HIS == 'latlon' :
+        jpja, jpia = d_ATM_his['aire'][0].shape   
+        file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' )
+        config['Files']['file_ATM_aire'] = file_ATM_aire
+        echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' )
+        d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze()
+        #ATM_lat  = d_ATM_his ['lat']
+        #ATM_lon  = d_ATM_his ['lon']
+        ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True, dim1D='cell' )
+        ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell' )
+        ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell' )
+        ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell' )
+        ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell' )
+        #SRF_lat  = d_SRF_his ['lat']
+        #SRF_lon  = d_SRF_his ['lon']
+        SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'], dim1D='cell' )
+        
+    if ATM_HIS == 'ico' :
+        echo ( f'Grille icosaedre' )
+        ATM_aire =  d_ATM_his ['aire']     [0][ATM_his_keysort].squeeze()
+        #ATM_lat  =  d_ATM_his ['lat']         [ATM_his_keysort]
+        #ATM_lon  =  d_ATM_his ['lon']         [ATM_his_keysort]
+        ATM_fter =  d_ATM_his ['fract_ter'][0][ATM_his_keysort]
+        ATM_foce =  d_ATM_his ['fract_oce'][0][ATM_his_keysort]
+        ATM_fsic =  d_ATM_his ['fract_sic'][0][ATM_his_keysort]
+        ATM_flic =  d_ATM_his ['fract_lic'][0][ATM_his_keysort]
+        #SRF_lat  =  d_SRF_his ['lat']         [SRF_his_keysort]
+        #SRF_lon  =  d_SRF_his ['lon']         [SRF_his_keysort]
+        SRF_aire =  d_SRF_his ['Areas'][SRF_his_keysort] * d_SRF_his ['Contfrac'][SRF_his_keysort]
+
+ATM_fsea      = ATM_foce + ATM_fsic
+ATM_flnd      = ATM_fter + ATM_flic
+ATM_aire_fter = ATM_aire * ATM_fter
+ATM_aire_flic = ATM_aire * ATM_flic
+ATM_aire_fsic = ATM_aire * ATM_fsic
+ATM_aire_foce = ATM_aire * ATM_foce
+ATM_aire_flnd = ATM_aire * ATM_flnd
+ATM_aire_fsea = ATM_aire * ATM_fsea
+
+SRF_aire = SRF_aire.where ( np.abs (SRF_aire) < 1E15, 0.)
+            
 if ICO :
     # Area on icosahedron grid
-    file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' )
     d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False).squeeze()
-    d_DYN_aire = d_DYN_aire.rename ( {'cell':'cell_mesh'} )
-    DYN_aire   = d_DYN_aire['aire']
-
-    DYN_fsea = d_DYN_aire ['fract_oce'] + d_DYN_aire ['fract_sic']
+
+    if SortIco : 
+        # Creation d'une clef de tri pour le fichier aire
+        DYN_aire_keysort = np.lexsort ( (d_DYN_aire['lat'], d_DYN_aire['lon']) )
+    else : 
+        DYN_aire_keysort = np.arange ( len ( d_DYN_aire['lat'] ) )
+            
+    DYN_lat = d_DYN_aire['lat'][DYN_aire_keysort]
+    DYN_lon = d_DYN_aire['lon'][DYN_aire_keysort]
+
+    DYN_aire = d_DYN_aire['aire'][DYN_aire_keysort]
+    DYN_fsea = d_DYN_aire ['fract_oce'][DYN_aire_keysort] + d_DYN_aire['fract_sic'][DYN_aire_keysort]
     DYN_flnd = 1.0 - DYN_fsea
-    DYN_fter = d_ATM_beg['FTER'].rename({'points_physiques':'cell_mesh'})
-    DYN_flic = d_ATM_beg['FTER'].rename({'points_physiques':'cell_mesh'})
+    DYN_fter = d_ATM_beg['FTER'][ATM_beg_keysort]
+    DYN_flic = d_ATM_beg['FLIC'][ATM_beg_keysort]
+    DYN_aire_fter = DYN_aire * DYN_fter
     
 if LMDZ :
+    # Area on lon/lat grid
     DYN_aire = ATM_aire
     DYN_fsea = ATM_fsea
     DYN_flnd = ATM_flnd
     DYN_fter = d_ATM_beg['FTER']
-    DYN_flic = d_ATM_beg['FTER']
-
-    
-DYN_aire_fter = DYN_aire * DYN_fter
+    DYN_flic = d_ATM_beg['FLIC']
+    DYN_aire_fter = DYN_aire * DYN_fter
+
+# Functions computing integrals and sum
+def ATM_stock_int (stock) :
+    '''Integrate (* surface) stock on atmosphere grid'''
+    ATM_stock_int  = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() ) 
+    return ATM_stock_int
+
+def ATM_flux_int (flux) :
+    '''Integrate (* time * surface) flux on atmosphere grid'''
+    ATM_flux_int  = wu.Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() )
+    return ATM_flux_int
+
+def SRF_stock_int (stock) :
+    '''Integrate (* surface) stock on land grid'''
+    SRF_stock_int  = wu.Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) )
+    return SRF_stock_int
+
+def SRF_flux_int (flux) :
+    '''Integrate (* time * surface) flux on land grid'''
+    SRF_flux_int  = wu.Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() )
+    return SRF_flux_int
+
+def ONE_stock_int (stock) :
+    '''Sum stock '''
+    ONE_stock_int  = wu.Psum ( stock.to_masked_array().ravel() )
+    return ONE_stock_int
+
+def ONE_flux_int (flux) :
+    '''Integrate (* time) flux on area=1 grid '''
+    ONE_flux_int  = wu.Psum ( (flux * dtime_per_sec ).to_masked_array().ravel() )
+    return ONE_flux_int
+
 
 #if LMDZ :
@@ -538,14 +603,12 @@
 
 ATM_aire_sea     = ATM_aire * ATM_fsea
-ATM_aire_sea_tot = ONE_stock_int ( ATM_aire_sea )
-
 ATM_aire_tot     = ONE_stock_int (ATM_aire)
 ATM_aire_sea_tot = ONE_stock_int (ATM_aire*ATM_fsea)
 
 
-echo ( 'Aire atmosphere/4pi R^2 : {:12.5f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) )
+echo ( 'Area of atmosphere/(4pi R^2) : {:12.5f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) )
 
 if (  np.abs (ATM_aire_tot/(Ra*Ra*4*np.pi) - 1.0) > 0.01 ) :
-    raise Exception ('Erreur surface interpolee sur grille reguliere')
+    raise Exception ('Error of atmosphere surface interpolated on lon/lat grid')
 
 echo ( '\n====================================================================================' )
@@ -555,58 +618,59 @@
 #-- Compute sum weighted by gridcell area (kg/m2) then convert to Sv
 
-# ATM vertical grid
+echo ( 'ATM vertical grid' )
 ATM_Ahyb = d_ATM_his['Ahyb'].squeeze()
 ATM_Bhyb = d_ATM_his['Bhyb'].squeeze()
 
-# Surface pressure
-if ICO : 
-    DYN_psol_beg = d_DYN_beg['ps']
-    DYN_psol_end = d_DYN_end['ps']
+echo ( 'Surface pressure' )
+if ICO :
+    DYN_psol_beg = d_DYN_beg['ps'][DYN_beg_keysort]
+    DYN_psol_end = d_DYN_end['ps'][DYN_end_keysort]
 if LMDZ : 
-    DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)) )
-    DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)) )
-    
-# 3D Pressure at the interface layers (not scalar points)
+    DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' )
+    DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' )
+    
+echo ( '3D Pressure at the interface layers (not scalar points)' )
 DYN_pres_beg = ATM_Ahyb + ATM_Bhyb * DYN_psol_beg
 DYN_pres_end = ATM_Ahyb + ATM_Bhyb * DYN_psol_end
 
 klevp1 = ATM_Bhyb.shape[-1]
-if ICO  : cell_mesh        = DYN_psol_beg.shape[-1]
-if LMDZ : points_physiques = DYN_psol_beg.shape[-1]
+cell        = DYN_psol_beg.shape[-1]
 klev = klevp1 - 1
 
-# Layer thickness (pressure)
-if ICO : 
-    DYN_dpres_beg = xr.DataArray ( np.empty( (klev, cell_mesh       )), dims=('sigs', 'cell_mesh'       ), coords=(np.arange(klev), np.arange(cell_mesh)        ) )
-    DYN_dpres_end = xr.DataArray ( np.empty( (klev, cell_mesh       )), dims=('sigs', 'cell_mesh'       ), coords=(np.arange(klev), np.arange(cell_mesh)        ) )
-if LMDZ : 
-    DYN_dpres_beg = xr.DataArray ( np.empty( (klev, points_physiques)), dims=('sigs', 'points_physiques'), coords=(np.arange(klev), np.arange(points_physiques) ) )
-    DYN_dpres_end = xr.DataArray ( np.empty( (klev, points_physiques)), dims=('sigs', 'points_physiques'), coords=(np.arange(klev), np.arange(points_physiques) ) )
-
+echo ( 'Layer thickness (pressure)' )
+DYN_dpres_beg = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) )
+DYN_dpres_end = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) )
+#DYN_dpres_beg = DYN_dpres_beg
+#DYN_dpres_end = DYN_dpres_end
+    
 for k in np.arange (klevp1-1) :
     DYN_dpres_beg[k,:] = DYN_pres_beg[k,:] - DYN_pres_beg[k+1,:]
     DYN_dpres_end[k,:] = DYN_pres_end[k,:] - DYN_pres_end[k+1,:]
 
-##-- Vertical and horizontal integral, and sum of liquid, solid and vapor water phases
+echo ( 'Vertical and horizontal integral, and sum of liquid, solid and vapor water phases' )
 if LMDZ :
     try : 
-        DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov']  + d_DYN_beg['H2Ol']  + d_DYN_beg['H2Oi'] ).isel(rlonv=slice(0,-1) ) )
-        DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov']  + d_DYN_end['H2Ol']  + d_DYN_end['H2Oi'] ).isel(rlonv=slice(0,-1) ) )
+        DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov']  + d_DYN_beg['H2Ol']  + d_DYN_beg['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' )
+        DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov']  + d_DYN_end['H2Ol']  + d_DYN_end['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' )
     except :
-        DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).isel(rlonv=slice(0,-1) ) )
-        DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).isel(rlonv=slice(0,-1) ) )
+        DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).isel(rlonv=slice(0,-1) ), dim1D='cell' )
+        DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).isel(rlonv=slice(0,-1) ), dim1D='cell' )
 if ICO :
     try :
-        DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).rename ( {'lev':'sigs'} )
-        DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).rename ( {'lev':'sigs'} )
+        DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'])[..., DYN_beg_keysort]
+        DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'])[..., DYN_beg_keysort]
+        
     except : 
-        DYN_wat_beg = (d_DYN_beg['q'].isel(nq=0) + d_DYN_beg['q'].isel(nq=1) + d_DYN_beg['q'].isel(nq=2) ).rename ( {'lev':'sigs'} )
-        DYN_wat_end = (d_DYN_end['q'].isel(nq=0) + d_DYN_end['q'].isel(nq=1) + d_DYN_end['q'].isel(nq=2) ).rename ( {'lev':'sigs'} )
-    
-# Compute water content : vertical and horizontal integral
-DYN_mas_wat_beg = ATM_stock_int (DYN_dpres_beg * DYN_wat_beg) / Grav
-DYN_mas_wat_end = ATM_stock_int (DYN_dpres_end * DYN_wat_end) / Grav
-
-# Variation of water content
+        DYN_wat_beg = (d_DYN_beg['q'].isel(nq=0) + d_DYN_beg['q'].isel(nq=1) + d_DYN_beg['q'].isel(nq=2) )[..., DYN_beg_keysort]
+        DYN_wat_end = (d_DYN_end['q'].isel(nq=0) + d_DYN_end['q'].isel(nq=1) + d_DYN_end['q'].isel(nq=2) )[..., DYN_beg_keysort]
+        
+    DYN_wat_beg = DYN_wat_beg.rename ( {'lev':'sigs'} )
+    DYN_wat_beg = DYN_wat_end.rename ( {'lev':'sigs'} )
+    
+echo ( 'Compute water content : vertical and horizontal integral' )
+DYN_mas_wat_beg = ATM_stock_int ( (DYN_dpres_beg * DYN_wat_beg).sum (dim='sigs') ) / Grav
+DYN_mas_wat_end = ATM_stock_int ( (DYN_dpres_end * DYN_wat_end).sum (dim='sigs') ) / Grav
+
+echo ( 'Variation of water content' )
 dDYN_mas_wat = DYN_mas_wat_end - DYN_mas_wat_beg
 
@@ -614,31 +678,23 @@
 # \([a-z,A-Z,_]*\)\/ATM_aire_sea_tot\/ATM_rho\/NbYear  kg2myear(\1)
 
-def var2prt (var, small=False) :
-    if small :  return var , kg2Sv(var)*1000., kg2myear(var)*1000.
-    else     :  return var , kg2Sv(var)      , kg2myear(var)
-
-def prtFlux (Desc, var, Form='F', small=False) :
-    if small :
-        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "
-        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "
-    else :
-        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  "
-        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  "
-    echo ( (' {:>15} = ' +ff).format (Desc, *var2prt(var, small) ) )
-    return None
-
-echo ( f'\nVariation du contenu en eau atmosphere (dynamique)  -- {Title} ' )
+echo ( f'\nChange of atmosphere water content (dynamics)  -- {Title} ' )
 echo ( '------------------------------------------------------------------------------------' )
 echo ( 'DYN_mas_beg = {:12.6e} kg | DYN_mas_end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) )
 prtFlux ( 'dMass (atm)  ', dDYN_mas_wat, 'e', True )
 
-ATM_sno_beg = d_ATM_beg['SNOW01']*d_ATM_beg['FTER']+d_ATM_beg['SNOW02']*d_ATM_beg['FLIC']+d_ATM_beg['SNOW03']*d_ATM_beg['FOCE']+d_ATM_beg['SNOW04']*d_ATM_beg['FSIC']
-ATM_sno_end = d_ATM_end['SNOW01']*d_ATM_end['FTER']+d_ATM_end['SNOW02']*d_ATM_end['FLIC']+d_ATM_end['SNOW03']*d_ATM_end['FOCE']+d_ATM_end['SNOW04']*d_ATM_end['FSIC']
-
-ATM_qs_beg  = d_ATM_beg['QS01']*d_ATM_beg['FTER']+d_ATM_beg['QS02']*d_ATM_beg['FLIC']+d_ATM_beg['QS03']*d_ATM_beg['FOCE']+d_ATM_beg['QS04']*d_ATM_beg['FSIC']
-ATM_qs_end  = d_ATM_end['QS01']*d_ATM_end['FTER']+d_ATM_end['QS02']*d_ATM_end['FLIC']+d_ATM_end['QS03']*d_ATM_end['FOCE']+d_ATM_end['QS04']*d_ATM_end['FSIC']
+ATM_sno_beg = d_ATM_beg['SNOW01']*d_ATM_beg['FTER'] + d_ATM_beg['SNOW02']*d_ATM_beg['FLIC'] + d_ATM_beg['SNOW03']*d_ATM_beg['FOCE'] + d_ATM_beg['SNOW04']*d_ATM_beg['FSIC']
+ATM_sno_end = d_ATM_end['SNOW01']*d_ATM_end['FTER'] + d_ATM_end['SNOW02']*d_ATM_end['FLIC'] + d_ATM_end['SNOW03']*d_ATM_end['FOCE'] + d_ATM_end['SNOW04']*d_ATM_end['FSIC']
+
+ATM_qs_beg  = d_ATM_beg['QS01']  *d_ATM_beg['FTER'] + d_ATM_beg['QS02']  *d_ATM_beg['FLIC'] + d_ATM_beg['QS03']  *d_ATM_beg['FOCE'] + d_ATM_beg['QS04']  *d_ATM_beg['FSIC']
+ATM_qs_end  = d_ATM_end['QS01']  *d_ATM_end['FTER'] + d_ATM_end['QS02']  *d_ATM_end['FLIC'] + d_ATM_end['QS03']  *d_ATM_end['FOCE'] + d_ATM_end['QS04']  *d_ATM_end['FSIC']
 
 ATM_qsol_beg = d_ATM_beg['QSOL']
 ATM_qsol_end = d_ATM_end['QSOL']
+
+LIC_sno_beg      = d_ATM_beg['SNOW02']*d_ATM_beg['FLIC']
+LIC_sno_end      = d_ATM_end['SNOW02']*d_ATM_end['FLIC']
+
+LIC_runlic0_beg  = d_ATM_beg['RUNOFFLIC0']
+LIC_runlic0_end  = d_ATM_end['RUNOFFLIC0']
 
 ATM_qs01_beg  = d_ATM_beg['QS01'] * d_ATM_beg['FTER']
@@ -651,34 +707,73 @@
 ATM_qs04_end  = d_ATM_end['QS04'] * d_ATM_end['FSIC']  
 
+# if LMDZ :
+#     ATM_sno_beg       = lmdz.geo2point ( ATM_sno_beg    , dim1D='cell' )
+#     ATM_sno_end       = lmdz.geo2point ( ATM_sno_end    , dim1D='cell' )
+#     ATM_qs_beg        = lmdz.geo2point ( ATM_qs_beg     , dim1D='cell' )
+#     ATM_qs_end        = lmdz.geo2point ( ATM_qs_end     , dim1D='cell' )
+#     ATM_qsol_beg      = lmdz.geo2point ( ATM_qsol_beg   , dim1D='cell' )
+#     ATM_qsol_end      = lmdz.geo2point ( ATM_qsol_end   , dim1D='cell' )
+#     ATM_qs01_beg      = lmdz.geo2point ( ATM_qs01_beg   , dim1D='cell' )
+#     ATM_qs01_end      = lmdz.geo2point ( ATM_qs01_end   , dim1D='cell' )
+#     ATM_qs02_beg      = lmdz.geo_point ( ATM_qs02_beg   , dim1D='cell' )
+#     ATM_qs02_end      = lmdz.geo2point ( ATM_qs02_end   , dim1D='cell' )
+#     ATM_qs03_beg      = lmdz.geo2point ( ATM_qs03_beg   , dim1D='cell' )
+#     ATM_qs03_end      = lmdz.geo2point ( ATM_qs03_end   , dim1D='cell' )
+#     ATM_qs04_beg      = lmdz.geo2point ( ATM_qs04_beg   , dim1D='cell' )
+#     ATM_qs04_end      = lmdz.geo2point ( ATM_qs04_end   , dim1D='cell' )
+#     LIC_sno_beg       = lmdz.geo2point ( LIC_sno_beg    , dim1D='cell' )
+#     LIC_sno_end       = lmdz.geo2point ( LIC_sno_end    , dim1D='cell' )
+#     LIC_runlic0_beg   = lmdz.geo2point ( LIC_runlic0_beg, dim1D='cell' )
+#     LIC_runlic0_end   = lmdz.geo2point ( LIC_runlic0_end, dim1D='cell' )
 if ICO :
-   ATM_sno_beg   = ATM_sno_beg .rename ( {'points_physiques':'cell_mesh'} )
-   ATM_sno_end   = ATM_sno_end .rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs_beg    = ATM_qs_beg  .rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs_end    = ATM_qs_end  .rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qsol_beg  = ATM_qsol_beg.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qsol_end  = ATM_qsol_end.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs01_beg  = ATM_qs01_beg.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs01_end  = ATM_qs01_end.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs02_beg  = ATM_qs02_beg.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs02_end  = ATM_qs02_end.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs03_beg  = ATM_qs03_beg.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs03_end  = ATM_qs03_end.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs04_beg  = ATM_qs04_beg.rename ( {'points_physiques':'cell_mesh'} )
-   ATM_qs04_end  = ATM_qs04_end.rename ( {'points_physiques':'cell_mesh'} ) 
-
-ATM_mas_sno_beg   = ATM_stock_int ( ATM_sno_beg  )
-ATM_mas_sno_end   = ATM_stock_int ( ATM_sno_end  )
-ATM_mas_qs_beg    = ATM_stock_int ( ATM_qs_beg   )
-ATM_mas_qs_end    = ATM_stock_int ( ATM_qs_end   )
-ATM_mas_qsol_beg  = ATM_stock_int ( ATM_qsol_beg )
-ATM_mas_qsol_end  = ATM_stock_int ( ATM_qsol_end )
-ATM_mas_qs01_beg  = ATM_stock_int ( ATM_qs01_beg )
-ATM_mas_qs01_end  = ATM_stock_int ( ATM_qs01_end )
-ATM_mas_qs02_beg  = ATM_stock_int ( ATM_qs02_beg )
-ATM_mas_qs02_end  = ATM_stock_int ( ATM_qs02_end )
-ATM_mas_qs03_beg  = ATM_stock_int ( ATM_qs03_beg )
-ATM_mas_qs03_end  = ATM_stock_int ( ATM_qs03_end )
-ATM_mas_qs04_beg  = ATM_stock_int ( ATM_qs04_beg )
-ATM_mas_qs04_end  = ATM_stock_int ( ATM_qs04_end )
+     ATM_sno_beg       = ATM_sno_beg    [ATM_beg_keysort]
+     ATM_sno_end       = ATM_sno_end    [ATM_end_keysort]
+     ATM_qs_beg        = ATM_qs_beg     [ATM_beg_keysort]
+     ATM_qs_end        = ATM_qs_end     [ATM_end_keysort]
+     ATM_qsol_beg      = ATM_qsol_beg   [ATM_beg_keysort]
+     ATM_qsol_end      = ATM_qsol_end   [ATM_end_keysort]
+     ATM_qs01_beg      = ATM_qs01_beg   [ATM_beg_keysort]
+     ATM_qs01_end      = ATM_qs01_end   [ATM_end_keysort]
+     ATM_qs02_beg      = ATM_qs02_beg   [ATM_beg_keysort]
+     ATM_qs02_end      = ATM_qs02_end   [ATM_end_keysort]
+     ATM_qs03_beg      = ATM_qs03_beg   [ATM_beg_keysort]
+     ATM_qs03_end      = ATM_qs03_end   [ATM_end_keysort]
+     ATM_qs04_beg      = ATM_qs04_beg   [ATM_beg_keysort]
+     ATM_qs04_end      = ATM_qs04_end   [ATM_end_keysort]
+     LIC_sno_beg       = LIC_sno_beg    [ATM_beg_keysort]
+     LIC_sno_end       = LIC_sno_end    [ATM_end_keysort]
+     LIC_runlic0_beg   = LIC_runlic0_beg[ATM_beg_keysort]
+     LIC_runlic0_end   = LIC_runlic0_end[ATM_end_keysort]
+
+
+   
+LIC_qs_beg = ATM_qs02_beg
+LIC_qs_end = ATM_qs02_end
+
+ATM_mas_sno_beg     = ATM_stock_int ( ATM_sno_beg  )
+ATM_mas_sno_end     = ATM_stock_int ( ATM_sno_end  )
+
+ATM_mas_qs_beg      = ATM_stock_int ( ATM_qs_beg   )
+ATM_mas_qs_end      = ATM_stock_int ( ATM_qs_end   )
+ATM_mas_qsol_beg    = ATM_stock_int ( ATM_qsol_beg )
+ATM_mas_qsol_end    = ATM_stock_int ( ATM_qsol_end )
+ATM_mas_qs01_beg    = ATM_stock_int ( ATM_qs01_beg )
+ATM_mas_qs01_end    = ATM_stock_int ( ATM_qs01_end )
+ATM_mas_qs02_beg    = ATM_stock_int ( ATM_qs02_beg )
+ATM_mas_qs02_end    = ATM_stock_int ( ATM_qs02_end )
+ATM_mas_qs03_beg    = ATM_stock_int ( ATM_qs03_beg )
+ATM_mas_qs03_end    = ATM_stock_int ( ATM_qs03_end )
+ATM_mas_qs04_beg    = ATM_stock_int ( ATM_qs04_beg )
+ATM_mas_qs04_end    = ATM_stock_int ( ATM_qs04_end )
+
+LIC_mas_sno_beg     = ATM_stock_int ( LIC_sno_beg     )
+LIC_mas_sno_end     = ATM_stock_int ( LIC_sno_end     )
+LIC_mas_runlic0_beg = ATM_stock_int ( LIC_runlic0_beg )
+LIC_mas_runlic0_end = ATM_stock_int ( LIC_runlic0_end )
+
+LIC_mas_qs_beg  = ATM_mas_qs02_beg
+LIC_mas_qs_end  = ATM_mas_qs02_end
+LIC_mas_wat_beg = LIC_mas_qs_beg + LIC_mas_sno_beg
+LIC_mas_wat_end = LIC_mas_qs_end + LIC_mas_sno_end
 
 dATM_mas_sno  = ATM_mas_sno_end  - ATM_mas_sno_beg
@@ -691,18 +786,20 @@
 dATM_mas_qs04 = ATM_mas_qs04_end - ATM_mas_qs04_beg
 
-dATM_mas_sno_2 = ATM_stock_int ( ATM_sno_end - ATM_sno_beg )
-
-echo ( f'\nVariation du contenu en neige atmosphere (calottes)  -- {Title} ' )
+dLIC_mas_qs      = LIC_mas_qs_end      - LIC_mas_qs_beg
+dLIC_mas_sno     = LIC_mas_sno_end     - LIC_mas_sno_beg
+dLIC_mas_runlic0 = LIC_mas_runlic0_end - LIC_mas_runlic0_beg
+dLIC_mas_wat     = dLIC_mas_qs + dLIC_mas_sno
+
+echo ( f'\nChange of atmosphere snow content (Land ice) -- {Title} ' )
 echo ( '------------------------------------------------------------------------------------' )
 echo ( 'ATM_mas_sno_beg  = {:12.6e} kg | ATM_mas_sno_end  = {:12.6e} kg'.format (ATM_mas_sno_beg, ATM_mas_sno_end) )
 prtFlux ( 'dMass (neige atm) ', dATM_mas_sno  , 'e', True  )
-prtFlux ( 'dMass (neige atm) ', dATM_mas_sno_2, 'e', True  )
-
-echo ( f'\nVariation du contenu humidite du sol  -- {Title} ' )
+
+echo ( f'\nChange of soil humidity content -- {Title} ' )
 echo ( '------------------------------------------------------------------------------------' )
 echo ( 'ATM_mas_qs_beg  = {:12.6e} kg | ATM_mas_qs_end  = {:12.6e} kg'.format (ATM_mas_qs_beg, ATM_mas_qs_end) )
 prtFlux ( 'dMass (neige atm) ', dATM_mas_qs, 'e', True )
 
-echo ( f'\nVariation du contenu en eau+neige atmosphere  -- {Title}  ' )
+echo ( f'\nChange of atmosphere water+snow content -- {Title}  ' )
 echo ( '------------------------------------------------------------------------------------' )
 prtFlux ( 'dMass (eau + neige atm) ', dDYN_mas_wat + dATM_mas_sno , 'e', True)
@@ -715,30 +812,31 @@
     RUN_mas_wat_slow_beg   = ONE_stock_int ( d_RUN_beg ['slow_reservoir']   )
     RUN_mas_wat_stream_beg = ONE_stock_int ( d_RUN_beg ['stream_reservoir'] )
-    RUN_mas_wat_flood_beg  = 0.0
-    RUN_mas_wat_lake_beg   = 0.0
-    RUN_mas_wat_pond_beg   = 0.0
+    
+    RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  )
+    RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   )
+    RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   )
     
     RUN_mas_wat_fast_end   = ONE_stock_int ( d_RUN_end ['fast_reservoir']   )
     RUN_mas_wat_slow_end   = ONE_stock_int ( d_RUN_end ['slow_reservoir']   )
     RUN_mas_wat_stream_end = ONE_stock_int ( d_RUN_end ['stream_reservoir'] )
-    RUN_mas_wat_flood_end  = 0.0
-    RUN_mas_wat_lake_end   = 0.0
-    RUN_mas_wat_pond_end   = 0.0
-
-if Routing == 'SECHIBA' :
-    RUN_mas_wat_fast_beg   = ONE_stock_int ( d_SRF_beg ['fastres']   )
-    RUN_mas_wat_slow_beg   = ONE_stock_int ( d_SRF_beg ['slowres']   )
-    RUN_mas_wat_stream_beg = ONE_stock_int ( d_SRF_beg ['streamres'] )
-    RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  )
-    RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   )
-    RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   )
-
-    
-    RUN_mas_wat_fast_end   = ONE_stock_int ( d_SRF_end ['fastres']   )
-    RUN_mas_wat_slow_end   = ONE_stock_int ( d_SRF_end ['slowres']   )
-    RUN_mas_wat_stream_end = ONE_stock_int ( d_SRF_end ['streamres'] )
+    
     RUN_mas_wat_flood_end  = ONE_stock_int ( d_SRF_end ['floodres']  )
     RUN_mas_wat_lake_end   = ONE_stock_int ( d_SRF_end ['lakeres']   )
     RUN_mas_wat_pond_end   = ONE_stock_int ( d_SRF_end ['pondres']   )
+
+if Routing == 'SECHIBA' :
+        RUN_mas_wat_fast_beg   = ONE_stock_int ( d_SRF_beg ['fastres']   )
+        RUN_mas_wat_slow_beg   = ONE_stock_int ( d_SRF_beg ['slowres']   )
+        RUN_mas_wat_stream_beg = ONE_stock_int ( d_SRF_beg ['streamres'] )
+        RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  )
+        RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   )
+        RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   )
+        
+        RUN_mas_wat_fast_end   = ONE_stock_int ( d_SRF_end ['fastres']   )
+        RUN_mas_wat_slow_end   = ONE_stock_int ( d_SRF_end ['slowres']   )
+        RUN_mas_wat_stream_end = ONE_stock_int ( d_SRF_end ['streamres'] )
+        RUN_mas_wat_flood_end  = ONE_stock_int ( d_SRF_end ['floodres']  )
+        RUN_mas_wat_lake_end   = ONE_stock_int ( d_SRF_end ['lakeres']   )
+        RUN_mas_wat_pond_end   = ONE_stock_int ( d_SRF_end ['pondres']   )
 
 RUN_mas_wat_beg = RUN_mas_wat_fast_beg + RUN_mas_wat_slow_beg + RUN_mas_wat_stream_beg + RUN_mas_wat_flood_beg + RUN_mas_wat_lake_beg + RUN_mas_wat_pond_beg
@@ -754,12 +852,13 @@
 dRUN_mas_wat        = RUN_mas_wat_end        - RUN_mas_wat_beg
 
-echo ( f'\nLes differents reservoirs  -- {Title} ')
-echo ( '------------------------------------------------------------------------------------' )
-echo ( 'RUN_mas_wat_fast_beg   = {:12.6e} kg | RUN_mas_wat_fast_end   = {:12.6e} kg '.format (RUN_mas_wat_fast_beg  , RUN_mas_wat_fast_end   ) )
-echo ( 'RUN_mas_wat_slow_beg   = {:12.6e} kg | RUN_mas_wat_slow_end   = {:12.6e} kg '.format (RUN_mas_wat_slow_beg  , RUN_mas_wat_slow_end   ) )
-echo ( 'RUN_mas_wat_stream_beg = {:12.6e} kg | RUN_mas_wat_stream_end = {:12.6e} kg '.format (RUN_mas_wat_stream_beg, RUN_mas_wat_stream_end ) )
-echo ( 'RUN_mas_wat_flood_beg  = {:12.6e} kg | RUN_mas_wat_flood_end  = {:12.6e} kg '.format (RUN_mas_wat_flood_beg , RUN_mas_wat_flood_end  ) )
-echo ( 'RUN_mas_wat_lake_beg   = {:12.6e} kg | RUN_mas_wat_lake_end   = {:12.6e} kg '.format (RUN_mas_wat_lake_beg  , RUN_mas_wat_lake_end   ) )
-echo ( 'RUN_mas_wat_pond_beg   = {:12.6e} kg | RUN_mas_wat_pond_end   = {:12.6e} kg '.format (RUN_mas_wat_pond_beg  , RUN_mas_wat_pond_end   ) )
+echo ( f'\nRunoff reservoirs -- {Title} ')
+echo ( f'------------------------------------------------------------------------------------' )
+echo ( f'RUN_mas_wat_fast_beg   = {RUN_mas_wat_fast_beg  :12.6e} kg | RUN_mas_wat_fast_end   = {RUN_mas_wat_fast_end  :12.6e} kg ' )
+echo ( f'RUN_mas_wat_slow_beg   = {RUN_mas_wat_slow_beg  :12.6e} kg | RUN_mas_wat_slow_end   = {RUN_mas_wat_slow_end  :12.6e} kg ' )
+echo ( f'RUN_mas_wat_stream_beg = {RUN_mas_wat_stream_beg:12.6e} kg | RUN_mas_wat_stream_end = {RUN_mas_wat_stream_end:12.6e} kg ' )
+echo ( f'RUN_mas_wat_flood_beg  = {RUN_mas_wat_flood_beg :12.6e} kg | RUN_mas_wat_flood_end  = {RUN_mas_wat_flood_end :12.6e} kg ' )
+echo ( f'RUN_mas_wat_lake_beg   = {RUN_mas_wat_lake_beg  :12.6e} kg | RUN_mas_wat_lake_end   = {RUN_mas_wat_lake_end  :12.6e} kg ' )
+echo ( f'RUN_mas_wat_pond_beg   = {RUN_mas_wat_pond_beg  :12.6e} kg | RUN_mas_wat_pond_end   = {RUN_mas_wat_pond_end  :12.6e} kg ' )
+echo ( f'RUN_mas_wat_beg        = {RUN_mas_wat_beg       :12.6e} kg | RUN_mas_wat_end        = {RUN_mas_wat_end       :12.6e} kg ' )
 
 echo ( '------------------------------------------------------------------------------------' )
@@ -776,37 +875,37 @@
 echo ( '------------------------------------------------------------------------------------' )
 echo ( 'RUN_mas_wat_beg = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_end, RUN_mas_wat_end) )
-prtFlux ( 'dMass (routing) ', dRUN_mas_wat       )
+prtFlux ( 'dMass (routing) ', dRUN_mas_wat , 'e', True   )
 
 echo ( '\n====================================================================================' )
 print (f'Reading SRF restart')
-SRF_tot_watveg_beg  = d_SRF_beg['tot_watveg_beg']  ; SRF_tot_watveg_beg  = SRF_tot_watveg_beg .where (SRF_tot_watveg_beg < 1E15, 0.)
-SRF_tot_watsoil_beg = d_SRF_beg['tot_watsoil_beg'] ; SRF_tot_watsoil_beg = SRF_tot_watsoil_beg.where (SRF_tot_watsoil_beg< 1E15, 0.)
-SRF_snow_beg        = d_SRF_beg['snow_beg']        ; SRF_snow_beg        = SRF_snow_beg       .where (SRF_snow_beg       < 1E15, 0.)
-SRF_lakeres_beg     = d_SRF_beg['lakeres']         ; SRF_lakeres_beg     = SRF_lakeres_beg    .where (SRF_lakeres_beg    < 1E15, 0.)
-
-SRF_tot_watveg_end  = d_SRF_end['tot_watveg_beg']  ; SRF_tot_watveg_end  = SRF_tot_watveg_end .where (SRF_tot_watveg_end < 1E15, 0.)
-SRF_tot_watsoil_end = d_SRF_end['tot_watsoil_beg'] ; SRF_tot_watsoil_end = SRF_tot_watsoil_end.where (SRF_tot_watsoil_end< 1E15, 0.)
-SRF_snow_end        = d_SRF_end['snow_beg']        ; SRF_snow_end        = SRF_snow_end       .where (SRF_snow_end       < 1E15, 0.)
-SRF_lakeres_end     = d_SRF_end['lakeres']         ; SRF_lakeres_end     = SRF_lakeres_end    .where (SRF_lakeres_end    < 1E15, 0.)
+SRF_tot_watveg_beg  = d_SRF_beg['tot_watveg_beg']  ; SRF_tot_watveg_beg  = SRF_tot_watveg_beg .where (SRF_tot_watveg_beg  < 1E15, 0.)
+SRF_tot_watsoil_beg = d_SRF_beg['tot_watsoil_beg'] ; SRF_tot_watsoil_beg = SRF_tot_watsoil_beg.where (SRF_tot_watsoil_beg < 1E15, 0.)
+SRF_snow_beg        = d_SRF_beg['snow_beg']        ; SRF_snow_beg        = SRF_snow_beg       .where (SRF_snow_beg        < 1E15, 0.)
+SRF_lakeres_beg     = d_SRF_beg['lakeres']         ; SRF_lakeres_beg     = SRF_lakeres_beg    .where (SRF_lakeres_beg     < 1E15, 0.)
+
+SRF_tot_watveg_end  = d_SRF_end['tot_watveg_beg']  ; SRF_tot_watveg_end  = SRF_tot_watveg_end .where (SRF_tot_watveg_end  < 1E15, 0.)
+SRF_tot_watsoil_end = d_SRF_end['tot_watsoil_beg'] ; SRF_tot_watsoil_end = SRF_tot_watsoil_end.where (SRF_tot_watsoil_end < 1E15, 0.)
+SRF_snow_end        = d_SRF_end['snow_beg']        ; SRF_snow_end        = SRF_snow_end       .where (SRF_snow_end        < 1E15, 0.)
+SRF_lakeres_end     = d_SRF_end['lakeres']         ; SRF_lakeres_end     = SRF_lakeres_end    .where (SRF_lakeres_end     < 1E15, 0.)
 
 if LMDZ :
-    SRF_tot_watveg_beg  = lmdz.geo2point (SRF_tot_watveg_beg )
-    SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg)
-    SRF_snow_beg        = lmdz.geo2point (SRF_snow_beg       )
-    SRF_lakeres_beg     = lmdz.geo2point (SRF_lakeres_beg    )
-    SRF_tot_watveg_end  = lmdz.geo2point (SRF_tot_watveg_end )
-    SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end)
-    SRF_snow_end        = lmdz.geo2point (SRF_snow_end       )
-    SRF_lakeres_end     = lmdz.geo2point (SRF_lakeres_end    )
+    SRF_tot_watveg_beg  = lmdz.geo2point (SRF_tot_watveg_beg , dim1D='cell')
+    SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg, dim1D='cell')
+    SRF_snow_beg        = lmdz.geo2point (SRF_snow_beg       , dim1D='cell')
+    SRF_lakeres_beg     = lmdz.geo2point (SRF_lakeres_beg    , dim1D='cell')
+    SRF_tot_watveg_end  = lmdz.geo2point (SRF_tot_watveg_end , dim1D='cell')
+    SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end, dim1D='cell')
+    SRF_snow_end        = lmdz.geo2point (SRF_snow_end       , dim1D='cell')
+    SRF_lakeres_end     = lmdz.geo2point (SRF_lakeres_end    , dim1D='cell')
   
 if ICO :
-    SRF_tot_watveg_beg  = SRF_tot_watveg_beg .rename ( {'y':'cell_mesh'} )
-    SRF_tot_watsoil_beg = SRF_tot_watsoil_beg.rename ( {'y':'cell_mesh'} )
-    SRF_snow_beg        = SRF_snow_beg       .rename ( {'y':'cell_mesh'} )
-    SRF_lakeres_beg     = SRF_lakeres_beg    .rename ( {'y':'cell_mesh'} )
-    SRF_tot_watveg_end  = SRF_tot_watveg_end .rename ( {'y':'cell_mesh'} )
-    SRF_tot_watsoil_end = SRF_tot_watsoil_end.rename ( {'y':'cell_mesh'} )
-    SRF_snow_end        = SRF_snow_end       .rename ( {'y':'cell_mesh'} )
-    SRF_lakeres_end     = SRF_lakeres_end    .rename ( {'y':'cell_mesh'} )
+    SRF_tot_watveg_beg  = SRF_tot_watveg_beg  [SRF_beg_keysort]
+    SRF_tot_watsoil_beg = SRF_tot_watsoil_beg [SRF_beg_keysort]
+    SRF_snow_beg        = SRF_snow_beg        [SRF_beg_keysort]
+    SRF_lakeres_beg     = SRF_lakeres_beg     [SRF_beg_keysort]
+    SRF_tot_watveg_end  = SRF_tot_watveg_end  [SRF_end_keysort]
+    SRF_tot_watsoil_end = SRF_tot_watsoil_end [SRF_end_keysort]
+    SRF_snow_end        = SRF_snow_end        [SRF_end_keysort]
+    SRF_lakeres_end     = SRF_lakeres_end     [SRF_end_keysort]
 
 # Stock dSoilHum dInterce dSWE dStream dFastR dSlowR dLake dPond dFlood
@@ -844,11 +943,10 @@
 
 
-
 echo ( '------------------------------------------------------------------------------------' )
-echo ( f'\nLes differents reservoirs  -- {Title} ')
-echo ( 'SRF_mas_watveg_beg   = {:12.6e} kg | SRF_mas_watveg_end   = {:12.6e} kg '.format (SRF_mas_watveg_beg  , SRF_mas_watveg_end   ) )
-echo ( 'SRF_mas_watsoil_beg  = {:12.6e} kg | SRF_mas_watsoil_end  = {:12.6e} kg '.format (SRF_mas_watsoil_beg , SRF_mas_watsoil_end  ) )
-echo ( 'SRF_mas_snow_beg     = {:12.6e} kg | SRF_mas_snow_end     = {:12.6e} kg '.format (SRF_mas_snow_beg    , SRF_mas_snow_end     ) )
-echo ( 'SRF_mas_lake_beg     = {:12.6e} kg | SRF_mas_lake_end     = {:12.6e} kg '.format (SRF_mas_lake_beg    , SRF_mas_lake_end     ) )
+echo ( f'\nSurface reservoirs  -- {Title} ')
+echo ( f'SRF_mas_watveg_beg   = {SRF_mas_watveg_beg :12.6e} kg | SRF_mas_watveg_end   = {SRF_mas_watveg_end :12.6e} kg ' )
+echo ( f'SRF_mas_watsoil_beg  = {SRF_mas_watsoil_beg:12.6e} kg | SRF_mas_watsoil_end  = {SRF_mas_watsoil_end:12.6e} kg ' )
+echo ( f'SRF_mas_snow_beg     = {SRF_mas_snow_beg   :12.6e} kg | SRF_mas_snow_end     = {SRF_mas_snow_end   :12.6e} kg ' )
+echo ( f'SRF_mas_lake_beg     = {SRF_mas_lake_beg   :12.6e} kg | SRF_mas_lake_end     = {SRF_mas_lake_end   :12.6e} kg ' )
 
 prtFlux ('dMass (watveg) ', dSRF_mas_watveg , 'e' , True)
@@ -863,5 +961,5 @@
 echo ( '------------------------------------------------------------------------------------' )
 echo ( f'Water content in surface  -- {Title} ' )
-echo ( 'SRF_mas_wat_beg   = {:12.6e} kg | SRF_mas_wat_end  = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) )
+echo ( f'SRF_mas_wat_beg   = {SRF_mas_wat_beg:12.6e} kg | SRF_mas_wat_end  = {SRF_mas_wat_end:12.6e} kg ')
 prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', True )
 
@@ -876,42 +974,105 @@
 echo ( f'-- ATM Fluxes  -- {Title} ' )
 
-ATM_wbilo_oce   = lmdz.geo2point ( d_ATM_his ['wbilo_oce']   )
-ATM_wbilo_sic   = lmdz.geo2point ( d_ATM_his ['wbilo_sic']   )
-ATM_wbilo_ter   = lmdz.geo2point ( d_ATM_his ['wbilo_ter']   )
-ATM_wbilo_lic   = lmdz.geo2point ( d_ATM_his ['wbilo_lic']   )
-ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic']   )
-ATM_fqcalving   = lmdz.geo2point ( d_ATM_his ['fqcalving']   )
-ATM_fqfonte     = lmdz.geo2point ( d_ATM_his ['fqfonte']     )
-ATM_precip      = lmdz.geo2point ( d_ATM_his ['precip']      )
-ATM_snowf       = lmdz.geo2point ( d_ATM_his ['snow']        )
-ATM_evap        = lmdz.geo2point ( d_ATM_his ['evap']        )
+print ( 'Step 1', end='' )
+if ATM_HIS == 'latlon' :
+    ATM_wbilo_oce   = lmdz.geo2point ( d_ATM_his ['wbilo_oce'], dim1D='cell' )
+    ATM_wbilo_sic   = lmdz.geo2point ( d_ATM_his ['wbilo_sic'], dim1D='cell' )
+    ATM_wbilo_ter   = lmdz.geo2point ( d_ATM_his ['wbilo_ter'], dim1D='cell' )
+    ATM_wbilo_lic   = lmdz.geo2point ( d_ATM_his ['wbilo_lic'], dim1D='cell' )
+    ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell' )
+    ATM_fqcalving   = lmdz.geo2point ( d_ATM_his ['fqcalving'], dim1D='cell' )
+    ATM_fqfonte     = lmdz.geo2point ( d_ATM_his ['fqfonte']  , dim1D='cell' )
+    ATM_precip      = lmdz.geo2point ( d_ATM_his ['precip']   , dim1D='cell' )
+    ATM_snowf       = lmdz.geo2point ( d_ATM_his ['snow']     , dim1D='cell' )
+    ATM_evap        = lmdz.geo2point ( d_ATM_his ['evap']     , dim1D='cell' )
+    ATM_wevap_ter   = lmdz.geo2point ( d_ATM_his ['wevap_ter'], dim1D='cell' )
+    ATM_wevap_oce   = lmdz.geo2point ( d_ATM_his ['wevap_oce'], dim1D='cell' )
+    ATM_wevap_lic   = lmdz.geo2point ( d_ATM_his ['wevap_lic'], dim1D='cell' )
+    ATM_wevap_sic   = lmdz.geo2point ( d_ATM_his ['wevap_sic'], dim1D='cell' )
+    ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell' )
+    
+print ( ' - Step 2', end='' )
+if ATM_HIS == 'ico' :
+    ATM_wbilo_oce   = d_ATM_his ['wbilo_oce'][..., ATM_his_keysort]
+    ATM_wbilo_sic   = d_ATM_his ['wbilo_sic'][..., ATM_his_keysort]
+    ATM_wbilo_ter   = d_ATM_his ['wbilo_ter'][..., ATM_his_keysort]
+    ATM_wbilo_lic   = d_ATM_his ['wbilo_lic'][..., ATM_his_keysort]
+    ATM_runofflic   = d_ATM_his ['runofflic'][..., ATM_his_keysort]
+    ATM_fqcalving   = d_ATM_his ['fqcalving'][..., ATM_his_keysort]
+    ATM_fqfonte     = d_ATM_his ['fqfonte']  [..., ATM_his_keysort]
+    ATM_precip      = d_ATM_his ['precip']   [..., ATM_his_keysort]
+    ATM_snowf       = d_ATM_his ['snow']     [..., ATM_his_keysort]
+    ATM_evap        = d_ATM_his ['evap']     [..., ATM_his_keysort]
+    ATM_wevap_ter   = d_ATM_his ['wevap_ter'][..., ATM_his_keysort]
+    ATM_wevap_oce   = d_ATM_his ['wevap_oce'][..., ATM_his_keysort]
+    ATM_wevap_lic   = d_ATM_his ['wevap_lic'][..., ATM_his_keysort]
+    ATM_wevap_sic   = d_ATM_his ['wevap_sic'][..., ATM_his_keysort]
+    ATM_runofflic   = d_ATM_his ['runofflic'][..., ATM_his_keysort]
+
+print ( ' - Step 3', end='' )
 ATM_wbilo       = ATM_wbilo_oce + ATM_wbilo_sic + ATM_wbilo_ter + ATM_wbilo_lic
 ATM_emp         = ATM_evap - ATM_precip
-
-RUN_coastalflow = lmdz.geo2point ( d_RUN_his ['coastalflow'] ) 
-RUN_riverflow   = lmdz.geo2point ( d_RUN_his ['riverflow']   )
-RUN_runoff      = lmdz.geo2point ( d_RUN_his ['runoff']      )
-RUN_drainage    = lmdz.geo2point ( d_RUN_his ['drainage']    )
-RUN_riversret   = lmdz.geo2point ( d_RUN_his ['riversret']   )
-
-RUN_coastalflow_cpl = lmdz.geo2point ( d_RUN_his ['coastalflow_cpl'] ) 
-RUN_riverflow_cpl   = lmdz.geo2point ( d_RUN_his ['riverflow_cpl']   )
-
-SRF_rain     = lmdz.geo2point ( d_SRF_his ['rain']  )
-SRF_evap     = lmdz.geo2point ( d_SRF_his ['evap']  )
-SRF_snowf    = lmdz.geo2point ( d_SRF_his ['snowf'] )
-SRF_subli    = lmdz.geo2point ( d_SRF_his ['subli'] )
-SRF_transpir = lmdz.geo2point ( np.sum(d_SRF_his ['transpir'], axis=1) ) ; SRF_transpir.attrs['units'] = d_SRF_his ['transpir'].attrs['units']
+ATM_wbilo_sea   = ATM_wbilo_oce + ATM_wbilo_sic
+ATM_wevap_sea   = ATM_wevap_sic + ATM_wevap_oce
+
+ATM_wemp_ter = ATM_wevap_ter - ATM_precip * ATM_fter
+ATM_wemp_oce = ATM_wevap_oce - ATM_precip * ATM_foce
+ATM_wemp_sic = ATM_wevap_sic - ATM_precip * ATM_fsic
+ATM_wemp_lic = ATM_wevap_lic - ATM_precip * ATM_flic
+ATM_wemp_sea = ATM_wevap_sic + ATM_wevap_oce - ATM_precip * ATM_fsea
+
+print ( ' - Step 4', end='' )
+if RUN_HIS == 'latlon' : 
+    RUN_coastalflow = lmdz.geo2point ( d_RUN_his ['coastalflow'], dim1D='cell' ) 
+    RUN_riverflow   = lmdz.geo2point ( d_RUN_his ['riverflow']  , dim1D='cell' )
+    RUN_runoff      = lmdz.geo2point ( d_RUN_his ['runoff']     , dim1D='cell' )
+    RUN_drainage    = lmdz.geo2point ( d_RUN_his ['drainage']   , dim1D='cell' )
+    RUN_riversret   = lmdz.geo2point ( d_RUN_his ['riversret']  , dim1D='cell' )
+    
+    RUN_coastalflow_cpl = lmdz.geo2point ( d_RUN_his ['coastalflow_cpl'], dim1D='cell' ) 
+    RUN_riverflow_cpl   = lmdz.geo2point ( d_RUN_his ['riverflow_cpl']  , dim1D='cell' )
+
+print ( ' - Step 5', end='' )
+if RUN_HIS == 'ico' :
+    RUN_coastalflow =  d_RUN_his ['coastalflow'][..., RUN_his_keysort]
+    RUN_riverflow   =  d_RUN_his ['riverflow']  [..., RUN_his_keysort]
+    RUN_runoff      =  d_RUN_his ['runoff']     [..., RUN_his_keysort]
+    RUN_drainage    =  d_RUN_his ['drainage']   [..., RUN_his_keysort]
+    RUN_riversret   =  d_RUN_his ['riversret']  [..., RUN_his_keysort]
+    
+    RUN_coastalflow_cpl = d_RUN_his ['coastalflow_cpl'][..., RUN_his_keysort]
+    RUN_riverflow_cpl   = d_RUN_his ['riverflow_cpl']  [..., RUN_his_keysort]
+
+print ( ' - Step 6', end='' )
+if SRF_HIS == 'latlon' :
+    SRF_rain     = lmdz.geo2point ( d_SRF_his ['rain']  , dim1D='cell')
+    SRF_evap     = lmdz.geo2point ( d_SRF_his ['evap']  , dim1D='cell')
+    SRF_snowf    = lmdz.geo2point ( d_SRF_his ['snowf'] , dim1D='cell')
+    SRF_subli    = lmdz.geo2point ( d_SRF_his ['subli'] , dim1D='cell')
+    SRF_transpir = lmdz.geo2point ( np.sum (d_SRF_his ['transpir'], axis=1), dim1D='cell' )
+
+print ( '- Step 7', end='' )
+if SRF_HIS == 'ico' :
+    SRF_rain     = d_SRF_his ['rain'] [..., SRF_his_keysort]
+    SRF_evap     = d_SRF_his ['evap'] [..., SRF_his_keysort]
+    SRF_snowf    = d_SRF_his ['snowf'][..., SRF_his_keysort]
+    SRF_subli    = d_SRF_his ['subli'][..., SRF_his_keysort]
+    SRF_transpir = np.sum (d_SRF_his ['transpir'], axis=1)[..., SRF_his_keysort]
+
+print ( '- Step 8', end='' )
+SRF_transpir.attrs['units'] = d_SRF_his ['transpir'].attrs['units']
 SRF_emp      = SRF_evap - SRF_rain - SRF_snowf ; SRF_emp.attrs['units'] = SRF_rain.attrs['units']
-
+    
 ## Correcting units of SECHIBA variables
 def mmd2SI ( Var ) :
     '''Change unit from mm/d or m^3/s to kg/s if needed'''
     if 'units' in VarT.attrs : 
-        if VarT.attrs['units'] in ['m^3/s', 'm3/s', 'm3.s-3'] :
+        if VarT.attrs['units'] in ['m^3/s', 'm3/s', 'm3.s-1',] :
             VarT.values = VarT.values  * ATM_rho                 ;  VarT.attrs['units'] = 'kg/s'
         if VarT.attrs['units'] == 'mm/d' :
             VarT.values = VarT.values  * ATM_rho * (1e-3/86400.) ;  VarT.attrs['units'] = 'kg/s'
-
+        if VarT.attrs['units'] in ['m^3', 'm3', ] :
+            VarT.values = VarT.values  * ATM_rho                 ;  VarT.attrs['units'] = 'kg'
+            
 for var in [ 'runoff', 'drainage', 'riversret', 'coastalflow', 'riverflow', 'coastalflow_cpl', 'riverflow_cpl' ] :
     VarT = locals()['RUN_' + var]
@@ -922,17 +1083,19 @@
     mmd2SI (VarT)
 
-
+print ( '- Step 9', end='' )
 RUN_input  = RUN_runoff      + RUN_drainage
 RUN_output = RUN_coastalflow + RUN_riverflow
 
-ATM_wbilo_sea = ATM_wbilo_oce + ATM_wbilo_sic
-
-ATM_flx_oce         = ATM_flux_int ( ATM_wbilo_oce  )
-ATM_flx_sic         = ATM_flux_int ( ATM_wbilo_sic  )
-ATM_flx_sea         = ATM_flux_int ( ATM_wbilo_sea  )
-ATM_flx_ter         = ATM_flux_int ( ATM_wbilo_ter  )
-ATM_flx_lic         = ATM_flux_int ( ATM_wbilo_lic  )
+print ( '- Step 10', end='' )
+ATM_flx_wbilo       = ATM_flux_int ( ATM_wbilo      )
+ATM_flx_wbilo_oce   = ATM_flux_int ( ATM_wbilo_oce  )
+ATM_flx_wbilo_sic   = ATM_flux_int ( ATM_wbilo_sic  )
+ATM_flx_wbilo_sea   = ATM_flux_int ( ATM_wbilo_sea  )
+ATM_flx_wbilo_ter   = ATM_flux_int ( ATM_wbilo_ter  )
+ATM_flx_wbilo_lic   = ATM_flux_int ( ATM_wbilo_lic  )
 ATM_flx_calving     = ATM_flux_int ( ATM_fqcalving  )
-ATM_flx_qfonte      = ATM_flux_int ( ATM_fqfonte    )
+ATM_flx_fqfonte     = ATM_flux_int ( ATM_fqfonte    )
+
+print ( '- Step 11', end='' )
 ATM_flx_precip      = ATM_flux_int ( ATM_precip     )
 ATM_flx_snowf       = ATM_flux_int ( ATM_snowf      )
@@ -940,4 +1103,16 @@
 ATM_flx_runlic      = ATM_flux_int ( ATM_runofflic  )
 
+print ( '- Step 12', end='' )
+ATM_flx_wevap_ter   = ATM_flux_int ( ATM_wevap_ter )
+ATM_flx_wevap_sea   = ATM_flux_int ( ATM_wevap_sea )
+ATM_flx_precip_ter  = ATM_flux_int ( ATM_precip * ATM_fter )
+ATM_flx_precip_sea  = ATM_flux_int ( ATM_precip * ATM_fsea )
+ATM_flx_emp         = ATM_flux_int ( ATM_emp)
+ATM_flx_wemp_ter    = ATM_flux_int ( ATM_wemp_ter )
+ATM_flx_wemp_oce    = ATM_flux_int ( ATM_wemp_oce )
+ATM_flx_wemp_lic    = ATM_flux_int ( ATM_wemp_lic )
+ATM_flx_wemp_sea    = ATM_flux_int ( ATM_wemp_sea )
+
+print ( '- Step 13', end='' )
 RUN_flx_coastal     = ONE_flux_int ( RUN_coastalflow)
 RUN_flx_river       = ONE_flux_int ( RUN_riverflow  )
@@ -950,20 +1125,17 @@
 RUN_flx_output      = ONE_flux_int ( RUN_output     )
 
-ATM_flx_emp   = ATM_flux_int (ATM_emp)
-ATM_flx_wbilo = ATM_flux_int (ATM_wbilo)
-
-RUN_flx_bil   = RUN_flx_input - RUN_flx_output
+print ( '- Step 14' )
+RUN_flx_bil    = RUN_flx_input   - RUN_flx_output
 RUN_flx_rivcoa = RUN_flx_coastal + RUN_flx_river
 
-prtFlux ('wbilo_oce     ', ATM_flx_oce, 'f' )
-prtFlux ('wbilo_oce     ', ATM_flx_oce, 'f' )          
-prtFlux ('wbilo_sic     ', ATM_flx_sic, 'f' )          
-prtFlux ('wbilo_sic+oce ', ATM_flx_sea, 'f' )          
-prtFlux ('wbilo_ter     ', ATM_flx_ter, 'f' )          
-prtFlux ('wbilo_lic     ', ATM_flx_lic, 'f' )          
+prtFlux ('wbilo_oce     ', ATM_flx_wbilo_oce  , 'f' )          
+prtFlux ('wbilo_sic     ', ATM_flx_wbilo_sic  , 'f' )          
+prtFlux ('wbilo_sic+oce ', ATM_flx_wbilo_sea  , 'f' )          
+prtFlux ('wbilo_ter     ', ATM_flx_wbilo_ter  , 'f' )          
+prtFlux ('wbilo_lic     ', ATM_flx_wbilo_lic  , 'f' )          
 prtFlux ('Sum wbilo_*   ', ATM_flx_wbilo      , 'f', True)  
 prtFlux ('E-P           ', ATM_flx_emp        , 'f', True)  
 prtFlux ('calving       ', ATM_flx_calving    , 'f' ) 
-prtFlux ('fqfonte       ', ATM_flx_qfonte     , 'f' )       
+prtFlux ('fqfonte       ', ATM_flx_fqfonte    , 'f' )       
 prtFlux ('precip        ', ATM_flx_precip     , 'f' )       
 prtFlux ('snowf         ', ATM_flx_snowf      , 'f' )        
@@ -982,25 +1154,61 @@
 prtFlux ('runoff lic    ', ATM_flx_runlic     , 'f' )   
 
-ATM_flx_budget = -ATM_flx_sea + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_qfonte + RUN_flx_river
+ATM_flx_budget = -ATM_flx_wbilo + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_fqfonte + RUN_flx_river
 echo ('')
-echo ('  Global        {:12.3e} kg | {:12.4f} Sv | {:12.4f} m '.format ( ATM_flx_budget , ATM_flx_budget / dtime_sec*1E-9, ATM_flx_budget /ATM_aire_sea_tot/ATM_rho ))
+#echo ('  Global        {:12.3e} kg | {:12.4f} Sv | {:12.4f} m '.format ( ATM_flx_budget , ATM_flx_budget / dtime_sec*1E-9, ATM_flx_budget /ATM_aire_sea_tot/ATM_rho ))
 
 #echo ('  E-P-R         {:12.3e} kg | {:12.4e} Sv | {:12.4f} m '.format ( ATM_flx_emp      , ATM_flx_emp      / dtime_sec*1E-6/ATM_rho, ATM_flx_emp      /ATM_aire_sea_tot/ATM_rho ))
+
+ATM_flx_toSRF = -ATM_flx_wbilo_ter
 
 echo (' ')
 echo ( '\n====================================================================================' )
 echo ( f'--  Atmosphere  -- {Title} ' )
-echo ( 'Mass begin = {:12.6e} kg | Mass end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) )
-echo ( 'dmass (atm)  = {:12.3e} kg | {:12.4e} Sv | {:12.4f} mm/year '.format ( dDYN_mas_wat , kg2Sv(dDYN_mas_wat) , kg2myear(dDYN_mas_wat )*1000. ))
-echo ( 'Sum wbilo_*  = {:12.3e} kg | {:12.4e} Sv | {:12.4f} mm/year '.format ( ATM_flx_wbilo, kg2Sv(ATM_flx_wbilo), kg2myear(ATM_flx_wbilo )*1000. ))
-echo ( 'E-P          = {:12.3e} kg | {:12.4e} Sv | {:12.4f} mm/year '.format ( ATM_flx_emp  , kg2Sv(ATM_flx_emp ) , kg2myear(ATM_flx_emp  )*1000. ))
+echo ( f'Mass begin = {DYN_mas_wat_beg:12.6e} kg | Mass end = {DYN_mas_wat_end:12.6e} kg' )
+prtFlux ( 'dmass (atm)  = ', dDYN_mas_wat , 'e', True )
+prtFlux ( 'Sum wbilo_*  = ', ATM_flx_wbilo, 'e', True )
+prtFlux ( 'E-P          = ', ATM_flx_emp  , 'e', True )
 echo ( ' ' )
-prtFlux ( 'Perte eau atm ', ATM_flx_wbilo - dDYN_mas_wat, 'e', True )
-echo ( 'Perte eau atm = {:12.3e} (rel)  '.format ( (ATM_flx_wbilo - dDYN_mas_wat)/dDYN_mas_wat  ) )
+prtFlux ( 'Water loss atm', ATM_flx_wbilo - dDYN_mas_wat, 'f', True )
+echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_wbilo - dDYN_mas_wat)/dDYN_mas_wat  ) )
 
 echo (' ')
-prtFlux ( 'Perte eau atm', ATM_flx_emp  - dDYN_mas_wat , 'e', True )
-echo ( 'Perte eau atm = {:12.3e} (rel)  '.format ( (ATM_flx_emp-dDYN_mas_wat)/dDYN_mas_wat  ) )
+prtFlux ( 'Water loss atm', ATM_flx_emp  - dDYN_mas_wat , 'f', True )
+echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_emp-dDYN_mas_wat)/dDYN_mas_wat  ) )
 echo (' ')
+
+echo (' ')
+echo ( '\n====================================================================================' )
+
+ATM_flx_runofflic_lic = ATM_flux_int ( ATM_runofflic * ATM_flic )
+
+LIC_flx_budget1 = -ATM_flx_wemp_lic  - ATM_flx_calving - ATM_flx_fqfonte
+LIC_flx_budget2 = -ATM_flx_wbilo_lic - ATM_flx_calving - ATM_flx_fqfonte
+LIC_flx_budget3 = -ATM_flx_wbilo_lic - ATM_flx_runofflic_lic
+
+echo ( f'--  LIC  -- {Title} ' )
+echo ( f'Mass total   begin = {LIC_mas_wat_beg    :12.6e} kg | Mass end = {LIC_mas_wat_end    :12.6e} kg' )
+echo ( f'Mass snow    begin = {LIC_mas_sno_beg    :12.6e} kg | Mass end = {LIC_mas_sno_end    :12.6e} kg' )
+echo ( f'Mass qs      begin = {LIC_mas_qs_beg     :12.6e} kg | Mass end = {LIC_mas_qs_end     :12.6e} kg' )
+echo ( f'Mass runlic0 begin = {LIC_mas_runlic0_beg:12.6e} kg | Mass end = {LIC_mas_runlic0_end:12.6e} kg' )
+prtFlux ( 'dmass (LIC sno)       ', dLIC_mas_sno          , 'f', True, width=65 )
+prtFlux ( 'dmass (LIC qs)        ', dLIC_mas_qs           , 'e', True, width=65 )
+prtFlux ( 'dmass (LIC wat)       ', dLIC_mas_wat          , 'f', True, width=65 )
+prtFlux ( 'dmass (LIC runlic0)   ', dLIC_mas_runlic0      , 'e', True, width=65 )
+prtFlux ( 'dmass (LIC total)     ', dLIC_mas_wat          , 'e', True, width=65 )
+prtFlux ( 'LIC ATM_flx_wemp_lic  ', ATM_flx_wemp_lic      , 'f', True, width=65 )
+prtFlux ( 'LIC ATM_flx_fqfonte   ', ATM_flx_fqfonte       , 'f', True, width=65 )
+prtFlux ( 'LIC ATM_flx_calving   ', ATM_flx_calving       , 'f', True, width=65 )
+prtFlux ( 'LIC ATM_flx_runofflic ', ATM_flx_runofflic_lic , 'f', True, width=65 )
+prtFlux ( 'LIC fqfonte + calving ', ATM_flx_calving+ATM_flx_fqfonte , 'f', True, width=65 )
+prtFlux ( 'LIC fluxes 1 (wevap - precip*frac_lic  - fqcalving - fqfonte) ', LIC_flx_budget1              , 'f', True, width=65 )
+prtFlux ( 'LIC fluxes 2 (-wbilo_lic - fqcalving - fqfonte)               ', LIC_flx_budget2              , 'f', True, width=65 )
+prtFlux ( 'LIC fluxes 3 (-wbilo_lic - runofflic*frac_lic)                ', LIC_flx_budget3              , 'f', True, width=65 )
+prtFlux ( 'LIC error 1                                                   ', LIC_flx_budget1-dLIC_mas_wat , 'e', True, width=65 )
+prtFlux ( 'LIC error 2                                                   ', LIC_flx_budget2-dLIC_mas_wat , 'e', True, width=65 )
+prtFlux ( 'LIC error 3                                                   ', LIC_flx_budget3-dLIC_mas_wat , 'e', True, width=65 )
+echo ( 'LIC error (wevap - precip*frac_lic  - fqcalving - fqfonte)    = {:12.4e} (rel) '.format ( (LIC_flx_budget1-dLIC_mas_wat)/dLIC_mas_wat) )
+echo ( 'LIC error (-wbilo_lic - fqcalving - fqfonte)                  = {:12.4e} (rel) '.format ( (LIC_flx_budget2-dLIC_mas_wat)/dLIC_mas_wat) )
+echo ( 'LIC error (-wbilo_lic - runofflic*frac_lic)                   = {:12.4e} (rel) '.format ( (LIC_flx_budget3-dLIC_mas_wat)/dLIC_mas_wat) )
 
 echo ( '\n====================================================================================' )
@@ -1019,18 +1227,27 @@
 SRF_flx_all = SRF_flx_rain + SRF_flx_snowf - SRF_flx_evap - RUN_flx_runoff - RUN_flx_drainage
 
-prtFlux ('rain       ', SRF_flx_rain     , 'f' )
-prtFlux ('evap       ', SRF_flx_evap     , 'f' )
-prtFlux ('snowf      ', SRF_flx_snowf    , 'f' )
-prtFlux ('E-P        ', SRF_flx_emp      , 'f' )
-prtFlux ('subli      ', SRF_flx_subli    , 'f' )
-prtFlux ('transpir   ', SRF_flx_transpir , 'f' )
-prtFlux ('to routing ', RUN_flx_torouting, 'f' )
-prtFlux ('budget     ', SRF_flx_all      , 'f', True )
+prtFlux ('rain         ', SRF_flx_rain       , 'f' )
+prtFlux ('evap         ', SRF_flx_evap       , 'f' )
+prtFlux ('snowf        ', SRF_flx_snowf      , 'f' )
+prtFlux ('E-P          ', SRF_flx_emp        , 'f' )
+prtFlux ('subli        ', SRF_flx_subli      , 'f' )
+prtFlux ('transpir     ', SRF_flx_transpir   , 'f' )
+prtFlux ('to routing   ', RUN_flx_torouting  , 'f' )
+prtFlux ('budget       ', SRF_flx_all        , 'f', small=True )
 
 echo ( '\n------------------------------------------------------------------------------------' )
 echo ( 'Water content in surface ' )
-echo ( 'SRF_mas_wat_beg  = {:12.6e} kg | SRF_mas_wat_end  = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) )
-prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', True)
+echo ( f'SRF_mas_wat_beg  = {SRF_mas_wat_beg:12.6e} kg | SRF_mas_wat_end  = {SRF_mas_wat_end:12.6e} kg ' )
+prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', small=True)
+prtFlux ( 'Error            ',  SRF_flx_all-dSRF_mas_wat, 'e', small=True )
 echo ( 'dMass (water srf) = {:12.4e} (rel)   '.format ( (SRF_flx_all-dSRF_mas_wat)/dSRF_mas_wat) )
+
+echo ( '\n====================================================================================' )
+echo ( f'-- Check ATM vs. SRF -- {Title} ' )
+prtFlux ('E-P ATM       ', ATM_flx_wemp_ter   , 'f' )
+prtFlux ('wbilo ter     ', ATM_flx_wbilo_ter  , 'f' )
+prtFlux ('E-P SRF       ', SRF_flx_emp        , 'f' )
+prtFlux ('SRF/ATM error ', ATM_flx_wbilo_ter - SRF_flx_emp, 'e', True)
+echo ( 'SRF/ATM error {:12.3e} (rel)  '.format ( (ATM_flx_wbilo_ter - SRF_flx_emp)/SRF_flx_emp ) )
 
 echo ('')
@@ -1044,18 +1261,23 @@
 prtFlux ('coastal   ', RUN_flx_coastal     , 'f' ) 
 prtFlux ('riv+coa   ', RUN_flx_fromrouting , 'f' ) 
-prtFlux ('budget    ', RUN_flx_all         , 'f' , True)
+prtFlux ('budget    ', RUN_flx_all         , 'f' , small=True)
+
+echo ( '\n------------------------------------------------------------------------------------' )
+echo ( f'Water content in routing+lake  -- {Title} ' )
+echo ( f'RUN_mas_wat_beg  = {RUN_mas_wat_beg:12.6e} kg | RUN_mas_wat_end = {RUN_mas_wat_end:12.6e} kg ' )
+prtFlux ( 'dMass (routing)  ', dRUN_mas_wat+dSRF_mas_lake, 'f', small=True)
+prtFlux ( 'Routing error    ', RUN_flx_all+dSRF_mas_lake-dRUN_mas_wat, 'e', small=True )
+echo ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dSRF_mas_lake-dRUN_mas_wat)/(dRUN_mas_wat+dSRF_mas_lake) ) )
 
 echo ( '\n------------------------------------------------------------------------------------' )
 echo ( f'Water content in routing  -- {Title} ' )
-echo ( 'RUN_mas_wat_beg  = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_beg, RUN_mas_wat_end) )
-prtFlux ( 'dMass (routing)  ', dRUN_mas_wat+dSRF_mas_lake, 'f', True)
-
-echo ( '\n------------------------------------------------------------------------------------' )
-echo ( f'Water content in routing  -- {Title} ' )
-echo ( 'RUN_mas_wat_beg  = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_beg, RUN_mas_wat_end) )
-prtFlux ( 'dMass (routing)  ', dRUN_mas_wat, 'f', True  )
-
-print ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dRUN_mas_wat)/dRUN_mas_wat ) )
+echo ( f'RUN_mas_wat_beg  = {RUN_mas_wat_beg:12.6e} kg | RUN_mas_wat_end = {RUN_mas_wat_end:12.6e} kg ' )
+prtFlux ( 'dMass (routing) ', dRUN_mas_wat, 'f', small=True  )
+prtFlux ( 'Routing error   ', RUN_flx_all-dRUN_mas_wat, 'e', small=True)
+echo ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dRUN_mas_wat)/dRUN_mas_wat ) )
 
 # PRINT *,"routing water Balance ;  before : ",Â water_balance_before," ; after : ",water_balance_after,  &a
 # 1150	            " ; delta : ",Â 100*(water_balance_after-water_balance_before)/(0.5*(water_balance_after+water_balance_before)),"%"
+
+echo ( ' ' )
+echo ( f'{Title = }' )
Index: TOOLS/WATER_BUDGET/CPL_waterbudget.py
===================================================================
--- TOOLS/WATER_BUDGET/CPL_waterbudget.py	(revision 6446)
+++ TOOLS/WATER_BUDGET/CPL_waterbudget.py	(revision 6508)
@@ -22,155 +22,180 @@
 ###
 ## Import system modules
-import sys, os, shutil, subprocess
+import sys, os, shutil, subprocess, platform
 import numpy as np
 import configparser, re
-
-## Creates parser
-config = configparser.ConfigParser()
+from pathlib import Path
+
+# Check python version
+if sys.version_info < (3, 8, 0) :
+    print ( f'Python version : {platform.python_version()}' ) 
+    raise Exception ( "Minimum Python version is 3.8" )
+
+## Import local module
+import WaterUtils as wu
+
+## Creates parser for reading .ini input file
+config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() )
 config.optionxform = str # To keep capitals
 
-config['Files']  = {}
-config['System'] = {}
-
-##-- Some physical constants
-#-- Earth Radius
-Ra = 6366197.7236758135
-#-- Gravity
-grav = 9.81
-#-- Ice volumic mass (kg/m3) in LIM3/SI3
-ICE_rho_ice = 917.0
-#-- Snow volumic mass (kg/m3) in LIM3/SI3
-ICE_rho_sno = 330.0
-#-- Water in ponds coluclic mass (kg/m3) in LIM3/SI3
-ICE_rho_pnd = 1000.
-#-- Ocean water volumic mass (kg/m3) in NEMO
-OCE_rho_liq = 1026.
-#-- Water volumic mass in atmosphere
-ATM_rho = 1.0e3
-#-- Water volumic mass in surface reservoirs
-SRF_rho = 1.0e3
-#-- Water volumic mass of rivers
-RUN_rho = 1.0e3
-
-## Read experiment parameters
-ATM = None ; ORCA = None ; NEMO = None ; OCE_relax = False ; OCE_icb = False ; Coupled = False ; Routing = None
-
-# Arguments passed
+## Experiment parameters
+ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False ; OCE_icb=False ; Coupled=False ; Routing=None ;  TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None
+
+##
+ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None
+TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None
+file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None
+tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None
+file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_beg=None ; file_OCE_end=None ; file_OCE_srf=None ; file_OCE_sca=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None
+
+# Read command line arguments
 print ( "Name of Python script:", sys.argv[0] )
-IniFile =  sys.argv[1]
+IniFile = sys.argv[1]
+# Text existence of IniFile
+if not os.path.exists (IniFile ) :
+    raise FileExistsError ( f"File not found : {IniFile = }" )
+
+if 'full' in IniFile : FullIniFile = IniFile
+else                 : FullIniFile = 'full_' + IniFile
+    
 print ("Input file : ", IniFile )
 config.read (IniFile)
-
-def setBool (chars) :
-    '''Convert specific char string in boolean if possible'''
-    setBool = chars
-    for key in configparser.ConfigParser.BOOLEAN_STATES.keys () :
-        if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key]
-    return setBool
-
-def setNum (chars) :
-    '''Convert specific char string in integer or real if possible'''
-    if type (chars) == str :
-        realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$")
-        isReal = realnum.match(chars.strip()) != None
-        isInt  = chars.strip().isdigit()
-        if isReal :
-            if isInt : setNum = int   (chars)
-            else     : setNum = float (chars)
-        else : setNum = chars
-    else : setNum = chars
-    return setNum
-
-print ('[Experiment]')
-for VarName in config['Experiment'].keys() :
-    locals()[VarName] = config['Experiment'][VarName]
-    locals()[VarName] = setBool (locals()[VarName])
-    locals()[VarName] = setNum  (locals()[VarName])
-    print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) )
-    
-###
-ICO  = ( 'ICO' in ATM )
-LMDZ = ( 'LMD' in ATM )
-    
-###
-## Import system modules
-import sys, os, shutil, subprocess
-
-# Where do we run ?
-SysName, NodeName, Release, Version, Machine = os.uname()
-TGCC  = ( 'irene'   in NodeName )
-IDRIS = ( 'jeanzay' in NodeName )
-
-## Set site specific libIGCM directories, and other specific stuff
-if TGCC :
-    CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' )
-    if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene'
-    if "AMD"                       in CPU : Machine = 'irene-amd'
-        
-    ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' )
-    STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' )
-    SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' )
-    R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM')
-    rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' )
-
-    ## Specific to run at TGCC.
-    # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...)
-    import mpi4py
-    mpi4py.rc.initialize = False
-        
-    ## Creates output directory
-    #TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
-    TmpDir = os.path.join ( '/ccc/scratch/cont003/drf/p86mart', f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
-
-if IDRIS :
-    raise Exception("Pour IDRIS : repertoires et chemins a definir") 
-
-## Import specific module
+FullIniFile = 'full_' + IniFile
+
+## Reading config file
+for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] :
+   if Section in config.keys () : 
+        print ( f'Reading [{Section}]' )
+        for VarName in config[Section].keys() :
+            locals()[VarName] = config[Section][VarName]
+            exec ( f'{VarName} = wu.setBool ({VarName})' )
+            exec ( f'{VarName} = wu.setNum  ({VarName})' )
+            exec ( f'{VarName} = wu.setNone ({VarName})' )
+            exec (  f'wu.{VarName} = {VarName}' )
+            print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) )
+            #exec ( f'del {VarName}' )
+
+#-- Some physical constants
+if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m)
+if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s
+if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO
+if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3)
+if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3)
+if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3)
+if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3)
+if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s) - Use only to compute drif in approximate unit 
+
+# Set libIGCM and machine dependant values
+if not 'Files' in config.keys() : config['Files'] = {}
+
+config['Physics'] = { 'Ra':Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno, 'OCE_rho_liq':OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}
+
+## --------------------------
+ICO  = ( 'ICO' in wu.ATM )
+LMDZ = ( 'LMD' in wu.ATM )
+
+with open ('SetLibIGCM.py') as f: exec ( f.read() )
+config['Files']['TmpDir'] = TmpDir
+
+if libIGCM :
+    config['libIGCM'] = {'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'SCRATCHDIR':SCRATCHDIR, 'R_IN':R_IN, 'rebuild':rebuild }
+
+# Import specific module
 import nemo, lmdz
 ## Now import needed scientific modules
 import xarray as xr
     
-# Output file
-FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
+# Output file with water budget diagnostics
+if wu.unDefined ( 'FileOut' ) : FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
+config['Files']['FileOut'] = FileOut
+
 f_out = open ( FileOut, mode = 'w' )
-
-# Function to print to stdout *and* output file
+    
+# Useful functions
+def kg2Sv    (val, rho=ATM_rho) :
+    '''From kg to Sverdrup'''
+    return val/dtime_sec*1.0e-6/rho
+
+def kg2myear (val, rho=ATM_rho) :
+    '''From kg to m/year'''
+    return val/ATM_aire_sea_tot/rho/NbYear
+
+def var2prt (var, small=False, rho=ATM_rho) :
+    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000.
+    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho)
+
+def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) :
+    if small :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "
+    else :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  "
+    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) )
+    return None
+
 def echo (string, end='\n') :
-    print ( string, end=end  )
+    '''Function to print to stdout *and* output file'''
+    print ( str(string), end=end  )
     sys.stdout.flush ()
-    f_out.write ( string + end )
+    f_out.write ( str(string) + end )
     f_out.flush ()
     return None
     
 ## Set libIGCM directories
-R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT')
-R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT')
-
-L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName)
-R_SAVE      = os.path.join ( R_OUT, L_EXP )
-R_BUFR      = os.path.join ( R_BUF, L_EXP )
-POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' )
-REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' )
-R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
-R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
-
-#if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir )
-if not os.path.isdir (TmpDir) : os.mkdir (TmpDir)
-TmpDirOCE = os.path.join (TmpDir, 'OCE')
-TmpDirICE = os.path.join (TmpDir, 'ICE')
-if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE )
-if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE )
-
-echo ( f'Working in TMPDIR : {TmpDir}' )
-
-echo ( f'\nDealing with {L_EXP}' )
+if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' )
+if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' )
+if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName)
+if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP )
+if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP )
+if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' )
+if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
+
+config['libIGCM'] = { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR }
+
+# Set directory to extract filesa
+if RunDir == None : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
+config['Files']['RunDir'] = RunDir
+
+if not os.path.isdir ( RunDir ) : os.makedirs ( RunDir )
+
+# Set directories to rebuild ocean and ice restart files
+RunDirOCE = os.path.join ( RunDir, 'OCE' )
+RunDirICE = os.path.join ( RunDir, 'ICE' )
+#RunDirATM = os.path.join ( RunDir, 'ATM' )
+#RunDirSRF = os.path.join ( RunDir, 'SRF' )
+#RunDirRUN = os.path.join ( RunDir, 'RUN' )
+#RunDirDYN = os.path.join ( RunDir, 'DYN' )
+if not os.path.exists ( RunDirOCE ) : os.mkdir ( RunDirOCE )
+if not os.path.exists ( RunDirICE ) : os.mkdir ( RunDirICE )
+
+echo (' ')
+echo ( f'JobName   : {JobName}'   )
+echo ( f'Comment   : {Comment}'   )
+echo ( f'TmpDir    : {TmpDir}'    )
+echo ( f'RunDirOCE : {RunDirOCE}' )
+echo ( f'RunDirICE : {RunDirICE}' )
+
+echo ( f'\nDealing with {L_EXP}'  )
 
 #-- Model output directories
 if Freq == "MO" : FreqDir =  os.path.join ('Output' , 'MO' )
 if Freq == "SE" : FreqDir =  os.path.join ('Analyse', 'SE' )
-dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir )
-dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir )
-dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir )
-dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir )
+if dir_ATM_his == None :
+    dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir )
+    config['Files']['dir_ATM_his'] = dir_ATM_his
+if dir_SRF_his == None : 
+    dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir )
+    config['Files']['dir_SRF_his'] = dir_SRF_his
+if dir_OCE_his == None :
+    dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir )
+    config['Files']['dir_OCE_his'] = dir_OCE_his
+if dir_ICE_his == None : 
+    dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir )
+    config['Files']['dir_ICE_his'] = dir_ICE_his
 
 echo ( f'The analysis relies on files from the following model output directories : ' )
@@ -180,15 +205,42 @@
 echo ( f'{dir_SRF_his}' )
 
-#-- Files Names
-if Freq == 'MO' : FileCommon = f'{JobName}_{YearBegin}0101_{YearEnd}1231_1M'
-if Freq == 'SE' : FileCommon = f'{JobName}_SE_{YearBegin}0101_{YearEnd}1231_1M'
+#-- Creates files names
+if Period == None :
+    if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M'
+    if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M'
+    config['Files']['Period'] = Period
+if FileCommon == None :
+    FileCommon = f'{JobName}_{Period}'
+    config['Files']['FileCommon'] = FileCommon
+
+if Title == None :
+    Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31'
+    config['Files']['Title'] = Title
 
 echo ('\nOpen history files' )
-file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' )
-file_OCE_his = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' )
-file_OCE_sca = os.path.join (  dir_OCE_his, f'{FileCommon}_scalar.nc' )
-file_ICE_his = os.path.join (  dir_ICE_his, f'{FileCommon}_icemod.nc' )
-file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' )
-file_OCE_srf = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' )
+if file_ATM_his == None : 
+    file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' )
+    config['Files']['file_ATM_his'] = file_ATM_his
+if file_SRF_his == None :
+    file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' )
+    config['Files']['file_SRF_his'] = file_SRF_his
+#if Routing == 'SECHIBA'  :
+#     file_RUN_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' )
+if Routing == 'SIMPLE' :
+    if file_RUN_his == None : 
+        file_RUN_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' )
+        config['Files']['file_RUN_his'] = file_RUN_his
+if file_OCE_his == None :
+    file_OCE_his = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' )
+    config['Files']['file_OCE_his'] = file_OCE_his
+if file_OCE_sca == None :
+    file_OCE_sca = os.path.join (  dir_OCE_his, f'{FileCommon}_scalar.nc' )
+    config['Files']['file_OCE_sca'] = file_OCE_sca
+if file_ICE_his == None :
+    file_ICE_his = os.path.join (  dir_ICE_his, f'{FileCommon}_icemod.nc' )
+    config['Files']['file_ICE_his'] = file_ICE_his
+if file_OCE_srf == None :
+    file_OCE_srf = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' )
+    config['Files']['file_OCE_srf'] = file_OCE_srf
 
 d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
@@ -199,10 +251,15 @@
 d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
 d_OCE_srf = xr.open_dataset ( file_OCE_srf, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
-
-echo ( file_ATM_his )
-echo ( file_OCE_his )
-echo ( file_OCE_sca )
-echo ( file_ICE_his )
-echo ( file_SRF_his )
+if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his
+if Routing == 'SIMPLE'  : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze()
+
+    
+echo ( f'{file_ATM_his = }' )
+echo ( f'{file_SRF_his = }' )
+if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' )
+echo ( f'{file_OCE_his = }' )
+echo ( f'{file_ICE_his = }' )
+echo ( f'{file_OCE_sca = }' )
+echo ( f'{file_OCE_srf = }' )
 
 ## Compute run length
@@ -216,4 +273,8 @@
 dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds
 dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] )
+dtime_per_sec.attrs['unit'] = 's'
+
+# Number of years
+NbYear = dtime_sec / YearLength
 
 #-- Open restart files
@@ -221,75 +282,114 @@
 YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation
 
+config['Files']['YearPre'] = f'{YearBegin}'
+
 echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
 
-file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearPre}0101_{YearRes}1231_restart.tar' )
-file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearBegin}0101_{YearEnd}1231_restart.tar' )
-
-echo ( f'{file_restart_beg}' )
-echo ( f'{file_restart_end}' )
-
-file_OCE_beg = f'OCE_{JobName}_{YearRes}1231_restart.nc'
-file_OCE_end = f'OCE_{JobName}_{YearEnd}1231_restart.nc'
-file_ICE_beg = f'ICE_{JobName}_{YearRes}1231_restart_icemod.nc'
-file_ICE_end = f'ICE_{JobName}_{YearEnd}1231_restart_icemod.nc'
-
-echo ( f'{file_OCE_beg}' )
-echo ( f'{file_OCE_end}' )
-echo ( f'{file_ICE_beg}' )
-echo ( f'{file_ICE_end}' )
-
-file_ATM_beg = f'ATM_{JobName}_{YearRes}1231_restartphy.nc'
-file_ATM_end = f'ATM_{JobName}_{YearEnd}1231_restartphy.nc'
-if LMDZ :
-    file_DYN_beg = f'ATM_{JobName}_{YearRes}1231_restart.nc'
-    file_DYN_end = f'ATM_{JobName}_{YearEnd}1231_restart.nc'
-if ICO :
-    file_DYN_beg = f'ICO_{JobName}_{YearRes}1231_restart.nc'
-    file_DYN_end = f'ICO_{JobName}_{YearEnd}1231_restart.nc'
-file_SRF_beg = f'SRF_{JobName}_{YearRes}1231_sechiba_rest.nc'
-file_SRF_end = f'SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc'
-liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg, ]
-liste_end = [file_ATM_end, file_DYN_end, file_SRF_end, ]
-echo ( f'{file_ATM_beg}')
-echo ( f'{file_ATM_end}')
-echo ( f'{file_SRF_beg}')
-echo ( f'{file_SRF_end}')
-
-if Routing == 'SIMPLE' : 
-    file_RUN_beg = f'SRF_{JobName}_{YearRes}1231_routing_restart.nc'
-    file_RUN_end = f'SRF_{JobName}_{YearEnd}1231_routing_restart.nc'
+if TarRestartPeriod_beg == None : 
+    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
+    TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231'
+    config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg
+
+if TarRestartPeriod_end == None : 
+    YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation
+    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
+    TarRestartPeriod_end = f'{YearBegin}0101_{YearEnd}1231'
+    config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end
+
+if tar_restart_beg == None :
+    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )
+    config['Files']['tar_restart_beg'] = tar_restart_beg
+if tar_restart_end == None :
+    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )
+    config['Files']['tar_restart_end'] = tar_restart_end
+
+echo ( f'{tar_restart_beg}' )
+echo ( f'{tar_restart_end}' )
+
+if file_ATM_beg == None : 
+    file_ATM_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc'
+    config['Files']['file_ATM_beg'] = file_ATM_beg
+if file_ATM_end == None :
+    file_ATM_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc'
+    config['Files']['file_ATM_end'] = file_ATM_end
+
+if file_DYN_beg == None :
+    if LMDZ : file_DYN_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restart.nc'
+    if ICO  : file_DYN_beg = f'{RunDir}/ICO_{JobName}_{YearRes}1231_restart.nc'
+    config['Files']['file_DYN_beg'] = file_DYN_beg
+    
+if file_DYN_end == None : 
+    if LMDZ : file_DYN_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restart.nc'
+    if ICO  : file_DYN_end = f'{RunDir}/ICO_{JobName}_{YearEnd}1231_restart.nc'
+    config['Files']['file_DYN_end'] = file_DYN_end
+    
+if file_SRF_beg == None :
+    file_SRF_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc'
+    config['Files']['file_SRF_beg'] = file_SRF_beg
+if file_SRF_end == None :
+    file_SRF_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc'
+    config['Files']['file_SRF_end'] = file_SRF_end
+    
+if file_OCE_beg == None : 
+    file_OCE_beg = f'{RunDir}/OCE_{JobName}_{YearRes}1231_restart.nc'
+    config['Files']['file_OCE_beg'] = file_OCE_beg
+if file_OCE_end == None :
+    file_OCE_end = f'{RunDir}/OCE_{JobName}_{YearEnd}1231_restart.nc'
+    config['Files']['file_OCE_end'] = file_OCE_end
+if file_ICE_beg == None :
+    file_ICE_beg = f'{RunDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc'
+    config['Files']['file_ICE_beg'] = file_ICE_beg
+if file_ICE_end == None : 
+    file_ICE_end = f'{RunDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc'
+    config['Files']['file_ICE_end'] = file_ICE_end
+
+liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg]
+liste_end = [file_ATM_end, file_DYN_end, file_SRF_end]
+
+if Routing == 'SIMPLE' :
+    if file_RUN_beg == None : 
+        file_RUN_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc'
+        config['Files']['file_RUN_beg'] = file_RUN_beg
+    if file_RUN_end == None : 
+        file_RUN_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc'
+        config['Files']['file_RUN_end'] = file_RUN_end
+        
     liste_beg.append ( file_RUN_beg )
     liste_end.append ( file_RUN_end )
-    echo ( f'{file_RUN_beg}')
-    echo ( f'{file_RUN_end}')
+    echo ( f'{file_RUN_beg = }' )
+    echo ( f'{file_RUN_end = }' )
+
+echo ( f'{file_ATM_beg = }' )
+echo ( f'{file_ATM_end = }' )
+echo ( f'{file_DYN_beg = }' )
+echo ( f'{file_DYN_end = }' )
+echo ( f'{file_SRF_beg = }' )
+echo ( f'{file_SRF_end = }' )
+echo ( f'{file_RUN_beg = }' )
+echo ( f'{file_RUN_end = }' )
+echo ( f'{file_OCE_beg = }' )
+echo ( f'{file_OCE_end = }' )
+echo ( f'{file_ICE_beg = }' )
+echo ( f'{file_ICE_end = }' )
 
 echo ('\nExtract restart files from tar : ATM, ICO and SRF')
-for resFile in liste_beg :
-    if not os.path.exists ( os.path.join (TmpDir, resFile) ) :
-        command =  f'cd {TmpDir} ; tar xf {file_restart_beg} {resFile}'
+for resFile in liste_beg + liste_end :
+    if os.path.exists ( os.path.join (RunDir, resFile) ) :
+        echo ( f'file found : {resFile = }' )
+    else :
+        base_file = Path (file_name).stem # basename, and remove suffix
+        command =  f'cd {RunDir} ; tar xf {tar_restart_beg} {base_resFile}.nc'
         echo ( command )
-        os.system ( command )
-        
-for resFile in liste_end :
-    if not os.path.exists ( os.path.join (TmpDir, resFile) ) :
-        command =  f'cd {TmpDir} ; tar xf {file_restart_end} {resFile}'
-        echo ( command )
-        os.system ( command )
+        ierr = os.system ( command )
+        if ierr == 0 : echo ( f'tar done : {base_resFile}')
+        else         : raise Exception ( f'command failed : {command}' )
 
 echo ('\nOpening ATM SRF and ICO restart files')
-d_ATM_beg = xr.open_dataset ( os.path.join (TmpDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze()
-d_ATM_end = xr.open_dataset ( os.path.join (TmpDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze()
-d_SRF_beg = xr.open_dataset ( os.path.join (TmpDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze()
-d_SRF_end = xr.open_dataset ( os.path.join (TmpDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze()
-d_DYN_beg = xr.open_dataset ( os.path.join (TmpDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze()
-d_DYN_end = xr.open_dataset ( os.path.join (TmpDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze()
-
-for var in d_SRF_beg.variables :
-    d_SRF_beg[var] = d_SRF_beg[var].where (  d_SRF_beg[var]<1.e20, 0.)
-    d_SRF_end[var] = d_SRF_end[var].where (  d_SRF_end[var]<1.e20, 0.)
-
-if ICO :
-    d_RUN_beg = xr.open_dataset ( os.path.join (TmpDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze()
-    d_RUN_end = xr.open_dataset ( os.path.join (TmpDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze()
+d_ATM_beg = xr.open_dataset ( os.path.join (RunDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze()
+d_ATM_end = xr.open_dataset ( os.path.join (RunDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze()
+d_SRF_beg = xr.open_dataset ( os.path.join (RunDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze()
+d_SRF_end = xr.open_dataset ( os.path.join (RunDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze()
+d_DYN_beg = xr.open_dataset ( os.path.join (RunDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze()
+d_DYN_end = xr.open_dataset ( os.path.join (RunDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze()
 
 echo ('\nExtract and rebuild OCE and ICE restarts')
@@ -298,109 +398,132 @@
     #ndomain_opa = d_zfile.attrs['DOMAIN_number_total']
     #d_zfile.close ()
-    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ).format()
+    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format()
     return int (ndomain_opa)
 
-
-if not os.path.exists ( os.path.join (TmpDir, file_OCE_beg) ) :
-    if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart_0000.nc') ):
-        command =  f'cd {TmpDirOCE} ; tar xf {file_restart_beg}  OCE_{JobName}_{YearRes}1231_restart_*.nc'
+def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, RunDirComp=RunDirOCE ) :
+    '''Extract restart file from tar. Rebuild ocean files if needed'''
+    echo ( f'file to extract : {file_name} ' )
+    if os.path.exists ( file_name ) :
+        echo ( f'-- File ready : {file_name}' )
+    else : 
+        echo ( f'-- Extracting {file_name}' )
+        base_resFile = Path (file_name).stem # basename, and remove suffix
+        # Try to extract the rebuilded file
+        command =  f'cd {RunDirComp} ; tar xf {tar_restart} {base_resFile}.nc'
         echo ( command )
-        os.system ( command )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart') )
-    command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearRes}1231_restart {ndomain_opa} ; mv {file_OCE_beg} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_beg}')
-    
-if not os.path.exists ( os.path.join (TmpDir, file_OCE_end) ) :
-    if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart_0000.nc') ):
-        command =  f'cd {TmpDirOCE} ; tar xf {file_restart_end}  OCE_{JobName}_{YearEnd}1231_restart_*.nc'
-        echo ( command )
-        os.system ( command )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart') )
-    command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearEnd}1231_restart {ndomain_opa} ; mv {file_OCE_end} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_end}')
-
-if not os.path.exists ( os.path.join (TmpDir, file_ICE_beg) ) :
-    if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ):
-        command =  f'cd {TmpDirICE} ; tar xf {file_restart_beg}  ICE_{JobName}_{YearRes}1231_restart_icemod_*.nc'
-        echo ( command )
-        os.system ( command )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') )
-    command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearRes}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_beg} {TmpDir} '
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_beg}')
-    
-if not os.path.exists ( os.path.join (TmpDir, file_ICE_end) ) :
-    if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearEnd}1231_restart_icemod') ):
-        command =  f'cd {TmpDirICE} ; tar xf {file_restart_end} ICE_{JobName}_{YearEnd}1231_restart_icemod_*.nc'
-        echo ( command )
-        os.system ( command )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') )
-    command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearEnd}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_end} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_ICE_end}')
+        ierr = os.system ( command )
+        if ierr == 0 :
+            echo ( f'tar done : {base_resFile}')
+            command = f'cd {RunDirComp} ; mv {base_resFile}.nc {RunDir}'
+            ierr = os.system ( command )
+            if ierr == 0 : echo ( f'command done : {command}' )
+            else         : raise Exception ( f'command failed : {command}' )
+        else :
+            if not os.path.exists ( os.path.join (RunDir, f'{base_resFile}_0000.nc') ):
+                command =  f'cd {RunDirComp} ; tar xf {tar_restart_end} {base_resFile}_*.nc'
+                echo ( command )
+                ierr = os.system ( command )
+                if ierr == 0 : echo ( f'tar done : {file_OCE_beg}')
+                else         : raise Exception ( f'command failed : {command}' )
+                echo ('extract ndomain' )
+            ndomain_opa = get_ndomain ( os.path.join (RunDir, f'{base_resFile}') )
+            command = f'cd {RunDirComp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {RunDir}'
+            echo ( command )
+            ierr = os.system ( command )
+            if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc')
+            else         : raise Exception ( f'command failed : {command}' )
+
+extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirOCE )
+extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, RunDirComp=RunDirOCE )
+extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirICE )
+extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, RunDirComp=RunDirICE )
 
 echo ('Opening OCE and ICE restart files')
 if NEMO == 3.6 : 
-    d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze()
-    d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze()
-    d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze()
+    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze()
+    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze()
+    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze()
 if NEMO == 4.0 or NEMO == 4.2 : 
-    d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    
-echo ( file_ATM_beg )
-echo ( file_ATM_end )
-echo ( file_DYN_beg )
-echo ( file_DYN_end )
-echo ( file_SRF_beg )
-echo ( file_SRF_end )
-if Routing == 'SIMPLE' :
-    echo ( file_RUN_beg )
-    echo ( file_RUN_end )
-echo ( file_OCE_beg )
-echo ( file_OCE_end )
-echo ( file_ICE_beg )
-echo ( file_ICE_end )
-
-def ATM_stock_int (stock) :
-    '''Integrate stock on atmosphere grid'''
-    ATM_stock_int  = np.sum (  np.sort ( (stock * DYN_aire).to_masked_array().ravel()) )
-    return ATM_stock_int
-
-def OCE_stock_int (stock) :
-    '''Integrate stock on ocean grid'''
-    OCE_stock_int  = np.sum (  np.sort ( (stock * OCE_aire).to_masked_array().ravel()) )
-    return OCE_stock_int
-
-def ONE_stock_int (stock) : 
-    '''Sum stock for field already integrated by cell'''
-    ONE_stock_int  = np.sum (  np.sort ( (stock).to_masked_array().ravel()) )
-    return ONE_stock_int
-
-# ATM grid with cell surfaces
+    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+
+## Write the full configuration
+config_out = open (FullIniFile, 'w')
+config.write (config_out )
+config_out.close ()
+
+for var in d_SRF_beg.variables :
+    d_SRF_beg[var] = d_SRF_beg[var].where (  d_SRF_beg[var]<1.e20, 0.)
+    d_SRF_end[var] = d_SRF_end[var].where (  d_SRF_end[var]<1.e20, 0.)
+
+if ICO :
+    d_RUN_beg = xr.open_dataset ( os.path.join (RunDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze()
+    d_RUN_end = xr.open_dataset ( os.path.join (RunDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze()
+
+def kg2Sv  (val, rho=OCE_rho_liq) :
+    '''From kg to Sverdrup'''
+    return val/dtime_sec*1.0e-6/rho
+
+def kg2myear (val, rho=OCE_rho_liq) :
+    '''From kg to m/year'''
+    return val/OCE_aire_tot/rho/NbYear
+
+def var2prt (var, small=False) :
+    if small :  return var , kg2Sv(var)*1000., kg2myear(var)*1000.
+    else     :  return var , kg2Sv(var)      , kg2myear(var)
+
+def prtFlux (Desc, var, Form='F', small=False) :
+    if small :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "
+    else :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  "
+    echo ( (' {:>15} = ' +ff).format (Desc, *var2prt(var, small) ) )
+    return None
+
+
+
 # ATM grid with cell surfaces
 if ICO :
-    jpja, jpia = d_ATM_his['aire'][0].shape   
-    file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' )
-    d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze()
-    ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True )
-    ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] )
-    ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] + d_ATM_his ['fract_lic'][0] )
-    SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] )
-    
+    if ATM_HIS == 'latlon' :
+        jpja, jpia = d_ATM_his['aire'][0].shape   
+        file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' )
+        config['Files']['file_ATM_aire'] = file_ATM_aire
+        echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' )
+        d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze()
+        ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True )
+        ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] )
+        ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] )
+        ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] )
+        ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] )
+        SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] )
+        #SRF_aire = ATM_aire * lmdz.geo2point (d_SRF_his ['Contfrac'] )
+        #SRF_aire = ATM_aire * ATM_fter
+    if ATM_HIS == 'ico' :
+        echo ( f'Aire sur grille icosaedre : {file_ATM_aire = }' )
+        
 if LMDZ :
     ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True )
-    ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] )
-    ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0]  )
-    SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] )
+    ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] )
+    ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] )
+    ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] )
+    ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] )
+    #SRF_aire = lmdz.geo2point ( d_SRF_his['Areas'] * d_SRF_his['Contfrac'] )
+    SRF_aire = ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'] )
+    
+ATM_fsea      = ATM_foce + ATM_fsic
+ATM_flnd      = ATM_fter + ATM_flic
+ATM_aire_fter = ATM_aire * ATM_fter
+ATM_aire_flic = ATM_aire * ATM_flic
+ATM_aire_fsic = ATM_aire * ATM_fsic
+ATM_aire_foce = ATM_aire * ATM_foce
+ATM_aire_flnd = ATM_aire * ATM_flnd
+ATM_aire_fsea = ATM_aire * ATM_fsea
+
+SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.)
 
 if ICO :
@@ -415,8 +538,51 @@
     
 if LMDZ :
+    # Area on lon/lat grid
     DYN_aire = ATM_aire
     DYN_fsea = ATM_fsea
     DYN_flnd = ATM_flnd
-
+    DYN_fter = d_ATM_beg['FTER']
+    DYN_flic = d_ATM_beg['FTER']
+
+def ATM_stock_int (stock) :
+    '''Integrate (* surface) stock on atmosphere grid'''
+    ATM_stock_int  = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() ) 
+    return ATM_stock_int
+
+def ATM_flux_int (flux) :
+    '''Integrate (* time * surface) flux on atmosphere grid'''
+    ATM_flux_int  = wu.Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() )
+    return ATM_flux_int
+
+def SRF_stock_int (stock) :
+    '''Integrate (* surface) stock on land grid'''
+    ATM_stock_int  = wu.Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) )
+    return ATM_stock_int
+
+def SRF_flux_int (flux) :
+    '''Integrate (* time * surface) flux on land grid'''
+    SRF_flux_int  = wu.Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() )
+    return SRF_flux_int
+
+def OCE_stock_int (stock) :
+    '''Integrate stock on ocean grid'''
+    OCE_stock_int = np.sum (  np.sort ( (stock * OCE_aire ).to_masked_array().ravel()) )
+    return OCE_stock_int
+
+def ONE_stock_int (stock) :
+    '''Sum stock'''
+    ONE_stock_int = np.sum (  np.sort ( (stock ).to_masked_array().ravel()) )
+    return ONE_stock_int
+
+def OCE_flux_int (flux) :
+    '''Integrate flux on oce grid'''
+    OCE_flux_int = np.sum (  np.sort ( (flux * OCE_aire * dtime_per_sec).to_masked_array().ravel()) )
+    return OCE_flux_int
+
+def ONE_flux_int (flux) :
+    '''Integrate flux on oce grid'''
+    OCE_flux_int = np.sum (  np.sort ( (flux * dtime_per_sec).to_masked_array().ravel()) )
+    return OCE_flux_int
+    
 #if LMDZ :
 #    d_ATM_beg = d_ATM_beg.assign ( coords={'lon':d_ATM_beg.lon*180./np.pi} )
@@ -440,5 +606,5 @@
 ATM_aire_sea_tot = ONE_stock_int ( ATM_aire_sea )
 
-echo ( '\n------------------------------------------------------------------------------------' )
+echo ( '\n====================================================================================' )
 echo ( '-- NEMO change in stores (for the records)' )
 #-- Note that the total number of days of the run should be diagnosed rather than assumed
@@ -522,17 +688,17 @@
     dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat
 
-echo ( 'ICE_vol_ice_beg = {:12.6e} m^3 | ICE_vol_ice_end = {:12.6e} m^3'.format (ICE_vol_ice_beg, ICE_vol_ice_end) )
-echo ( 'ICE_vol_sno_beg = {:12.6e} m^3 | ICE_vol_sno_end = {:12.6e} m^3'.format (ICE_vol_sno_beg, ICE_vol_sno_end) )
-echo ( 'ICE_vol_pnd_beg = {:12.6e} m^3 | ICE_vol_pnd_end = {:12.6e} m^3'.format (ICE_vol_pnd_beg, ICE_vol_pnd_end) )
-echo ( 'ICE_vol_fzl_beg = {:12.6e} m^3 | ICE_vol_fzl_end = {:12.6e} m^3'.format (ICE_vol_fzl_beg, ICE_vol_fzl_end) )
-
-echo ( 'dICE_vol_ice   = {:12.3e} m^3'.format (dICE_vol_ice) )
-echo ( 'dICE_vol_sno   = {:12.3e} m^3'.format (dICE_vol_sno) )
-echo ( 'dICE_vol_pnd   = {:12.3e} m^3'.format (dICE_vol_pnd) )
-echo ( 'dICE_mas_ice   = {:12.3e} m^3'.format (dICE_mas_ice) )
-echo ( 'dICE_mas_sno   = {:12.3e} m^3'.format (dICE_mas_sno) )  
-echo ( 'dICE_mas_pnd   = {:12.3e} m^3'.format (dICE_mas_pnd) )  
-echo ( 'dICE_mas_fzl   = {:12.3e} m^3'.format (dICE_mas_fzl) )  
-echo ( 'dICE_mas_wat   = {:12.3e} m^3'.format (dICE_mas_wat) ) 
+echo ( f'ICE_vol_ice_beg = {ICE_vol_ice_beg:12.6e} m^3 | ICE_vol_ice_end = {ICE_vol_ice_end:12.6e} m^3' )
+echo ( f'ICE_vol_sno_beg = {ICE_vol_sno_beg:12.6e} m^3 | ICE_vol_sno_end = {ICE_vol_sno_end:12.6e} m^3' )
+echo ( f'ICE_vol_pnd_beg = {ICE_vol_pnd_beg:12.6e} m^3 | ICE_vol_pnd_end = {ICE_vol_pnd_end:12.6e} m^3' )
+echo ( f'ICE_vol_fzl_beg = {ICE_vol_fzl_beg:12.6e} m^3 | ICE_vol_fzl_end = {ICE_vol_fzl_end:12.6e} m^3' )
+
+echo ( f'dICE_vol_ice   = {dICE_vol_ice:12.3e} m^3' )
+echo ( f'dICE_vol_sno   = {dICE_vol_sno:12.3e} m^3' )
+echo ( f'dICE_vol_pnd   = {dICE_vol_pnd:12.3e} m^3' )
+echo ( f'dICE_mas_ice   = {dICE_mas_ice:12.3e} m^3' )
+echo ( f'dICE_mas_sno   = {dICE_mas_sno:12.3e} m^3' )  
+echo ( f'dICE_mas_pnd   = {dICE_mas_pnd:12.3e} m^3' )  
+echo ( f'dICE_mas_fzl   = {dICE_mas_fzl:12.3e} m^3' )  
+echo ( f'dICE_mas_wat   = {dICE_mas_wat:12.3e} m^3' ) 
 
 
@@ -576,6 +742,6 @@
 
 for k in np.arange (klevp1-1) :
-    DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / grav
-    DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / grav
+    DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / Grav
+    DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / Grav
 
 DYN_sigma_beg = DYN_sigma_beg.rename ( {'klevp1':'sigs'} )
@@ -769,7 +935,7 @@
 
 echo ('\nLes differents reservoirs')
-echo ( 'SRF_mas_watveg_beg   = {:12.6e} kg | SRF_mas_watveg_end   = {:12.6e} kg '.format (SRF_mas_watveg_beg , SRF_mas_watveg_end) )
-echo ( 'SRF_mas_watsoil_beg  = {:12.6e} kg | SRF_mas_watsoil_end  = {:12.6e} kg '.format (SRF_mas_watsoil_beg, SRF_mas_watsoil_end) )
-echo ( 'SRF_mas_snow_beg     = {:12.6e} kg | SRF_mas_snow_end     = {:12.6e} kg '.format (SRF_mas_snow_beg   , SRF_mas_snow_end) )
+echo ( f'SRF_mas_watveg_beg   = {SRF_mas_watveg_beg :12.6e} kg | SRF_mas_watveg_end   = {SRF_mas_watveg_end :12.6e} kg ' )
+echo ( f'SRF_mas_watsoil_beg  = {SRF_mas_watsoil_beg:12.6e} kg | SRF_mas_watsoil_end  = {SRF_mas_watsoil_end:12.6e} kg ' )
+echo ( f'SRF_mas_snow_beg     = {SRF_mas_snow_beg   :12.6e} kg | SRF_mas_snow_end     = {SRF_mas_snow_end   :12.6e} kg ' )
 
 echo ( 'dMass (watveg)  = {:12.3e} kg | {:12.2e} Sv | {:12.2e} m '.format (dSRF_mas_watveg , dSRF_mas_watveg /dtime_sec*1E-9, dSRF_mas_watveg /OCE_aire_tot*1E-3) )
Index: TOOLS/WATER_BUDGET/OCE_waterbudget.py
===================================================================
--- TOOLS/WATER_BUDGET/OCE_waterbudget.py	(revision 6446)
+++ TOOLS/WATER_BUDGET/OCE_waterbudget.py	(revision 6508)
@@ -24,6 +24,15 @@
 import numpy as np
 import configparser, re
-
-## Creates parser
+from pathlib import Path
+
+## Import local module
+import WaterUtils as wu
+
+# Check python version
+if sys.version_info < (3, 8, 0) :
+    print ( f'Python version : {platform.python_version()}' ) 
+    raise Exception ( "Minimum Python version is 3.8" )
+
+## Creates parser for reading .ini input file
 config = configparser.ConfigParser()
 config.optionxform = str # To keep capitals
@@ -33,129 +42,58 @@
 
 ##
-ARCHIVE=None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None
-TmpDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None
+ARCHIVE=None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild='rebuild_nemo'
+TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None
 file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None 
-file_restart_beg=None ; file_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None
+tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None ; file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None
 file_RUN_beg=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None
-
-# Arguments passed
+ContinueOnError=False ; ErrorCount=0
+tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None ; tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None
+tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None ; tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None
+
+# Read command line arguments
 print ( "Name of Python script:", sys.argv[0] )
 IniFile = sys.argv[1]
+# Text existence of IniFile
+print ("Input file : ", IniFile )
+
+if 'full' in IniFile : FullIniFile = IniFile
+else                 : FullIniFile = 'full_' + IniFile
+
 print ("Input file : ", IniFile )
 config.read (IniFile)
-if 'full' in IniFile : FullIniFile = IniFile
-else                 : FullIniFile = 'full_' + IniFile
-
-def setBool (chars) :
-    '''Convert specific char string in boolean if possible'''
-    setBool = chars
-    for key in configparser.ConfigParser.BOOLEAN_STATES.keys () :
-        if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key]
-    return setBool
-
-def setNum (chars) :
-    '''Convert specific char string in integer or real if possible'''
-    if type (chars) == str :
-        realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$")
-        isReal = realnum.match(chars.strip()) != None
-        isInt  = chars.strip().isdigit()
-        if isReal :
-            if isInt : setNum = int   (chars)
-            else     : setNum = float (chars)
-        else : setNum = chars
-    else : setNum = chars
-    return setNum
-
-def setNone (chars) :
-    '''Convert specific char string to None if possible'''
-    if type (chars) == str :
-        if chars in ['None', 'NONE', 'none'] : setNone = None
-        else : setNone = chars
-    else : setNone = chars
-    return setNone
-
-## Reading config
+FullIniFile = 'full_' + IniFile
+    
+## Reading config file
 for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] :
-    if Section in config.keys() : 
-        print ( f'[{Section}]' )
+   if Section in config.keys () : 
+        print ( f'Reading [{Section}]' )
         for VarName in config[Section].keys() :
             locals()[VarName] = config[Section][VarName]
-            locals()[VarName] = setBool (locals()[VarName])
-            locals()[VarName] = setNum  (locals()[VarName])
+            exec ( f'{VarName} = wu.setBool ({VarName})' )
+            exec ( f'{VarName} = wu.setNum  ({VarName})' )
+            exec ( f'{VarName} = wu.setNone ({VarName})' )
+            exec ( f'wu.{VarName} = {VarName}' )
             print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) )
-
+            #exec ( f'del {VarName}' )
+
+#-- Some physical constants
+if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m)
+if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s
+if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3
+if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO
+if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3)
+if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3)
+if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3)
+if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3)
+if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s)
+
+# Set libIGCM and machine dependant values
 if not 'Files' in config.keys() : config['Files'] = {}
-
-def unDefined (char) :
-    if char in globals () :
-        if char == None : return True
-        else : return False
-    else : return True
-
-##-- Some physical constants
-#-- Earth Radius
-if not 'Ra'            in locals () : Ra = 6366197.7236758135
-#-- Gravity
-if not 'Grav'          in locals () : Grav = 9.81
-#-- Ice volumic mass (kg/m3) in LIM3
-if not 'ICE_rho_ice'   in locals () : ICE_rho_ice = 917.0
-#-- Snow volumic mass (kg/m3) in LIM3
-if not 'ICE_rho_sno'   in locals () : ICE_rho_sno = 330.0
-    #-- Water density in ice pounds in SI3
-if not 'ICE_rho_pnd'   in locals () : ICE_rho_pnd = 1000.
-#-- Ocean water volumic mass (kg/m3) in NEMO
-if not 'OCE_rho_liq'   in locals () : OCE_rho_liq = 1026.
-#-- Water volumic mass in atmosphere
-if not 'ATM_rho'       in locals () : ATM_rho = 1000.
-#-- Water volumic mass in surface reservoirs
-if not 'SRF_rho'       in locals () : SRF_rho = 1000.
-#-- Water volumic mass of rivers
-if not 'RUN_rho'       in locals () : RUN_rho = 1000.
-#-- Year length
-if not 'YearLength'    in locals () : YearLength = 365.25 * 24. * 60. * 60.
-
-config['Physics'] = { 'Ra':Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno, 'OCE_rho_liq':OCE_rho_liq, 'ICE_rho_pnd':ICE_rho_pnd,
-                          'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}
+    
+config['Physics'] = { 'Ra':Ra, 'Grav':Grav, 'ICE_rho_ice':ICE_rho_ice, 'ICE_rho_sno':ICE_rho_sno, 'OCE_rho_liq':OCE_rho_liq, 'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho}
         
-
-
-# Where do we run ?
-SysName, NodeName, Release, Version, Machine = os.uname()
-TGCC  = ( 'irene'   in NodeName )
-IDRIS = ( 'jeanzay' in NodeName )
-
-## Set site specific libIGCM directories, and other specific stuff
-if TGCC :
-    CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' )
-    if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene'
-    if "AMD"                       in CPU : Machine = 'irene-amd'
-        
-    ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' )
-    STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' )
-    SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' )
-    R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg'), 'IGCM')
-    rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg'), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' )
-
-    ## Specific to run at TGCC.
-    # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...)
-    import mpi4py
-    mpi4py.rc.initialize = False
-        
-    ## Creates output directory
-    TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
-
-if IDRIS :
-    raise Exception ("Pour IDRIS : repertoires et chemins a definir") 
-
-config['System'] = {'SysName':SysName, 'NodeName':NodeName, 'Release':Release, 'Version':Version,'Machine':Machine, 'TGCC':TGCC,'IDRIS':IDRIS, 'CPU':CPU,
-                    'Program'  : "Generated by : " + str(sys.argv), 
-                    'HOSTNAME' : platform.node (), 'LOGNAME'  : os.getlogin (),
-                    'Python'   : f'{platform.python_version ()}',
-                    'OS'       : f'{platform.system ()} release : {platform.release ()} hardware : {platform.machine ()}',
-                    'SVN_Author'   : "$Author$", 
-                    'SVN_Date'     : "$Date$",
-                    'SVN_Revision' : "$Revision$",
-                    'SVN_Id'       : "$Id$",
-                    'SVN_HeadURL'  : "$HeadURL$"}
+with open ('SetLibIGCM.py') as f: exec ( f.read() )
+config['Files']['TmpDir'] = TmpDir
 
 if libIGCM :
@@ -167,13 +105,35 @@
 import xarray as xr
     
-# Output file
-if FileOut == None : 
-    FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
-    config['Files']['FileOut'] = FileOut
+# Output file with water budget diagnostics
+if wu.unDefined ( 'FileOut' ) : FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out'
+config['Files']['FileOut'] = FileOut
 
 f_out = open ( FileOut, mode = 'w' )
-    
-# Function to print to stdout *and* output file
+
+# Useful functions
+def kg2Sv    (val, rho=ATM_rho) :
+    '''From kg to Sverdrup'''
+    return val/dtime_sec*1.0e-6/rho
+
+def kg2myear (val, rho=ATM_rho) :
+    '''From kg to m/year'''
+    return val/ATM_aire_sea_tot/rho/NbYear
+
+def var2prt (var, small=False, rho=ATM_rho) :
+    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000.
+    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho)
+
+def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) :
+    if small :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year "
+    else :
+        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  "
+        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  "
+    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) )
+    return None
+
 def echo (string, end='\n') :
+    '''Function to print to stdout *and* output file'''
     print ( str(string), end=end  )
     sys.stdout.flush ()
@@ -182,37 +142,45 @@
     return None
     
-## Set libIGCM directories
-R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT')
-R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT')
-
-L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName)
-R_SAVE      = os.path.join ( R_OUT, L_EXP )
-R_BUFR      = os.path.join ( R_BUF, L_EXP )
-POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' )
-REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' )
-R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
-R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
-    
-#if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir )
-if not os.path.isdir (TmpDir) : os.mkdir (TmpDir)
-TmpDirOCE = os.path.join (TmpDir, 'OCE')
-TmpDirICE = os.path.join (TmpDir, 'ICE')
-if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE )
-if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE )
+### Set libIGCM directories
+if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' )
+if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' )
+if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName)
+if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP )
+if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP )
+if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' )
+if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' )
+if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP )
+
+config['libIGCM'] = { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR }
+
+# Set directory to extract files
+if wu.unDefined ( 'RunDir' ) : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' )
+config['Files']['RunDir'] = RunDir
+
+if not os.path.isdir (RunDir) : os.makedirs (RunDir)
+
+# Set directories to rebuild ocean and ice restart files
+RunDirOCE = os.path.join (RunDir, 'OCE')
+RunDirICE = os.path.join (RunDir, 'ICE')
+if not os.path.exists (RunDirOCE) : os.mkdir (RunDirOCE )
+if not os.path.exists (RunDirICE) : os.mkdir (RunDirICE )
 
 echo (' ')
-echo ( f'JobName : {JobName}' )
-echo (Comment)
-echo ( f'Working in TMPDIR : {TmpDir}' )
-
-echo ( f'\nDealing with {L_EXP}' )
-
-#-- Model output directories
-if Freq == "MO" : FreqDir =  os.path.join ('Output' , 'MO' )
-if Freq == "SE" : FreqDir =  os.path.join ('Analyse', 'SE' )
-if dir_OCE_his == None :
+echo ( f'JobName   : {JobName}'   )
+echo ( f'Comment   : {Comment}'   )
+echo ( f'TmpDir    : {TmpDir}'    )
+echo ( f'RunDirOCE : {RunDirOCE}' )
+echo ( f'RunDirICE : {RunDirICE}' )
+
+echo ( f'\nDealing with {L_EXP}'  )
+
+#-- Creates model output directory names
+if Freq == "MO" : FreqDir = os.path.join ( 'Output' , 'MO' )
+if Freq == "SE" : FreqDir = os.path.join ( 'Analyse', 'SE' )
+if wu.unDefined ( 'dir_OCE_his' ) :
     dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir )
     config['Files']['dir_OCE_his'] = dir_OCE_his
-if dir_ICE_his == None :
+if wu.unDefined ( 'dir_ICE_his' ) :
     dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir )
     config['Files']['dir_OCE_his'] = dir_OCE_his
@@ -222,14 +190,14 @@
 echo ( f'{dir_ICE_his}' )
 
-#-- Files Names
-if Period == None :
+#-- Creates files names
+if wu.unDefined ( 'Period ' ) :
     if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M'
     if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M'
     config['Files']['Period'] = Period
-if FileCommon == None :
+if wu.unDefined ( 'FileCommon' ) :
     FileCommon = f'{JobName}_{Period}'
     config['Files']['FileCommon'] = FileCommon
 
-if Title == None :
+if wu.unDefined ( 'Title' ) :
     Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31'
     config['Files']['Title'] = Title
@@ -237,11 +205,11 @@
         
 echo ('\nOpen history files' )
-if file_OCE_his == None :
+if wu.unDefined ('file_OCE_his' ) :
     file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' )
     file_OCE_his = file_OCE_his
-if file_OCE_sca == None :    
+if wu.unDefined ('file_OCE_sca' ) :    
     file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' )
     config['Files']['file_OCE_sca'] = file_OCE_sca
-if file_ICE_his == None : 
+if wu.unDefined ( 'file_ICE_hi' ) : 
     file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' )
     config['Files']['file_ICE_his'] = file_ICE_his
@@ -258,11 +226,11 @@
 ## Compute run length
 dtime = ( d_OCE_his.time_counter_bounds.max() - d_OCE_his.time_counter_bounds.min() )
-echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) )
+echo ( f'\nRun length : {(dtime/np.timedelta64(1, "D")).values:8.2f} days' )
 dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds
 
 ## Compute length of each period
 dtime_per = ( d_OCE_his.time_counter_bounds[:,-1] - d_OCE_his.time_counter_bounds[:,0] )
-echo ('\nPeriods lengths (days) : ')
-echo (' {:}'.format ( (dtime_per/np.timedelta64(1, "D")).values ) )
+echo ( f'\nPeriods lengths (days) : ')
+echo ( f' {(dtime_per/np.timedelta64(1, "D")).values}' )
 dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds
 dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_OCE_his.time_counter,] )
@@ -271,4 +239,5 @@
 ## Number of years
 NbYear = dtime_sec / YearLength
+
 #-- Open restart files
 YearRes = YearBegin - 1              # Year of the restart of beginning of simulation
@@ -277,10 +246,10 @@
 echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
 
-if TarRestartPeriod_beg == None : 
+if wu.unDefined ( 'TarRestartPeriod_beg' ) : 
     echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
     TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231'
     config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg
 
-if TarRestartPeriod_end == None : 
+if wu.unDefined ( 'TarRestartPeriod_end' ) : 
     YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation
     echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ')
@@ -288,25 +257,40 @@
     config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end
 
-if file_restart_beg == None :
-    file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )
-    config['Files']['file_restart_beg'] = file_restart_beg
-if file_restart_end == None :
-    file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )
-    config['Files']['file_restart_end'] = file_restart_end
-
-echo ( f'{file_restart_beg}' )
-echo ( f'{file_restart_end}' )
-
-if file_OCE_beg == None : 
-    file_OCE_beg = f'{TmpDir}/OCE_{JobName}_{YearRes}1231_restart.nc'
+if wu.unDefined ( 'tar_restart_beg' ) :
+    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' )
+    config['Files']['tar_restart_beg'] = tar_restart_beg
+if wu.unDefined ( 'tar_restart_end' ) :
+    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' )
+    config['Files']['tar_restart_end'] = tar_restart_end
+
+echo ( f'{tar_restart_beg}' )
+echo ( f'{tar_restart_end}' )
+
+#
+if wu.unDefined ('tar_restart_beg_ATM' ) : tar_restart_beg_ATM = tar_restart_beg
+if wu.unDefined ('tar_restart_beg_DYN' ) : tar_restart_beg_DYN = tar_restart_beg
+if wu.unDefined ('tar_restart_beg_SRF' ) : tar_restart_beg_SRF = tar_restart_beg
+if wu.unDefined ('tar_restart_beg_RUN' ) : tar_restart_beg_RUN = tar_restart_beg
+if wu.unDefined ('tar_restart_beg_OCE' ) : tar_restart_beg_OCE = tar_restart_beg
+if wu.unDefined ('tar_restart_beg_ICE' ) : tar_restart_beg_ICE = tar_restart_beg
+
+if wu.unDefined ('tar_restart_end_ATM' ) : tar_restart_end_ATM = tar_restart_end
+if wu.unDefined ('tar_restart_end_DYN' ) : tar_restart_end_DYN = tar_restart_end
+if wu.unDefined ('tar_restart_end_SRF' ) : tar_restart_end_SRF = tar_restart_end
+if wu.unDefined ('tar_restart_end_RUN' ) : tar_restart_end_RUN = tar_restart_end
+if wu.unDefined ('tar_restart_end_OCE' ) : tar_restart_end_OCE = tar_restart_end
+if wu.unDefined ('tar_restart_end_ICE' ) : tar_restart_end_ICE = tar_restart_end
+
+if wu.unDefined ( 'file_OCE_beg' ) : 
+    file_OCE_beg = f'{RunDir}/OCE_{JobName}_{YearRes}1231_restart.nc'
     config['Files']['file_OCE_beg'] = file_OCE_beg
-if file_OCE_end == None :
-    file_OCE_end = f'{TmpDir}/OCE_{JobName}_{YearEnd}1231_restart.nc'
+if wu.unDefined ( 'file_OCE_end' ) :
+    file_OCE_end = f'{RunDir}/OCE_{JobName}_{YearEnd}1231_restart.nc'
     config['Files']['file_OCE_end'] = file_OCE_end
-if file_ICE_beg == None :
-    file_ICE_beg = f'{TmpDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc'
+if wu.unDefined ( 'file_ICE_beg' ) :
+    file_ICE_beg = f'{RunDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc'
     config['Files']['file_ICE_beg'] = file_ICE_beg
-if file_ICE_end == None : 
-    file_ICE_end = f'{TmpDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc'
+if wu.unDefined ( 'file_ICE_end' ) : 
+    file_ICE_end = f'{RunDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc'
     config['Files']['file_ICE_end'] = file_ICE_end
 
@@ -321,76 +305,68 @@
     #ndomain_opa = d_zfile.attrs['DOMAIN_number_total']
     #d_zfile.close ()
-    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ).format()
+    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format()
     return int (ndomain_opa)
 
-if not os.path.exists ( file_OCE_beg) :
-    echo ( f'Extracting {file_OCE_beg}' )
-    base_file_OCE_beg = os.path.basename (file_OCE_beg)
-    if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart_0000.nc') ) :
-        command =  f'cd {TmpDirOCE} ; tar xf {file_restart_beg}  OCE_{JobName}_{YearRes}1231_restart_*.nc'
-        echo ( command )
-        os.system ( command )
-    echo ('extract ndomain' )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart') )
-    command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearRes}1231_restart {ndomain_opa} ; mv {base_file_OCE_beg} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_beg}')
-    
-if not os.path.exists ( file_OCE_end) :
-    echo ( f'Extracting {file_OCE_end}' )
-    base_file_OCE_end = os.path.basename (file_OCE_end)
-    if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart_0000.nc') ):
-        command =  f'cd {TmpDirOCE} ; tar xf {file_restart_end}  OCE_{JobName}_{YearEnd}1231_restart_*.nc'
-        echo ( command )
-        os.system ( command )
-    echo ('extract ndomain' )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart') )
-    command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearEnd}1231_restart {ndomain_opa} ; mv {base_file_OCE_end} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_end}')
-
-if not os.path.exists ( file_ICE_beg) :
-    echo ( f'Extracting {file_ICE_beg}' )
-    base_file_ICE_beg = os.path.basename (file_ICE_beg)
-    if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod_0000.nc') ):
-        command =  f'cd {TmpDirICE} ; tar xf {file_restart_beg}  ICE_{JobName}_{YearRes}1231_restart_icemod_*.nc'
-        echo ( command )
-        os.system ( command )
-    echo ('extract ndomain' )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') )
-    command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearRes}1231_restart_icemod {ndomain_opa} ; mv {base_file_ICE_beg} {TmpDir} '
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_OCE_beg}')
-    
-if not os.path.exists ( file_ICE_end ) :
-    echo ( f'Extracting {file_ICE_end}' )
-    base_file_ICE_end = os.path.basename (file_ICE_end)
-    if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearEnd}1231_restart_icemod_0000.nc') ):
-        command =  f'cd {TmpDirICE} ; tar xf {file_restart_end} ICE_{JobName}_{YearEnd}1231_restart_icemod_*.nc'
-        echo ( command )
-        os.system ( command )
-    echo ('extract ndomain' )
-    ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') )
-    command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearEnd}1231_restart_icemod {ndomain_opa} ; mv {base_file_ICE_end} {TmpDir}'
-    echo ( command )
-    os.system ( command )
-    echo ( f'Rebuild done : {file_ICE_end}')
+def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, RunDirComp=RunDirOCE, ErrorCount=ErrorCount ) :
+    '''Extract restart file from tar. Rebuild ocean files if needed'''
+    echo ( f'----------')
+    if os.path.exists ( file_name ) :
+        echo ( f'-- File ready : {file_name = }' )
+    else : 
+        echo ( f'-- Extracting {file_name = }' )
+        base_resFile = Path (file_name).stem # basename, and remove suffix
+        # Try to extract the rebuilded file
+        if os.path.exists ( tar_restart ) :
+            command =  f'cd {RunDirComp} ; tar xf {tar_restart} {base_resFile}.nc'
+            echo ( command )
+            try : 
+                os.system ( command )
+            except :
+                if not os.path.exists ( os.path.join (RunDir, f'{base_resFile}_0000.nc') ):
+                    command =  f'cd {RunDirComp} ; tar xf {tar_restart_end} {base_file}_*.nc'
+                    echo ( command )
+                    ierr = os.system ( command )
+                    if ierr == 0 : echo ( f'tar done : {base_resFile}.nc')
+                    else         : raise Exception ( f'command failed : {command}' )
+                    echo ( f'extract ndomain' )
+                ndomain_opa = get_ndomain ( os.path.join (RunDir, f'{base_file}') )
+                command = f'cd {RunDirComp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {RunDir}'
+                echo ( command )
+                ierr = os.system ( command )
+                if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc')
+                else         : raise Exception ( f'command failed : {command}' )
+            else : 
+                echo ( f'tar done : {base_resFile}')
+                command = f'cd {RunDirComp} ; mv {base_resFile}.nc {RunDir}'
+                ierr = os.system ( command )
+                if ierr == 0 : echo ( f'command done : {command}' )
+                else         : raise Exception ( f'command failed : {command = }' )                   
+        else :
+            echo ( f'****** Tar restart file {tar_restart = } not found ' )
+            if ContinueOnError :
+                ErrorCount += 1
+            else : 
+                raise Exception ( f'****** tar file not found {tar_restart = } - Stopping' )
+    return ErrorCount
+
+            
+ErrorCount += extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirOCE )
+ErrorCount += extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, RunDirComp=RunDirOCE )
+ErrorCount += extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirICE )
+ErrorCount += extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, RunDirComp=RunDirICE )
 
 echo ('Opening OCE and ICE restart files')
 if NEMO == 3.6 : 
-    d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze()
-    d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze()
-    d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze()
+    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze()
+    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze()
+    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze()
 if NEMO == 4.0 or NEMO == 4.2 : 
-    d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-    d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
-
-##
+    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze()
+
+## Write the full configuration
 config_out = open (FullIniFile, 'w')
 config.write (config_out )
@@ -473,10 +449,10 @@
     OCE_sum_e3tn_end = OCE_stock_int ( OCE_e3tn_end * OCE_msk3)
 
-echo ( 'OCE_sum_ssh_beg = {:12.6e} m^3  - OCE_sum_ssh_end = {:12.6e} m^3'.format (OCE_sum_ssh_beg, OCE_sum_ssh_end) )
+echo ( f'OCE_sum_ssh_beg = {OCE_sum_ssh_beg:12.6e} m^3  - OCE_sum_ssh_end = {OCE_sum_ssh_end:12.6e} m^3' )
 dOCE_ssh_vol = ( OCE_sum_ssh_end - OCE_sum_ssh_beg )
 dOCE_ssh_mas = dOCE_ssh_vol * OCE_rho_liq
 
 if NEMO == 3.6 :
-    echo ( 'OCE_sum_e3tn_beg = {:12.6e} m^3  - OCE_sum_e3tn_end = {:12.6e} m^3'.format (OCE_sum_e3tn_beg, OCE_sum_e3tn_end) )
+    echo ( f'OCE_sum_e3tn_beg = {OCE_sum_e3tn_beg:12.6e} m^3  - OCE_sum_e3tn_end = {OCE_sum_e3tn_end:12.6e} m^3' )
     dOCE_e3tn_vol = ( OCE_sum_e3tn_end - OCE_sum_e3tn_beg )
     dOCE_e3tn_mas = dOCE_e3tn_vol * OCE_rho_liq
@@ -484,10 +460,10 @@
 dOCE_vol_wat = dOCE_ssh_vol ; dOCE_mas_wat = dOCE_ssh_mas
 
-echo ( 'dOCE vol    = {:12.3e} m^3'.format ( dOCE_vol_wat) )
-echo ( 'dOCE ssh    = {:12.3e} m  '.format ( dOCE_vol_wat/OCE_aire_tot) )
+echo ( f'dOCE vol    = {dOCE_vol_wat             :12.3e} m^3' )
+echo ( f'dOCE ssh    = {dOCE_vol_wat/OCE_aire_tot:12.3e} m  ' )
 prtFlux ( 'dOCE mass ', dOCE_mas_wat, 'e' )
 
 if NEMO == 3.6 :
-    echo ( 'dOCE e3tn   vol    = {:12.3e} m^3'.format ( dOCE_e3tn_vol) )
+    echo ( f'dOCE e3tn   vol    = {dOCE_e3tn_vol:12.3e} m^3' )
     prtFlux ( 'dOCE e3tn   mass', dOCE_e3tn_mas, 'e' )
 
@@ -547,19 +523,19 @@
     dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat
 
-echo ( 'ICE_vol_ice_beg = {:12.6e} m^3 | ICE_vol_ice_end = {:12.6e} m^3'.format (ICE_vol_ice_beg, ICE_vol_ice_end) )
-echo ( 'ICE_vol_sno_beg = {:12.6e} m^3 | ICE_vol_sno_end = {:12.6e} m^3'.format (ICE_vol_sno_beg, ICE_vol_sno_end) )
-echo ( 'ICE_vol_pnd_beg = {:12.6e} m^3 | ICE_vol_pnd_end = {:12.6e} m^3'.format (ICE_vol_pnd_beg, ICE_vol_pnd_end) )
-echo ( 'ICE_vol_fzl_beg = {:12.6e} m^3 | ICE_vol_fzl_end = {:12.6e} m^3'.format (ICE_vol_fzl_beg, ICE_vol_fzl_end) )
-
-echo ( 'dICE_vol_ice   = {:12.3e} m^3'.format (dICE_vol_ice) )
-echo ( 'dICE_vol_sno   = {:12.3e} m^3'.format (dICE_vol_sno) )
-echo ( 'dICE_vol_pnd   = {:12.3e} m^3'.format (dICE_vol_pnd) )
-echo ( 'dICE_mas_ice   = {:12.3e} m^3'.format (dICE_mas_ice) )
-echo ( 'dICE_mas_sno   = {:12.3e} m^3'.format (dICE_mas_sno) )  
-echo ( 'dICE_mas_pnd   = {:12.3e} m^3'.format (dICE_mas_pnd) )  
-echo ( 'dICE_mas_fzl   = {:12.3e} m^3'.format (dICE_mas_fzl) )  
+echo ( f'ICE_vol_ice_beg = {ICE_vol_ice_beg:12.6e} m^3 | ICE_vol_ice_end = {ICE_vol_ice_end:12.6e} m^3' )
+echo ( f'ICE_vol_sno_beg = {ICE_vol_sno_beg:12.6e} m^3 | ICE_vol_sno_end = {ICE_vol_sno_end:12.6e} m^3' )
+echo ( f'ICE_vol_pnd_beg = {ICE_vol_pnd_beg:12.6e} m^3 | ICE_vol_pnd_end = {ICE_vol_pnd_end:12.6e} m^3' )
+echo ( f'ICE_vol_fzl_beg = {ICE_vol_fzl_beg:12.6e} m^3 | ICE_vol_fzl_end = {ICE_vol_fzl_end:12.6e} m^3' )
+
+echo ( f'dICE_vol_ice   = {dICE_vol_ice:12.3e} m^3' )
+echo ( f'dICE_vol_sno   = {dICE_vol_sno:12.3e} m^3' )
+echo ( f'dICE_vol_pnd   = {dICE_vol_pnd:12.3e} m^3' )
+echo ( f'dICE_mas_ice   = {dICE_mas_ice:12.3e} m^3' )
+echo ( f'dICE_mas_sno   = {dICE_mas_sno:12.3e} m^3' )  
+echo ( f'dICE_mas_pnd   = {dICE_mas_pnd:12.3e} m^3' )  
+echo ( f'dICE_mas_fzl   = {dICE_mas_fzl:12.3e} m^3' )  
 
 echo ( '\n------------------------------------------------------------')
-echo ( 'Variation du contenu en eau ocean + glace ' )
+echo ( 'Change in water content (ocean + ice) ' )
 prtFlux ( 'dMass (ocean)', dSEA_mas_wat, 'e', True )
 
@@ -584,5 +560,5 @@
 
 echo ( '\n------------------------------------------------------------------------------------' )
-echo ( '-- Checks in NEMO - from budget_modipsl.sh (Clement Rousset)' )
+echo ( '-- Checks in NEMO - from budget_modipsl.sh (ClÃ©ment Rousset)' )
 
 # Read variable and computes integral over space and time
@@ -658,9 +634,9 @@
 prtFlux ('  WFXSNW_PRE   ', ICE_mas_wfxsnw_pre, 'e', True)
 prtFlux ('  WFXSUB_ERR   ', ICE_mas_wfxsub_err, 'e', True)
-prtFlux ('  EVAP_OCE     ', OCE_mas_evap_oce  , 'e' )
+prtFlux ('  EVAP_OCE     ', OCE_mas_evap_oce  , 'e'      )
 prtFlux ('  EVAP_ICE     ', ICE_mas_evap_ice  , 'e', True)
 prtFlux ('  SNOW_OCE     ', OCE_mas_snow_oce  , 'e', True)
 prtFlux ('  SNOW_ICE     ', OCE_mas_snow_ice  , 'e', True)
-prtFlux ('  RAIN         ', OCE_mas_rain      , 'e' )
+prtFlux ('  RAIN         ', OCE_mas_rain      , 'e'      )
 prtFlux ('  FWB          ', OCE_mas_fwb       , 'e', True)
 prtFlux ('  SSR          ', OCE_mas_ssr       , 'e', True)
@@ -705,5 +681,5 @@
 
 echo ( '\n------------------------------------------------------------------------------------' )
-echo ( '-- Calculs dans la note PDF de Clement')
+echo ( '-- Computations in the PDF note of ClÃ©ment Rousset')
 echo ( 'Freshwater budget of the ice-ocean system          = emp_oce + emp_ice - runoffs - iceberg - iceshelf                = {:12.5e} (kg) '.format ( OCE_mas_emp_oce + OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceberg - OCE_mas_iceshelf ))
 echo ( 'Freshwater budget of the ice-ocean system          = emp_oce + emp_ice - friver  - iceberg - iceshelf                = {:12.5e} (kg) '.format ( OCE_mas_emp_oce + OCE_mas_emp_ice - OCE_mas_friver  - OCE_mas_iceberg - OCE_mas_iceshelf ))
Index: TOOLS/WATER_BUDGET/SetLibIGCM.py
===================================================================
--- TOOLS/WATER_BUDGET/SetLibIGCM.py	(revision 6508)
+++ TOOLS/WATER_BUDGET/SetLibIGCM.py	(revision 6508)
@@ -0,0 +1,63 @@
+# Where do we run ?
+import pathlib, os
+
+SysName, NodeName, Release, Version, Machine = os.uname ()
+TGCC  = ( 'irene'    in NodeName )
+IDRIS = ( 'jeanzay'  in NodeName )
+SPIP  = ( 'lsce5138' in NodeName ) or ( 'spip' in NodeName.lower () )
+
+## Set site specific libIGCM directories, and other specific stuff
+# ===========================================================================================
+if TGCC :
+    CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' )
+    if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene'
+    if "AMD"                       in CPU : Machine = 'irene-amd'
+
+    if libIGCM : 
+        if ARCHIVE    == None : ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' )
+        if STORAGE    == None : STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' )
+        if SCRATCHDIR == None : SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' )
+        if R_IN       == None : R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM')
+        if rebuild    == None : rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' )
+
+    ## Specific to run at TGCC.
+    # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...)
+    if platform.python_version () == '3.7.5' :
+        import mpi4py
+        mpi4py.rc.initialize = False
+        
+    ## Creates output directory name
+    if TmpDir == None :
+        TmpDir = subprocess.getoutput ( 'ccc_home -s' )
+        config['Files']['TmpDir'] = TmpDir
+        
+# ===========================================================================================
+if IDRIS :
+    Machine = 'jean-zay'
+    if libIGCM : 
+        if ARCHIVE    == None : ARCHIVE    = os.path.join ( '/', 'gpfsstore'  , 'rech', Project, User )
+        if STORAGE    == None : STORAGE    = os.path.join ( '/', 'gpfswork'   , 'rech', Project, User )
+        if SCRATCHDIR == None : SCRATCHDIR = os.path.join ( '/', 'gpfsscratch', 'rech', Project, User )
+        if R_IN       == None : R_IN       = os.path.join ( '/', 'gpfswork'   , 'rech', 'psl', 'commun', 'IGCM' )
+        if rebuild    == None : rebuild    = os.path.join ( '/', 'gpfswork', 'rech', 'psl', 'commun', 'Tools', 'rebuild', 'modipsl_IOIPSL_PLUS_v2_2_4', 'bin', 'rebuild' )
+
+    ## Creates output directory name
+    if TmpDir == None :
+        TmpDir = os.getenv ( 'CCFRSCRATCH' )
+        config['Files']['TmpDir'] = TmpDir
+
+# ===========================================================================================
+if SPIP :
+    Machine = 'spip'
+    if libIGCM : 
+        if ARCHIVE    == None : ARCHIVE    = os.path.join ( '/', 'Users', User, 'Data' )
+        if STORAGE    == None : STORAGE    = os.path.join ( '/', 'Users', User, 'Data' )
+        if SCRATCHDIR == None : SCRATCHDIR = os.path.join ( '/', 'Users', User, 'Data' )
+        if R_IN       == None : R_IN       = os.path.join ( '/', 'Users', User, 'Data', 'IGCM' )
+
+    ## Creates output directory name
+    if TmpDir == None :
+        TmpDir = os.path.join ( pathlib.Path.home (), 'Scratch' )
+        config['Files']['TmpDir'] = TmpDir
+
+# ===========================================================================================
Index: TOOLS/WATER_BUDGET/WaterUtils.py
===================================================================
--- TOOLS/WATER_BUDGET/WaterUtils.py	(revision 6508)
+++ TOOLS/WATER_BUDGET/WaterUtils.py	(revision 6508)
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+###
+### Script to check water conservation in the IPSL coupled model
+###
+## Here, some common utilities to all scripts
+##
+##  Warning, to install, configure, run, use any of included software or
+##  to read the associated documentation you'll need at least one (1)
+##  brain in a reasonably working order. Lack of this implement will
+##  void any warranties (either express or implied).  Authors assumes
+##  no responsability for errors, omissions, data loss, or any other
+##  consequences caused directly or indirectly by the usage of his
+##  software by incorrectly or partially configured personal
+##
+##
+## SVN information
+#  $Author: omamce $
+#  $Date: 2022-12-08 10:24:05 +0100 (Thu, 08 Dec 2022) $
+#  $Revision: 6277 $
+#  $Id: ATM_waterbudget.py 6277 2022-12-08 09:24:05Z omamce $
+#  $HeadURL: svn+ssh://omamce@forge.ipsl.jussieu.fr/ipsl/forge/projets/igcmg/svn/TOOLS/WATER_BUDGET/ATM_waterbudget.py $
+
+## Import system modules
+#import sys, os, shutil, subprocess, platform
+import numpy as np
+import configparser, re
+
+VarInt = 10
+Ra     = None
+
+def ftest () :
+    print ( toto )
+
+def setBool (chars) :
+    '''Convert specific char string in boolean if possible'''
+    setBool = chars
+    if type (chars) == str :
+        for key in configparser.ConfigParser.BOOLEAN_STATES.keys () :
+            if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key]
+    return setBool
+
+def setNum (chars) :
+    '''Convert specific char string in integer or real if possible'''
+    if type (chars) == str :
+        realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$")
+        isNumber = realnum.match(chars.strip()) != None
+        isInt    = chars.strip().isdigit()
+        #print (chars , isNumber , isInt)
+        if isNumber :
+            if isInt : setNum = int   (chars)
+            else     : setNum = float (chars)
+        else : setNum = chars
+    else : setNum = chars
+    return setNum
+
+def setNone (chars) :
+    '''Convert specific char string to None if possible'''
+    if type (chars) == str :
+        if chars in ['None', 'NONE', 'none'] : setNone = None
+        else : setNone = chars
+    else : setNone = chars
+    return setNone
+
+def unDefined (char) :
+    if char in globals () :
+        if globals()[char] == None : unDefined = True
+        else            : unDefined = False
+    else                : unDefined = True
+    return unDefined
+
+def Ksum (tab) :
+    '''
+    Kahan summation algorithm, also known as compensated summation
+    https://en.wikipedia.org/wiki/Kahan_summation_algorithm
+    '''
+    Ksum = 0.0                   # Prepare the accumulator.
+    comp = 0.0                   # A running compensation for lost low-order bits.
+   
+    for xx in np.where ( np.isnan(tab), 0., tab ) : 
+        yy = xx - comp           # comp is zero the first time around.
+        tt = Ksum + yy           # Alas, sum is big, y small, so low-order digits of y are lost.
+        comp = (tt - Ksum) - yy  # (tt - Ksum) cancels the high-order part of y; subtracting y recovers negative (low part of yy)
+        Ksum = tt                # Algebraically, comp should always be zero. Beware overly-aggressive optimizing compilers !
+                                 # Next time around, the lost low part will be added to y in a fresh attempt.
+    return Ksum
+
+def Ssum (tab) :
+    '''
+    Precision summation by sorting by absolute value
+    '''
+    Ssum = np.sum ( tab[np.argsort(np.abs(tab))] )
+    return Ssum
+
+def KSsum (tab) :
+    '''
+    Precision summation by sorting by absolute value, and applying Kahan summation
+    '''
+    KSsum = Ksum ( tab[np.argsort(np.abs(tab))] )
+    return KSsum
+
+# Choosing algorithm for precise summation
+Psum = KSsum
+
+
+
+
Index: TOOLS/WATER_BUDGET/lmdz.py
===================================================================
--- TOOLS/WATER_BUDGET/lmdz.py	(revision 6446)
+++ TOOLS/WATER_BUDGET/lmdz.py	(revision 6508)
@@ -238,10 +238,11 @@
     if math == xr :
         p2D = xr.DataArray (p2D)
-        p2D.attrs = p1D.attrs
+        for attr in p1D.attrs : 
+            p2D.attrs[attr] = p1D.attrs[attr]
         p2D = p2D.rename ( {p2D.dims[0]:p1D.dims[0], p2D.dims[-1]:'x', p2D.dims[-2]:'y'} )
         
     return p2D
 
-def geo2point ( p2D, cumulPoles=False, dim1D='points_physiques' ) : 
+def geo2point ( p2D, cumulPoles=False, dim1D='cell', debug=False ) : 
     '''
     From 2D (lat, lon) to 1D (points_phyiques)
@@ -259,4 +260,7 @@
 
     jpn = jpi*(jpj-2) + 2
+
+    if debug :
+        print ( f'{jpi=} {jpj=} {jpn=} {jpt=}' )
 
     if jpt == -1 :
@@ -277,5 +281,6 @@
     if math == xr :
         p1D       = xr.DataArray (p1D)
-        p1D.attrs = p2D.attrs
+        for attr in p2D.attrs :
+            p1D.attrs[attr] = p2D.attrs[attr]
         p1D       = p1D.rename ( {p1D.dims[0]:p2D.dims[0], p1D.dims[-1]:dim1D} )
 
@@ -286,5 +291,5 @@
     return p1D
 
-def geo3point ( p3D, cumulPoles=False, dim1D='points_physiques' ) : 
+def geo3point ( p3D, cumulPoles=False, dim1D='cell' ) : 
     '''
     From 3D (lev, lat, lon) to 2D (lev, points_phyiques)
@@ -314,5 +319,6 @@
     if math == xr :
         p2D       = xr.DataArray (p2D)
-        p2D.attrs = p3D.attrs
+        for attr in p2D.attrs : 
+            p2D.attrs[attr] = p3D.attrs[attr]
         p2D       = p2D.rename ( {p2D.dims[-1]:dim1D, p2D.dims[-2]:p3D.dims[-3]} )
         
