Changeset 6508 for TOOLS


Ignore:
Timestamp:
06/13/23 12:58:38 (11 months ago)
Author:
omamce
Message:

WaterUtils?.pyVersion qui marche pour :
Water Budget
O.M.

Version qui marche pour :

  • Grille LMDZ et routage SECHIBA
  • Grille ICO avec sorties natives et routage SIMPLE : routage pas très précis.

Ne marche pas pour :

  • Grille LMDZ et routage SIMPLE : pb sur runoff
  • Grille ICO avec sorties interpolées :

# Erreurs relatives

### VALID-CM622-LR.01 - LMDZ : OK ? Sauf LIC

  • LIC : 1.e-2
  • SRF : 4.e-6
  • SRF/ATM : 2e-10
  • RUNOFF : 1.5e-4

### VALID-CM622-SIMPLE-ROUTING - LMDZ : Erreur RUNOFF, LIC

  • LIC : 1.6
  • SRF : 1e-6
  • SRF/ATM : 1.e-10
  • RUNOFF : -7

### TEST-CM72-SIMPLE-ROUTING.13 - ICO : Erreur SRF, RUNOFF, LIC

  • LIC : 150
  • SRF : 0.5
  • SRF/ATM : 4e-2
  • RUNOFF : 700

### CM71v420-LR-pd-02.ini - ICO interpolé : Erreur SRF, RUNOFF, LIC

  • LIC : 15
  • SRF : 0.7
  • SRF/ATM : -5.e-2
  • ROUTING : 3e3

### CM71v420-LR-pd-02.ini - ICO natif : Erreurs faibles RUNOFF, LIC

  • LIC : 0.3
  • SRF : 7.e-6
  • SRF/ATM : -6.e-9
  • ROUTING : 5.e-2
Location:
TOOLS/WATER_BUDGET
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • TOOLS/WATER_BUDGET/ATM_waterbudget.py

    r6277 r6508  
    2525import configparser, re 
    2626 
    27 ## Creates parser 
    28 config = configparser.ConfigParser() 
     27# Check python version 
     28if sys.version_info < (3, 8, 0) : 
     29    print ( f'Python version : {platform.python_version()}' )  
     30    raise Exception ( "Minimum Python version is 3.8" ) 
     31 
     32## Import local module 
     33import WaterUtils as wu 
     34 
     35## Creates parser for reading .ini input file 
     36config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    2937config.optionxform = str # To keep capitals 
    3038 
    31 ## Read experiment parameters 
    32 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 
     39## Experiment parameters 
     40ATM=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 
    3341 
    3442## 
    35 ARCHIVE =None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None 
    36 TmpDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 
     43ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None 
     44TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 
    3745file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None 
    38 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 
    39 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 
    40  
    41 d_ATM_his=None ; d_SRF_his=None ; d_RUN_his=None ; d_OCE_his=None ;  d_ICE_his=None ; d_OCE_sca=None 
    42 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 
    43 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 
    44  
    45 # Arguments passed 
     46tar_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 
     47file_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 
     48tar_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 
     49tar_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 
     50SortIco = False 
     51 
     52# Read command line arguments 
    4653print ( "Name of Python script:", sys.argv[0] ) 
    4754IniFile = sys.argv[1] 
     55# Text existence of IniFile 
     56if not os.path.exists (IniFile ) : 
     57    raise FileExistsError ( f"File not found : {IniFile = }" ) 
     58 
     59if 'full' in IniFile : FullIniFile = IniFile 
     60else                 : FullIniFile = 'full_' + IniFile 
     61     
    4862print ("Input file : ", IniFile ) 
    4963config.read (IniFile) 
    5064FullIniFile = 'full_' + IniFile 
    5165 
    52 def setBool (chars) : 
    53     '''Convert specific char string in boolean if possible''' 
    54     setBool = chars 
    55     for key in configparser.ConfigParser.BOOLEAN_STATES.keys () : 
    56         if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key] 
    57     return setBool 
    58  
    59 def setNum (chars) : 
    60     '''Convert specific char string in integer or real if possible''' 
    61     if type (chars) == str : 
    62         realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$") 
    63         isReal = realnum.match(chars.strip()) != None 
    64         isInt  = chars.strip().isdigit() 
    65         if isReal : 
    66             if isInt : setNum = int   (chars) 
    67             else     : setNum = float (chars) 
    68         else : setNum = chars 
    69     else : setNum = chars 
    70     return setNum 
    71  
    72 def setNone (chars) : 
    73     '''Convert specific char string to None if possible''' 
    74     if type (chars) == str : 
    75         if chars in ['None', 'NONE', 'none'] : setNone = None 
    76         else : setNone = chars 
    77     else : setNone = chars 
    78     return setNone 
    79  
    80 ## Reading config 
    81 for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] : 
    82     if Section in config.keys() :  
    83         print ( f'[{Section}]' ) 
     66## Reading config file 
     67for Section in ['Config', 'Experiment', 'libIGCM', 'Files', 'Physics' ] : 
     68   if Section in config.keys () :  
     69        print ( f'\nReading [{Section}]' ) 
    8470        for VarName in config[Section].keys() : 
    8571            locals()[VarName] = config[Section][VarName] 
    86             locals()[VarName] = setBool (locals()[VarName]) 
    87             locals()[VarName] = setNum  (locals()[VarName]) 
    88             print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) ) 
    89  
    90 if not 'Files' in config.keys() : config['Files'] = {} 
    91  
    92 def unDefined (char) : 
    93     if char in globals () : 
    94         if char == None : return True 
    95         else : return False 
    96     else : return True 
    97  
     72            exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
     73            exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
     74            exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
     75            exec  ( f'wu.{VarName} = {VarName}' ) 
     76            print ( f'{VarName:25} set to : {locals()[VarName]:}' ) 
     77            #exec ( f'del {VarName}' ) 
     78 
     79print ( f'\nConfig file readed : {IniFile} ' ) 
     80             
    9881##-- Some physical constants 
    99 #-- Earth Radius 
    100 if not 'Ra'            in locals () : Ra = 6366197.7236758135 
    101 #-- Gravity 
    102 if not 'Grav'          in locals () : Grav = 9.81 
    103 #-- Ice volumic mass (kg/m3) in LIM3 
    104 if not 'ICE_rho_ice'   in locals () : ICE_rho_ice = 917.0 
    105 #-- Snow volumic mass (kg/m3) in LIM3 
    106 if not 'ICE_rho_sno'   in locals () : ICE_rho_sno = 330.0 
    107 #-- Ocean water volumic mass (kg/m3) in NEMO 
    108 if not 'OCE_rho_liq'   in locals () : OCE_rho_liq = 1026. 
    109 #-- Water volumic mass in atmosphere 
    110 if not 'ATM_rho'       in locals () : ATM_rho = 1000. 
    111 #-- Water volumic mass in surface reservoirs 
    112 if not 'SRF_rho'       in locals () : SRF_rho = 1000. 
    113 #-- Water volumic mass of rivers 
    114 if not 'RUN_rho'       in locals () : RUN_rho = 1000. 
    115 #-- Year length 
    116 if not 'YearLength'    in locals () : YearLength = 365.25 * 24. * 60. * 60. 
     82if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m) 
     83if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s 
     84if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3 
     85if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3 
     86if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO 
     87if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3) 
     88if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3) 
     89if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3) 
     90if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3) 
     91if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s) - Use only to compute drif in approximate unit  
     92             
     93##-- Set libIGCM and machine dependant values 
     94if not 'Files' in config.keys () : config['Files'] = {} 
    11795 
    11896config['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} 
    11997 
    120 ## -- 
    121 ICO  = ( 'ICO' in ATM ) 
    122 LMDZ = ( 'LMD' in ATM ) 
    123      
    124  
    125 # Where do we run ? 
    126 SysName, NodeName, Release, Version, Machine = os.uname () 
    127 TGCC  = ( 'irene'   in NodeName ) 
    128 IDRIS = ( 'jeanzay' in NodeName ) 
    129  
    130 ## Set site specific libIGCM directories, and other specific stuff 
    131 if TGCC : 
    132     CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' ) 
    133     if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene' 
    134     if "AMD"                       in CPU : Machine = 'irene-amd' 
    135  
    136     if libIGCM :  
    137         if ARCHIVE    == None : ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' ) 
    138         if STORAGE    == None : STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' ) 
    139         if SCRATCHDIR == None : SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' ) 
    140         if R_IN       == None : R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM') 
    141         if rebuild    == None : rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' ) 
    142  
    143     ## Specific to run at TGCC. 
    144     # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...) 
    145     import mpi4py 
    146     mpi4py.rc.initialize = False 
    147          
    148     ## Creates output directory 
    149     if TmpDir == None : 
    150         TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
    151         config['Files']['TmpDir'] = TmpDir 
    152          
    153 if IDRIS : 
    154     raise Exception ("Pour IDRIS : repertoires et chemins a definir")  
    155  
    156 config['System'] = {'SysName':SysName, 'NodeName':NodeName, 'Release':Release, 'Version':Version,'Machine':Machine, 'TGCC':TGCC,'IDRIS':IDRIS, 'CPU':CPU, 
    157                     'Program'  : "Generated by : " + str(sys.argv),  
    158                     'HOSTNAME' : platform.node (), 'LOGNAME'  : os.getlogin (), 
    159                     'Python'   : f'{platform.python_version ()}', 
    160                     'OS'       : f'{platform.system ()} release : {platform.release ()} hardware : {platform.machine ()}', 
    161                     'SVN_Author'   : "$Author$",  
    162                     'SVN_Date'     : "$Date$", 
    163                     'SVN_Revision' : "$Revision$", 
    164                     'SVN_Id'       : "$Id$", 
    165                     'SVN_HeadURL'  : "$HeadURL$"} 
     98config['Config'] = { 'ContinueOnError':ContinueOnError, 'SortIco':SortIco} 
     99 
     100## -------------------------- 
     101ICO  = ( 'ICO' in wu.ATM ) 
     102LMDZ = ( 'LMD' in wu.ATM ) 
     103     
     104with open ('SetLibIGCM.py') as f: exec ( f.read() ) 
     105config['Files']['TmpDir'] = TmpDir 
    166106 
    167107if libIGCM : 
    168108    config['libIGCM'] = {'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'SCRATCHDIR':SCRATCHDIR, 'R_IN':R_IN, 'rebuild':rebuild } 
    169109 
    170 ## Import specific module 
     110##-- Import specific module 
    171111import nemo, lmdz 
    172 ## Now import needed scientific modules 
     112##-- Now import needed scientific modules 
    173113import xarray as xr 
    174114 
    175 # Output file 
    176 if FileOut == None :  
    177     FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
    178     config['Files']['FileOut'] = FileOut 
     115##- Output file with water budget diagnostics 
     116if wu.unDefined ( 'FileOut' ) : FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
     117config['Files']['FileOut'] = FileOut 
    179118 
    180119f_out = open ( FileOut, mode = 'w' ) 
    181120 
    182 # Function to print to stdout *and* output file 
     121##- Useful functions 
     122def kg2Sv    (val, rho=ATM_rho) : 
     123    '''From kg to Sverdrup''' 
     124    return val/dtime_sec*1.0e-6/rho 
     125 
     126def kg2myear (val, rho=ATM_rho) : 
     127    '''From kg to m/year''' 
     128    return val/ATM_aire_sea_tot/rho/NbYear 
     129 
     130def var2prt (var, small=False, rho=ATM_rho) : 
     131    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000. 
     132    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho) 
     133 
     134def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) : 
     135    if small : 
     136        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
     137        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year " 
     138    else : 
     139        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  " 
     140        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  " 
     141    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) ) 
     142    return None 
     143 
    183144def echo (string, end='\n') : 
     145    '''Function to print to stdout *and* output file''' 
    184146    print ( str(string), end=end  ) 
    185147    sys.stdout.flush () 
     
    188150    return None 
    189151     
    190 ## Set libIGCM directories 
    191 R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT') 
    192 R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT') 
    193  
    194 L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    195 R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    196 R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    197 POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' ) 
    198 REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' ) 
    199 R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    200 R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    201  
    202 #if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir ) 
    203 if not os.path.isdir (TmpDir) : os.mkdir (TmpDir) 
    204 TmpDirOCE = os.path.join (TmpDir, 'OCE') 
    205 TmpDirICE = os.path.join (TmpDir, 'ICE') 
    206 if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE ) 
    207 if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE ) 
     152##- Set libIGCM directories 
     153if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
     154if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
     155if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
     156if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
     157if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
     158if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
     159if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' ) 
     160if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
     161if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
     162 
     163config['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 } 
     164 
     165##- Set directory to extract files 
     166if wu.unDefined ( 'RunDir' ) : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
     167config['Files']['RunDir'] = RunDir 
     168 
     169if not os.path.isdir ( RunDir ) : os.makedirs ( RunDir ) 
     170 
     171##- Set directories to rebuild ocean and ice restart files 
     172if wu.unDefined ( 'RunDirOCE' ) : RunDirOCE = os.path.join ( RunDir, 'OCE' ) 
     173if wu.unDefined ( 'RunDirICE' ) : RunDirICE = os.path.join ( RunDir, 'ICE' ) 
     174if not os.path.exists ( RunDirOCE ) : os.mkdir ( RunDirOCE ) 
     175if not os.path.exists ( RunDirICE ) : os.mkdir ( RunDirICE ) 
    208176 
    209177echo (' ') 
    210 echo ( f'JobName : {JobName}' ) 
    211 echo (Comment) 
    212 echo ( f'Working in TMPDIR : {TmpDir}' ) 
    213  
    214 echo ( f'\nDealing with {L_EXP}' ) 
    215  
    216 #-- Model output directories 
     178echo ( f'JobName   : {JobName}'   ) 
     179echo ( f'Comment   : {Comment}'   ) 
     180echo ( f'TmpDir    : {TmpDir}'    ) 
     181echo ( f'RunDir    : {RunDir}'    ) 
     182echo ( f'RunDirOCE : {RunDirOCE}' ) 
     183echo ( f'RunDirICE : {RunDirICE}' ) 
     184 
     185echo ( f'\nDealing with {L_EXP}'  ) 
     186 
     187##-- Creates model output directory names 
    217188if Freq == "MO" : FreqDir = os.path.join ('Output' , 'MO' ) 
    218189if Freq == "SE" : FreqDir = os.path.join ('Analyse', 'SE' ) 
    219 if dir_ATM_his == None : 
     190if wu.unDefined ('dir_ATM_his' ) : 
    220191    dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) 
    221192    config['Files']['dir_ATM_his'] = dir_ATM_his 
    222 if dir_SRF_his == None :  
     193if wu.unDefined ( 'dir_SRF_his' ) :  
    223194    dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) 
    224195    config['Files']['dir_SRF_his'] = dir_SRF_his 
    225196     
    226197echo ( f'The analysis relies on files from the following model output directories : ' ) 
    227 echo ( f'{dir_ATM_his}' ) 
    228 echo ( f'{dir_SRF_his}' ) 
    229  
    230 #-- Files Names 
    231 if Period == None : 
     198echo ( f'{dir_ATM_his = }' ) 
     199echo ( f'{dir_SRF_his = }' ) 
     200 
     201##-- Creates files names 
     202if wu.unDefined ( 'Period' ) : 
    232203    if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M' 
    233204    if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M' 
    234205    config['Files']['Period'] = Period 
    235 if FileCommon == None : 
     206if wu.unDefined ( 'FileCommon' ) : 
    236207    FileCommon = f'{JobName}_{Period}' 
    237208    config['Files']['FileCommon'] = FileCommon 
    238209 
    239 if Title == None : 
     210if wu.unDefined ( 'Title' ) : 
    240211    Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31' 
    241212    config['Files']['Title'] = Title 
    242213      
    243214echo ('\nOpen history files' ) 
    244 if file_ATM_his == None :  
     215if wu.unDefined ( 'file_ATM_his' ) :  
    245216    file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' ) 
    246217    config['Files']['file_ATM_his'] = file_ATM_his 
    247 if file_SRF_his == None : 
     218if wu.unDefined ( 'file_SRF_his' ) : 
    248219    file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    249220    config['Files']['file_SRF_his'] = file_SRF_his 
     
    257228d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    258229d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    259 if Routing == 'SECHIBA' : 
    260     d_RUN_his = d_SRF_his 
    261 if Routing == 'SIMPLE' :  
    262     d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    263  
    264 echo ( file_ATM_his ) 
    265 echo ( file_SRF_his ) 
    266 if Routing == 'SIMPLE' :  
    267     echo ( file_RUN_his ) 
    268  
    269 ## Compute run length 
     230if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his 
     231if Routing == 'SIMPLE'  : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     232 
     233echo ( f'{file_ATM_his = }' ) 
     234echo ( f'{file_SRF_his = }' ) 
     235if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' ) 
     236 
     237##-- Compute run length 
    270238dtime = ( d_ATM_his.time_counter_bounds.max() - d_ATM_his.time_counter_bounds.min() ) 
    271239echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) ) 
    272240dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds 
    273241 
    274 ## Compute length of each period 
     242##-- Compute length of each period 
    275243dtime_per = (d_ATM_his.time_counter_bounds[:,-1] -  d_ATM_his.time_counter_bounds[:,0] ) 
    276244echo ('\nPeriods lengths (days) : {:} days'.format ( (dtime_per/np.timedelta64(1, "D")).values ) ) 
    277245dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds 
    278246dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] ) 
    279  
    280 ## Number of years 
     247dtime_per_sec.attrs['unit'] = 's' 
     248 
     249##-- Number of years (approximative) 
    281250NbYear = dtime_sec / YearLength 
    282251 
    283 #-- Open restart files 
    284  
     252##-- Extract restart files from tar 
    285253YearRes = YearBegin - 1              # Year of the restart of beginning of simulation 
    286254YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation 
    287255 
    288 if TarRestartPeriod_beg == None :  
     256config['Files']['YearPre'] = f'{YearBegin}' 
     257 
     258if wu.unDefined ( 'TarRestartPeriod_beg' ) :  
    289259    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
    290260    TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231' 
    291261    config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg 
    292262 
    293 if TarRestartPeriod_end == None :  
     263if wu.unDefined ( 'TarRestartPeriod_end ' ) :  
    294264    YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation 
    295265    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
     
    297267    config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end 
    298268 
    299 if file_restart_beg == None : 
    300     file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
    301     config['Files']['file_restart_beg'] = file_restart_beg 
    302 if file_restart_end == None : 
    303     file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
    304     config['Files']['file_restart_end'] = file_restart_end 
    305      
    306 echo ( f'{file_restart_beg}' ) 
    307 echo ( f'{file_restart_end}' ) 
    308  
    309 if file_ATM_beg == None :  
    310     file_ATM_beg = f'{TmpDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc' 
     269if wu.unDefined ( 'tar_restart_beg' ) : 
     270    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
     271    config['Files']['tar_restart_beg'] = tar_restart_beg 
     272if wu.unDefined ( 'tar_restart_end' ) : 
     273    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
     274    config['Files']['tar_restart_end'] = tar_restart_end 
     275     
     276echo ( f'{tar_restart_beg = }' ) 
     277echo ( f'{tar_restart_end = }' ) 
     278 
     279##-- Names of tar files with restarts 
     280if wu.unDefined ( 'SRF_HIS' ) : SRF_HIS = ATM_HIS 
     281 
     282if wu.unDefined ( 'tar_restart_beg_ATM' ) : tar_restart_beg_ATM = tar_restart_beg 
     283if wu.unDefined ( 'tar_restart_beg_DYN' ) : tar_restart_beg_DYN = tar_restart_beg 
     284if wu.unDefined ( 'tar_restart_beg_SRF' ) : tar_restart_beg_SRF = tar_restart_beg 
     285if wu.unDefined ( 'tar_restart_beg_RUN' ) : tar_restart_beg_RUN = tar_restart_beg 
     286if wu.unDefined ( 'tar_restart_beg_OCE' ) : tar_restart_beg_OCE = tar_restart_beg 
     287if wu.unDefined ( 'tar_restart_beg_ICE' ) : tar_restart_beg_ICE = tar_restart_beg 
     288 
     289if wu.unDefined ( 'tar_restart_end_ATM' ) : tar_restart_end_ATM = tar_restart_end 
     290if wu.unDefined ( 'tar_restart_end_DYN' ) : tar_restart_end_DYN = tar_restart_end 
     291if wu.unDefined ( 'tar_restart_end_SRF' ) : tar_restart_end_SRF = tar_restart_end 
     292if wu.unDefined ( 'tar_restart_end_RUN' ) : tar_restart_end_RUN = tar_restart_end 
     293if wu.unDefined ( 'tar_restart_end_OCE' ) : tar_restart_end_OCE = tar_restart_end 
     294if wu.unDefined ( 'tar_restart_end_ICE' ) : tar_restart_end_ICE = tar_restart_end 
     295 
     296if wu.unDefined ( 'file_ATM_beg' ) :  
     297    file_ATM_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc' 
    311298    config['Files']['file_ATM_beg'] = file_ATM_beg 
    312 if file_ATM_end == None : 
    313     file_ATM_end = f'{TmpDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc' 
     299if wu.unDefined ( 'file_ATM_end' ) : 
     300    file_ATM_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc' 
    314301    config['Files']['file_ATM_end'] = file_ATM_end 
    315302 
    316303liste_beg = [file_ATM_beg, ] 
    317304liste_end = [file_ATM_end, ] 
    318      
    319  
    320 if file_DYN_beg == None : 
    321     if LMDZ : 
    322         file_DYN_beg = f'{TmpDir}/ATM_{JobName}_{YearRes}1231_restart.nc' 
    323     if ICO  : 
    324         file_DYN_beg = f'{TmpDir}/ICO_{JobName}_{YearRes}1231_restart.nc' 
     305 
     306if wu.unDefined ( 'file_DYN_beg' ) : 
     307    if LMDZ : file_DYN_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restart.nc' 
     308    if ICO  : file_DYN_beg = f'{RunDir}/ICO_{JobName}_{YearRes}1231_restart.nc' 
    325309    liste_beg.append (file_DYN_beg) 
    326310    config['Files']['file_DYN_beg'] = file_DYN_beg 
    327311     
    328 if file_DYN_end == None :  
    329     if LMDZ : 
    330         file_DYN_end = f'{TmpDir}/ATM_{JobName}_{YearEnd}1231_restart.nc' 
    331     if ICO  : 
    332         file_DYN_end = f'{TmpDir}/ICO_{JobName}_{YearEnd}1231_restart.nc' 
     312if wu.unDefined ( 'file_DYN_end' ) :  
     313    if LMDZ : file_DYN_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restart.nc' 
     314    if ICO  : file_DYN_end = f'{RunDir}/ICO_{JobName}_{YearEnd}1231_restart.nc' 
    333315    liste_end.append ( file_DYN_end ) 
    334316    config['Files']['file_DYN_end'] = file_DYN_end 
    335317 
    336 if file_SRF_beg == None :  
    337     file_SRF_beg = f'{TmpDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc' 
     318if wu.unDefined ( 'file_SRF_beg' ) : 
     319    file_SRF_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc' 
    338320    config['Files']['file_SRF_beg'] = file_SRF_beg 
    339 if file_SRF_end == None :  
    340     file_SRF_end = f'{TmpDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc' 
     321if wu.unDefined ( 'file_SRF_end' ) : 
     322    file_SRF_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc' 
    341323    config['Files']['file_SRF_end'] = file_SRF_end 
    342324     
     
    344326liste_end.append ( file_SRF_end ) 
    345327 
    346 echo ( f'{file_ATM_beg}') 
    347 echo ( f'{file_ATM_end}') 
    348 echo ( f'{file_DYN_beg}') 
    349 echo ( f'{file_DYN_end}') 
    350 echo ( f'{file_SRF_beg}') 
    351 echo ( f'{file_SRF_end}') 
     328echo ( f'{file_ATM_beg = }') 
     329echo ( f'{file_ATM_end = }') 
     330echo ( f'{file_DYN_beg = }') 
     331echo ( f'{file_DYN_end = }') 
     332echo ( f'{file_SRF_beg = }') 
     333echo ( f'{file_SRF_end = }') 
     334 
     335if ICO : 
     336    if wu.unDefined ('file_DYN_aire') : file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) 
     337    config['Files'] ['file_DYN_aire'] = file_DYN_aire 
    352338 
    353339if Routing == 'SIMPLE' : 
    354     if file_RUN_beg == None :  
    355         file_RUN_beg = f'{TmpDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc' 
     340    if wu.unDefined ( 'file_RUN_beg' ) :  
     341        file_RUN_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc' 
    356342        config['Files']['file_RUN_beg'] = file_RUN_beg 
    357     if file_RUN_end == None :  
    358         file_RUN_end = f'{TmpDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc' 
     343    if wu.unDefined ( 'file_RUN_end' ) :  
     344        file_RUN_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc' 
    359345        config['Files']['file_RUN_end'] = file_RUN_end 
    360346         
    361347    liste_beg.append ( file_RUN_beg ) 
    362348    liste_end.append ( file_RUN_end ) 
    363     echo ( f'{file_RUN_beg}') 
    364     echo ( f'{file_RUN_end}') 
     349    echo ( f'{file_RUN_beg = }' ) 
     350    echo ( f'{file_RUN_end = }' ) 
    365351 
    366352echo ('\nExtract restart files from tar : ATM, ICO and SRF') 
    367 for resFile in liste_beg : 
    368     if os.path.exists ( os.path.join (TmpDir, resFile) ) : 
    369         echo ( f'file found : {resFile}' ) 
     353 
     354def extract_and_rebuild ( file_name=file_ATM_beg, tar_restart=tar_restart_end, RunDirComp=RunDir, ErrorCount=ErrorCount ) : 
     355    echo ( f'----------') 
     356    echo ( f'file to extract : {file_name = }' ) 
     357    if os.path.exists ( os.path.join (RunDir, file_name) ) : 
     358        echo ( f'file found : {file_name = }' ) 
    370359    else : 
    371         base_resFile = os.path.basename (resFile) 
    372         command =  f'cd {TmpDir} ; tar xf {file_restart_beg} {base_resFile}' 
    373         echo ( command ) 
    374         os.system ( command ) 
    375          
    376 for resFile in liste_end : 
    377     if os.path.exists ( os.path.join (TmpDir, resFile) ) : 
    378         echo ( f'file found : {resFile}' ) 
    379     else : 
    380         base_resFile = os.path.basename (resFile) 
    381         command =  f'cd {TmpDir} ; tar xf {file_restart_end} {base_resFile}' 
    382         echo ( command ) 
    383         os.system ( command ) 
    384         
     360        echo ( f'file not found : {file_name = }' ) 
     361        base_resFile = os.path.basename (file_name) 
     362        if os.path.exists ( tar_restart ) : 
     363            command =  f'cd {RunDir} ; tar xf {tar_restart} {base_resFile}' 
     364            echo ( f'{command = }' ) 
     365            try :  
     366                os.system ( command ) 
     367            except : 
     368                if ContinueOnError : 
     369                    ErrorCount += 1 
     370                    echo ( f'****** Command failed : {command}' ) 
     371                    echo ( f'****** Trying to continue' ) 
     372                    echo ( ' ') 
     373                else : 
     374                    raise Exception ( f'**** command failed : {command} - Stopping' ) 
     375            else : 
     376                echo ( f'tar done : {base_resFile}' ) 
     377        else : 
     378            echo ( f'****** Tar restart file {tar_restart = } not found ' ) 
     379            if ContinueOnError : 
     380                ErrorCount += 1 
     381            else :  
     382                raise Exception ( f'****** tar file not found {tar_restart = } - Stopping' ) 
     383    return ErrorCount 
     384  
     385ErrorCount += extract_and_rebuild ( file_name=file_ATM_beg, tar_restart=tar_restart_beg_ATM, RunDirComp=RunDir ) 
     386ErrorCount += extract_and_rebuild ( file_name=file_DYN_beg, tar_restart=tar_restart_beg_DYN, RunDirComp=RunDir ) 
     387ErrorCount += extract_and_rebuild ( file_name=file_SRF_beg, tar_restart=tar_restart_beg_SRF, RunDirComp=RunDir ) 
     388 
     389ErrorCount += extract_and_rebuild ( file_name=file_ATM_end, tar_restart=tar_restart_end_ATM, RunDirComp=RunDir ) 
     390ErrorCount += extract_and_rebuild ( file_name=file_DYN_end, tar_restart=tar_restart_end_DYN, RunDirComp=RunDir ) 
     391ErrorCount += extract_and_rebuild ( file_name=file_SRF_end, tar_restart=tar_restart_end_SRF, RunDirComp=RunDir ) 
     392 
     393if Routing == 'SIMPLE' : 
     394    ErrorCount += extract_and_rebuild ( file_name=file_RUN_beg, tar_restart=tar_restart_beg_RUN, RunDirComp=RunDir ) 
     395    ErrorCount += extract_and_rebuild ( file_name=file_RUN_end, tar_restart=tar_restart_end_RUN, RunDirComp=RunDir ) 
     396 
     397##-- Exit in case of error in the opening file phase 
     398if ErrorCount > 0 : 
     399    echo ( '  ' ) 
     400    raise Exception ( f'**** Some files missing - Stopping - {ErrorCount = }' ) 
     401 
     402##  
    385403echo ('\nOpening ATM SRF and ICO restart files') 
    386 d_ATM_beg = xr.open_dataset ( os.path.join (TmpDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze() 
    387 d_ATM_end = xr.open_dataset ( os.path.join (TmpDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze() 
    388 d_SRF_beg = xr.open_dataset ( os.path.join (TmpDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze() 
    389 d_SRF_end = xr.open_dataset ( os.path.join (TmpDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze() 
    390 d_DYN_beg = xr.open_dataset ( os.path.join (TmpDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze() 
    391 d_DYN_end = xr.open_dataset ( os.path.join (TmpDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze() 
     404d_ATM_beg = xr.open_dataset ( os.path.join (RunDir, file_ATM_beg), decode_times=False, decode_cf=True ).squeeze() 
     405d_ATM_end = xr.open_dataset ( os.path.join (RunDir, file_ATM_end), decode_times=False, decode_cf=True ).squeeze() 
     406d_SRF_beg = xr.open_dataset ( os.path.join (RunDir, file_SRF_beg), decode_times=False, decode_cf=True ).squeeze() 
     407d_SRF_end = xr.open_dataset ( os.path.join (RunDir, file_SRF_end), decode_times=False, decode_cf=True ).squeeze() 
     408d_DYN_beg = xr.open_dataset ( os.path.join (RunDir, file_DYN_beg), decode_times=False, decode_cf=True ).squeeze() 
     409d_DYN_end = xr.open_dataset ( os.path.join (RunDir, file_DYN_end), decode_times=False, decode_cf=True ).squeeze() 
    392410 
    393411for var in d_SRF_beg.variables : 
     
    396414 
    397415if Routing == 'SIMPLE' : 
    398     d_RUN_beg = xr.open_dataset ( os.path.join (TmpDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze() 
    399     d_RUN_end = xr.open_dataset ( os.path.join (TmpDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze() 
    400      
    401 echo ( file_ATM_beg ) 
    402 echo ( file_ATM_end ) 
    403 echo ( file_DYN_beg ) 
    404 echo ( file_DYN_end ) 
    405 echo ( file_SRF_beg ) 
    406 echo ( file_SRF_end ) 
     416    d_RUN_beg = xr.open_dataset ( os.path.join (RunDir, file_RUN_beg), decode_times=False, decode_cf=True ).squeeze() 
     417    d_RUN_end = xr.open_dataset ( os.path.join (RunDir, file_RUN_end), decode_times=False, decode_cf=True ).squeeze() 
     418 
     419def to_cell ( dd, newname='cell' ) : 
     420    '''Set space dimension to 'cell' ''' 
     421    for oldname in [ 'cell_mesh', 'y', 'points_physiques' ] : 
     422        try    : dd = dd.rename ( {oldname : newname} ) 
     423        except : pass 
     424    return dd 
     425 
     426d_ATM_beg = to_cell ( d_ATM_beg ) 
     427d_ATM_end = to_cell ( d_ATM_end ) 
     428d_SRF_beg = to_cell ( d_SRF_beg ) 
     429d_SRF_end = to_cell ( d_SRF_end ) 
     430d_DYN_beg = to_cell ( d_DYN_beg ) 
     431d_DYN_end = to_cell ( d_DYN_end ) 
     432 
    407433if Routing == 'SIMPLE' : 
    408     echo ( file_RUN_beg ) 
    409     echo ( file_RUN_end ) 
    410  
    411 ## 
     434    d_RUN_beg = to_cell ( d_RUN_beg ) 
     435    d_RUN_end = to_cell ( d_RUN_end ) 
     436 
     437d_ATM_his = to_cell ( d_ATM_his ) 
     438d_SRF_his = to_cell ( d_SRF_his ) 
     439     
     440echo ( f'{file_ATM_beg = }' ) 
     441echo ( f'{file_ATM_end = }' ) 
     442echo ( f'{file_DYN_beg = }' ) 
     443echo ( f'{file_DYN_end = }' ) 
     444echo ( f'{file_SRF_beg = }' ) 
     445echo ( f'{file_SRF_end = }' ) 
     446if Routing == 'SIMPLE' : 
     447    echo ( f'{file_RUN_beg = }' ) 
     448    echo ( f'{file_RUN_end = }' ) 
     449 
     450## Write the full configuration 
    412451config_out = open (FullIniFile, 'w') 
    413 config.write (config_out ) 
     452config.write ( config_out ) 
    414453config_out.close () 
    415454 
    416 def Ksum (tab) : 
    417     ''' 
    418     Kahan summation algorithm, also known as compensated summation 
    419     https://en.wikipedia.org/wiki/Kahan_summation_algorithm 
    420     ''' 
    421     Ksum = 0.0                   # Prepare the accumulator. 
    422     comp = 0.0                   # A running compensation for lost low-order bits. 
    423     
    424     for xx in np.where ( np.isnan(tab), 0., tab ) :  
    425         yy = xx - comp           # comp is zero the first time around. 
    426         tt = Ksum + yy           # Alas, sum is big, y small, so low-order digits of y are lost. 
    427         comp = (tt - Ksum) - yy  # (tt - Ksum) cancels the high-order part of y; subtracting y recovers negative (low part of yy) 
    428         Ksum = tt                # Algebraically, comp should always be zero. Beware overly-aggressive optimizing compilers! 
    429                                  # Next time around, the lost low part will be added to y in a fresh attempt. 
    430     return Ksum 
    431  
    432 def Ssum (tab) : 
    433     ''' 
    434     Precision summation by sorting by absolute value 
    435     ''' 
    436     Ssum = np.sum ( tab[np.argsort(np.abs(tab))] ) 
    437     return Ssum 
    438  
    439 def KSsum (tab) : 
    440     ''' 
    441     Precision summation by sorting by absolute value, and applying Kahan summation 
    442     ''' 
    443     KSsum = Ksum ( tab[np.argsort(np.abs(tab))] ) 
    444     return KSsum 
    445  
    446 # Choosing algorithm 
    447 Psum = KSsum 
    448  
    449 def ATM_stock_int (stock) : 
    450     '''Integrate stock on atmosphere grid''' 
    451     ATM_stock_int  = Psum ( (stock * DYN_aire).to_masked_array().ravel() )  
    452     return ATM_stock_int 
    453  
    454 def ATM_flux_int (flux) : 
    455     '''Integrate flux on atmosphere grid''' 
    456     ATM_flux_int  = Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() ) 
    457     return ATM_flux_int 
    458  
    459 def SRF_stock_int (stock) : 
    460     '''Integrate stock on land grid''' 
    461     ATM_stock_int  = Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) ) 
    462     return ATM_stock_int 
    463  
    464 def SRF_flux_int (flux) : 
    465     '''Integrate flux on land grid''' 
    466     SRF_flux_int  = Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() ) 
    467     return SRF_flux_int 
    468  
    469 def ONE_stock_int (stock) : 
    470     '''Sum stock ''' 
    471     ONE_stock_int  = Psum ( stock.to_masked_array().ravel() ) 
    472     return ONE_stock_int 
    473  
    474 def ONE_flux_int (flux) : 
    475     '''Sum flux ''' 
    476     ONE_flux_int  = Psum ( (flux * dtime_per_sec ).to_masked_array().ravel() ) 
    477     return ONE_flux_int 
    478  
    479 def kg2Sv  (val, rho=ATM_rho) : 
    480     '''From kg to Sverdrup''' 
    481     return val/dtime_sec*1.0e-6/rho 
    482  
    483 def kg2myear (val, rho=ATM_rho) : 
    484     '''From kg to m/year''' 
    485     return val/ATM_aire_sea_tot/rho/NbYear 
    486      
     455if ICO : 
     456    if SortIco :  
     457        # Creation d'une clef de tri pour les restarts (pour chaque restart !) 
     458        DYN_beg_keysort = np.lexsort ( (d_DYN_beg['lat_mesh'], d_DYN_beg['lon_mesh'] ) ) 
     459        ATM_beg_keysort = np.lexsort ( (d_ATM_beg['latitude'], d_ATM_beg['longitude']) ) 
     460        SRF_beg_keysort = np.lexsort ( (d_SRF_beg['nav_lat' ], d_SRF_beg['nav_lon']  ) ) 
     461        DYN_end_keysort = np.lexsort ( (d_DYN_end['lat_mesh'], d_DYN_end['lon_mesh'] ) ) 
     462        ATM_end_keysort = np.lexsort ( (d_ATM_end['latitude'], d_ATM_end['longitude']) ) 
     463        SRF_end_keysort = np.lexsort ( (d_SRF_end['nav_lat' ], d_SRF_end['nav_lon']  ) ) 
     464         
     465        if ATM_HIS == 'ico' : 
     466            ATM_his_keysort = np.lexsort ( (d_ATM_his['lat'], d_ATM_his['lon'] ) ) 
     467        if SRF_HIS == 'ico' : 
     468            SRF_his_keysort = np.lexsort ( (d_SRF_his['lat'], d_SRF_his['lon'] ) ) 
     469            RUN_his_keysort = SRF_his_keysort 
     470    else :  
     471        DYN_beg_keysort = np.arange ( len ( d_DYN_beg['lat_mesh'] ) ) 
     472        ATM_beg_keysort = DYN_beg_keysort 
     473        SRF_beg_keysort = DYN_beg_keysort 
     474 
     475        DYN_end_keysort = DYN_beg_keysort 
     476        ATM_end_keysort = DYN_beg_keysort 
     477        SRF_end_keysort = DYN_beg_keysort 
     478     
     479        ATM_his_keysort = DYN_beg_keysort 
     480        SRF_his_keysort = DYN_beg_keysort 
     481        RUN_his_keysort = SRF_his_keysort 
     482         
    487483# ATM grid with cell surfaces 
     484if LMDZ : 
     485    #ATM_lat  = lmdz.geo2point ( d_ATM_his ['lat']         , dim1D='cell' ) 
     486    #ATM_lon  = lmdz.geo2point ( d_ATM_his ['lon']         , dim1D='cell' ) 
     487    ATM_aire = lmdz.geo2point ( d_ATM_his ['aire']     [0], cumulPoles=True, dim1D='cell' ) 
     488    ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell' ) 
     489    ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell' ) 
     490    ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell' ) 
     491    ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell' ) 
     492    #SRF_lat  = lmdz.geo2point ( d_SRF_his ['lat']      [0], dim1D='cell' ) 
     493    #SRF_lon  = lmdz.geo2point ( d_SRF_his ['lon']      [0], dim1D='cell' ) 
     494     
     495    #??SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'], dim1D='cell' ) 
     496    SRF_aire =  ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'], dim1D='cell' ) 
     497     
    488498if ICO : 
    489     jpja, jpia = d_ATM_his['aire'][0].shape    
    490     file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' ) 
    491     config['Files']['file_ATM_aire'] = file_ATM_aire 
    492     echo ( f'Aire sur grille reguliere : {file_ATM_aire}' ) 
    493     d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze() 
    494     ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True ) 
    495     ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) 
    496     ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] ) 
    497     ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] ) 
    498     ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] ) 
    499     ATM_fsea = ATM_foce + ATM_fsic 
    500     ATM_flnd = ATM_fter + ATM_flic 
    501     SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] ) 
    502     #SRF_aire = ATM_aire * lmdz.geo2point (d_SRF_his ['Contfrac'] ) 
    503     #SRF_aire = ATM_aire * ATM_fter 
    504      
    505 if LMDZ : 
    506     ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True ) 
    507     ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] ) 
    508     ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) 
    509     #SRF_aire = lmdz.geo2point ( d_SRF_his['Areas'] * d_SRF_his['Contfrac'] ) 
    510     SRF_aire = ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'] ) 
    511  
    512 SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.) 
    513  
     499    if ATM_HIS == 'latlon' : 
     500        jpja, jpia = d_ATM_his['aire'][0].shape    
     501        file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' ) 
     502        config['Files']['file_ATM_aire'] = file_ATM_aire 
     503        echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' ) 
     504        d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze() 
     505        #ATM_lat  = d_ATM_his ['lat'] 
     506        #ATM_lon  = d_ATM_his ['lon'] 
     507        ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True, dim1D='cell' ) 
     508        ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0], dim1D='cell' ) 
     509        ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0], dim1D='cell' ) 
     510        ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0], dim1D='cell' ) 
     511        ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0], dim1D='cell' ) 
     512        #SRF_lat  = d_SRF_his ['lat'] 
     513        #SRF_lon  = d_SRF_his ['lon'] 
     514        SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'], dim1D='cell' ) 
     515         
     516    if ATM_HIS == 'ico' : 
     517        echo ( f'Grille icosaedre' ) 
     518        ATM_aire =  d_ATM_his ['aire']     [0][ATM_his_keysort].squeeze() 
     519        #ATM_lat  =  d_ATM_his ['lat']         [ATM_his_keysort] 
     520        #ATM_lon  =  d_ATM_his ['lon']         [ATM_his_keysort] 
     521        ATM_fter =  d_ATM_his ['fract_ter'][0][ATM_his_keysort] 
     522        ATM_foce =  d_ATM_his ['fract_oce'][0][ATM_his_keysort] 
     523        ATM_fsic =  d_ATM_his ['fract_sic'][0][ATM_his_keysort] 
     524        ATM_flic =  d_ATM_his ['fract_lic'][0][ATM_his_keysort] 
     525        #SRF_lat  =  d_SRF_his ['lat']         [SRF_his_keysort] 
     526        #SRF_lon  =  d_SRF_his ['lon']         [SRF_his_keysort] 
     527        SRF_aire =  d_SRF_his ['Areas'][SRF_his_keysort] * d_SRF_his ['Contfrac'][SRF_his_keysort] 
     528 
     529ATM_fsea      = ATM_foce + ATM_fsic 
     530ATM_flnd      = ATM_fter + ATM_flic 
     531ATM_aire_fter = ATM_aire * ATM_fter 
     532ATM_aire_flic = ATM_aire * ATM_flic 
     533ATM_aire_fsic = ATM_aire * ATM_fsic 
     534ATM_aire_foce = ATM_aire * ATM_foce 
     535ATM_aire_flnd = ATM_aire * ATM_flnd 
     536ATM_aire_fsea = ATM_aire * ATM_fsea 
     537 
     538SRF_aire = SRF_aire.where ( np.abs (SRF_aire) < 1E15, 0.) 
     539             
    514540if ICO : 
    515541    # Area on icosahedron grid 
    516     file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) 
    517542    d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False).squeeze() 
    518     d_DYN_aire = d_DYN_aire.rename ( {'cell':'cell_mesh'} ) 
    519     DYN_aire   = d_DYN_aire['aire'] 
    520  
    521     DYN_fsea = d_DYN_aire ['fract_oce'] + d_DYN_aire ['fract_sic'] 
     543 
     544    if SortIco :  
     545        # Creation d'une clef de tri pour le fichier aire 
     546        DYN_aire_keysort = np.lexsort ( (d_DYN_aire['lat'], d_DYN_aire['lon']) ) 
     547    else :  
     548        DYN_aire_keysort = np.arange ( len ( d_DYN_aire['lat'] ) ) 
     549             
     550    DYN_lat = d_DYN_aire['lat'][DYN_aire_keysort] 
     551    DYN_lon = d_DYN_aire['lon'][DYN_aire_keysort] 
     552 
     553    DYN_aire = d_DYN_aire['aire'][DYN_aire_keysort] 
     554    DYN_fsea = d_DYN_aire ['fract_oce'][DYN_aire_keysort] + d_DYN_aire['fract_sic'][DYN_aire_keysort] 
    522555    DYN_flnd = 1.0 - DYN_fsea 
    523     DYN_fter = d_ATM_beg['FTER'].rename({'points_physiques':'cell_mesh'}) 
    524     DYN_flic = d_ATM_beg['FTER'].rename({'points_physiques':'cell_mesh'}) 
     556    DYN_fter = d_ATM_beg['FTER'][ATM_beg_keysort] 
     557    DYN_flic = d_ATM_beg['FLIC'][ATM_beg_keysort] 
     558    DYN_aire_fter = DYN_aire * DYN_fter 
    525559     
    526560if LMDZ : 
     561    # Area on lon/lat grid 
    527562    DYN_aire = ATM_aire 
    528563    DYN_fsea = ATM_fsea 
    529564    DYN_flnd = ATM_flnd 
    530565    DYN_fter = d_ATM_beg['FTER'] 
    531     DYN_flic = d_ATM_beg['FTER'] 
    532  
    533      
    534 DYN_aire_fter = DYN_aire * DYN_fter 
     566    DYN_flic = d_ATM_beg['FLIC'] 
     567    DYN_aire_fter = DYN_aire * DYN_fter 
     568 
     569# Functions computing integrals and sum 
     570def ATM_stock_int (stock) : 
     571    '''Integrate (* surface) stock on atmosphere grid''' 
     572    ATM_stock_int  = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() )  
     573    return ATM_stock_int 
     574 
     575def ATM_flux_int (flux) : 
     576    '''Integrate (* time * surface) flux on atmosphere grid''' 
     577    ATM_flux_int  = wu.Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() ) 
     578    return ATM_flux_int 
     579 
     580def SRF_stock_int (stock) : 
     581    '''Integrate (* surface) stock on land grid''' 
     582    SRF_stock_int  = wu.Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) ) 
     583    return SRF_stock_int 
     584 
     585def SRF_flux_int (flux) : 
     586    '''Integrate (* time * surface) flux on land grid''' 
     587    SRF_flux_int  = wu.Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() ) 
     588    return SRF_flux_int 
     589 
     590def ONE_stock_int (stock) : 
     591    '''Sum stock ''' 
     592    ONE_stock_int  = wu.Psum ( stock.to_masked_array().ravel() ) 
     593    return ONE_stock_int 
     594 
     595def ONE_flux_int (flux) : 
     596    '''Integrate (* time) flux on area=1 grid ''' 
     597    ONE_flux_int  = wu.Psum ( (flux * dtime_per_sec ).to_masked_array().ravel() ) 
     598    return ONE_flux_int 
     599 
    535600 
    536601#if LMDZ : 
     
    538603 
    539604ATM_aire_sea     = ATM_aire * ATM_fsea 
    540 ATM_aire_sea_tot = ONE_stock_int ( ATM_aire_sea ) 
    541  
    542605ATM_aire_tot     = ONE_stock_int (ATM_aire) 
    543606ATM_aire_sea_tot = ONE_stock_int (ATM_aire*ATM_fsea) 
    544607 
    545608 
    546 echo ( 'Aire atmosphere/4pi R^2 : {:12.5f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) ) 
     609echo ( 'Area of atmosphere/(4pi R^2) : {:12.5f}'.format(ATM_aire_tot/(Ra*Ra*4*np.pi) ) ) 
    547610 
    548611if (  np.abs (ATM_aire_tot/(Ra*Ra*4*np.pi) - 1.0) > 0.01 ) : 
    549     raise Exception ('Erreur surface interpolee sur grille reguliere') 
     612    raise Exception ('Error of atmosphere surface interpolated on lon/lat grid') 
    550613 
    551614echo ( '\n====================================================================================' ) 
     
    555618#-- Compute sum weighted by gridcell area (kg/m2) then convert to Sv 
    556619 
    557 # ATM vertical grid 
     620echo ( 'ATM vertical grid' ) 
    558621ATM_Ahyb = d_ATM_his['Ahyb'].squeeze() 
    559622ATM_Bhyb = d_ATM_his['Bhyb'].squeeze() 
    560623 
    561 # Surface pressure 
    562 if ICO :  
    563     DYN_psol_beg = d_DYN_beg['ps'] 
    564     DYN_psol_end = d_DYN_end['ps'] 
     624echo ( 'Surface pressure' ) 
     625if ICO : 
     626    DYN_psol_beg = d_DYN_beg['ps'][DYN_beg_keysort] 
     627    DYN_psol_end = d_DYN_end['ps'][DYN_end_keysort] 
    565628if LMDZ :  
    566     DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)) ) 
    567     DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)) ) 
    568      
    569 # 3D Pressure at the interface layers (not scalar points) 
     629    DYN_psol_beg = lmdz.geo2point ( d_DYN_beg['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' ) 
     630    DYN_psol_end = lmdz.geo2point ( d_DYN_end['ps'].isel(rlonv=slice(0,-1)), dim1D='cell' ) 
     631     
     632echo ( '3D Pressure at the interface layers (not scalar points)' ) 
    570633DYN_pres_beg = ATM_Ahyb + ATM_Bhyb * DYN_psol_beg 
    571634DYN_pres_end = ATM_Ahyb + ATM_Bhyb * DYN_psol_end 
    572635 
    573636klevp1 = ATM_Bhyb.shape[-1] 
    574 if ICO  : cell_mesh        = DYN_psol_beg.shape[-1] 
    575 if LMDZ : points_physiques = DYN_psol_beg.shape[-1] 
     637cell        = DYN_psol_beg.shape[-1] 
    576638klev = klevp1 - 1 
    577639 
    578 # Layer thickness (pressure) 
    579 if ICO :  
    580     DYN_dpres_beg = xr.DataArray ( np.empty( (klev, cell_mesh       )), dims=('sigs', 'cell_mesh'       ), coords=(np.arange(klev), np.arange(cell_mesh)        ) ) 
    581     DYN_dpres_end = xr.DataArray ( np.empty( (klev, cell_mesh       )), dims=('sigs', 'cell_mesh'       ), coords=(np.arange(klev), np.arange(cell_mesh)        ) ) 
    582 if LMDZ :  
    583     DYN_dpres_beg = xr.DataArray ( np.empty( (klev, points_physiques)), dims=('sigs', 'points_physiques'), coords=(np.arange(klev), np.arange(points_physiques) ) ) 
    584     DYN_dpres_end = xr.DataArray ( np.empty( (klev, points_physiques)), dims=('sigs', 'points_physiques'), coords=(np.arange(klev), np.arange(points_physiques) ) ) 
    585  
     640echo ( 'Layer thickness (pressure)' ) 
     641DYN_dpres_beg = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 
     642DYN_dpres_end = xr.DataArray ( np.empty( (klev, cell )), dims = ('sigs', 'cell'), coords=(np.arange(klev), np.arange(cell) ) ) 
     643#DYN_dpres_beg = DYN_dpres_beg 
     644#DYN_dpres_end = DYN_dpres_end 
     645     
    586646for k in np.arange (klevp1-1) : 
    587647    DYN_dpres_beg[k,:] = DYN_pres_beg[k,:] - DYN_pres_beg[k+1,:] 
    588648    DYN_dpres_end[k,:] = DYN_pres_end[k,:] - DYN_pres_end[k+1,:] 
    589649 
    590 ##-- Vertical and horizontal integral, and sum of liquid, solid and vapor water phases 
     650echo ( 'Vertical and horizontal integral, and sum of liquid, solid and vapor water phases' ) 
    591651if LMDZ : 
    592652    try :  
    593         DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov']  + d_DYN_beg['H2Ol']  + d_DYN_beg['H2Oi'] ).isel(rlonv=slice(0,-1) ) ) 
    594         DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov']  + d_DYN_end['H2Ol']  + d_DYN_end['H2Oi'] ).isel(rlonv=slice(0,-1) ) ) 
     653        DYN_wat_beg = lmdz.geo3point ( (d_DYN_beg['H2Ov']  + d_DYN_beg['H2Ol']  + d_DYN_beg['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' ) 
     654        DYN_wat_end = lmdz.geo3point ( (d_DYN_end['H2Ov']  + d_DYN_end['H2Ol']  + d_DYN_end['H2Oi'] ).isel(rlonv=slice(0,-1) ), dim1D='cell' ) 
    595655    except : 
    596         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) ) ) 
    597         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) ) ) 
     656        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' ) 
     657        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' ) 
    598658if ICO : 
    599659    try : 
    600         DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s']).rename ( {'lev':'sigs'} ) 
    601         DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s']).rename ( {'lev':'sigs'} ) 
     660        DYN_wat_beg = (d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'])[..., DYN_beg_keysort] 
     661        DYN_wat_end = (d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'])[..., DYN_beg_keysort] 
     662         
    602663    except :  
    603         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'} ) 
    604         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'} ) 
    605      
    606 # Compute water content : vertical and horizontal integral 
    607 DYN_mas_wat_beg = ATM_stock_int (DYN_dpres_beg * DYN_wat_beg) / Grav 
    608 DYN_mas_wat_end = ATM_stock_int (DYN_dpres_end * DYN_wat_end) / Grav 
    609  
    610 # Variation of water content 
     664        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] 
     665        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] 
     666         
     667    DYN_wat_beg = DYN_wat_beg.rename ( {'lev':'sigs'} ) 
     668    DYN_wat_beg = DYN_wat_end.rename ( {'lev':'sigs'} ) 
     669     
     670echo ( 'Compute water content : vertical and horizontal integral' ) 
     671DYN_mas_wat_beg = ATM_stock_int ( (DYN_dpres_beg * DYN_wat_beg).sum (dim='sigs') ) / Grav 
     672DYN_mas_wat_end = ATM_stock_int ( (DYN_dpres_end * DYN_wat_end).sum (dim='sigs') ) / Grav 
     673 
     674echo ( 'Variation of water content' ) 
    611675dDYN_mas_wat = DYN_mas_wat_end - DYN_mas_wat_beg 
    612676 
     
    614678# \([a-z,A-Z,_]*\)\/ATM_aire_sea_tot\/ATM_rho\/NbYear  kg2myear(\1) 
    615679 
    616 def var2prt (var, small=False) : 
    617     if small :  return var , kg2Sv(var)*1000., kg2myear(var)*1000. 
    618     else     :  return var , kg2Sv(var)      , kg2myear(var) 
    619  
    620 def prtFlux (Desc, var, Form='F', small=False) : 
    621     if small : 
    622         if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
    623         if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year " 
    624     else : 
    625         if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  " 
    626         if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  " 
    627     echo ( (' {:>15} = ' +ff).format (Desc, *var2prt(var, small) ) ) 
    628     return None 
    629  
    630 echo ( f'\nVariation du contenu en eau atmosphere (dynamique)  -- {Title} ' ) 
     680echo ( f'\nChange of atmosphere water content (dynamics)  -- {Title} ' ) 
    631681echo ( '------------------------------------------------------------------------------------' ) 
    632682echo ( 'DYN_mas_beg = {:12.6e} kg | DYN_mas_end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) ) 
    633683prtFlux ( 'dMass (atm)  ', dDYN_mas_wat, 'e', True ) 
    634684 
    635 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'] 
    636 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'] 
    637  
    638 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'] 
    639 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'] 
     685ATM_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'] 
     686ATM_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'] 
     687 
     688ATM_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'] 
     689ATM_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'] 
    640690 
    641691ATM_qsol_beg = d_ATM_beg['QSOL'] 
    642692ATM_qsol_end = d_ATM_end['QSOL'] 
     693 
     694LIC_sno_beg      = d_ATM_beg['SNOW02']*d_ATM_beg['FLIC'] 
     695LIC_sno_end      = d_ATM_end['SNOW02']*d_ATM_end['FLIC'] 
     696 
     697LIC_runlic0_beg  = d_ATM_beg['RUNOFFLIC0'] 
     698LIC_runlic0_end  = d_ATM_end['RUNOFFLIC0'] 
    643699 
    644700ATM_qs01_beg  = d_ATM_beg['QS01'] * d_ATM_beg['FTER'] 
     
    651707ATM_qs04_end  = d_ATM_end['QS04'] * d_ATM_end['FSIC']   
    652708 
     709# if LMDZ : 
     710#     ATM_sno_beg       = lmdz.geo2point ( ATM_sno_beg    , dim1D='cell' ) 
     711#     ATM_sno_end       = lmdz.geo2point ( ATM_sno_end    , dim1D='cell' ) 
     712#     ATM_qs_beg        = lmdz.geo2point ( ATM_qs_beg     , dim1D='cell' ) 
     713#     ATM_qs_end        = lmdz.geo2point ( ATM_qs_end     , dim1D='cell' ) 
     714#     ATM_qsol_beg      = lmdz.geo2point ( ATM_qsol_beg   , dim1D='cell' ) 
     715#     ATM_qsol_end      = lmdz.geo2point ( ATM_qsol_end   , dim1D='cell' ) 
     716#     ATM_qs01_beg      = lmdz.geo2point ( ATM_qs01_beg   , dim1D='cell' ) 
     717#     ATM_qs01_end      = lmdz.geo2point ( ATM_qs01_end   , dim1D='cell' ) 
     718#     ATM_qs02_beg      = lmdz.geo_point ( ATM_qs02_beg   , dim1D='cell' ) 
     719#     ATM_qs02_end      = lmdz.geo2point ( ATM_qs02_end   , dim1D='cell' ) 
     720#     ATM_qs03_beg      = lmdz.geo2point ( ATM_qs03_beg   , dim1D='cell' ) 
     721#     ATM_qs03_end      = lmdz.geo2point ( ATM_qs03_end   , dim1D='cell' ) 
     722#     ATM_qs04_beg      = lmdz.geo2point ( ATM_qs04_beg   , dim1D='cell' ) 
     723#     ATM_qs04_end      = lmdz.geo2point ( ATM_qs04_end   , dim1D='cell' ) 
     724#     LIC_sno_beg       = lmdz.geo2point ( LIC_sno_beg    , dim1D='cell' ) 
     725#     LIC_sno_end       = lmdz.geo2point ( LIC_sno_end    , dim1D='cell' ) 
     726#     LIC_runlic0_beg   = lmdz.geo2point ( LIC_runlic0_beg, dim1D='cell' ) 
     727#     LIC_runlic0_end   = lmdz.geo2point ( LIC_runlic0_end, dim1D='cell' ) 
    653728if ICO : 
    654    ATM_sno_beg   = ATM_sno_beg .rename ( {'points_physiques':'cell_mesh'} ) 
    655    ATM_sno_end   = ATM_sno_end .rename ( {'points_physiques':'cell_mesh'} ) 
    656    ATM_qs_beg    = ATM_qs_beg  .rename ( {'points_physiques':'cell_mesh'} ) 
    657    ATM_qs_end    = ATM_qs_end  .rename ( {'points_physiques':'cell_mesh'} ) 
    658    ATM_qsol_beg  = ATM_qsol_beg.rename ( {'points_physiques':'cell_mesh'} ) 
    659    ATM_qsol_end  = ATM_qsol_end.rename ( {'points_physiques':'cell_mesh'} ) 
    660    ATM_qs01_beg  = ATM_qs01_beg.rename ( {'points_physiques':'cell_mesh'} ) 
    661    ATM_qs01_end  = ATM_qs01_end.rename ( {'points_physiques':'cell_mesh'} ) 
    662    ATM_qs02_beg  = ATM_qs02_beg.rename ( {'points_physiques':'cell_mesh'} ) 
    663    ATM_qs02_end  = ATM_qs02_end.rename ( {'points_physiques':'cell_mesh'} ) 
    664    ATM_qs03_beg  = ATM_qs03_beg.rename ( {'points_physiques':'cell_mesh'} ) 
    665    ATM_qs03_end  = ATM_qs03_end.rename ( {'points_physiques':'cell_mesh'} ) 
    666    ATM_qs04_beg  = ATM_qs04_beg.rename ( {'points_physiques':'cell_mesh'} ) 
    667    ATM_qs04_end  = ATM_qs04_end.rename ( {'points_physiques':'cell_mesh'} )  
    668  
    669 ATM_mas_sno_beg   = ATM_stock_int ( ATM_sno_beg  ) 
    670 ATM_mas_sno_end   = ATM_stock_int ( ATM_sno_end  ) 
    671 ATM_mas_qs_beg    = ATM_stock_int ( ATM_qs_beg   ) 
    672 ATM_mas_qs_end    = ATM_stock_int ( ATM_qs_end   ) 
    673 ATM_mas_qsol_beg  = ATM_stock_int ( ATM_qsol_beg ) 
    674 ATM_mas_qsol_end  = ATM_stock_int ( ATM_qsol_end ) 
    675 ATM_mas_qs01_beg  = ATM_stock_int ( ATM_qs01_beg ) 
    676 ATM_mas_qs01_end  = ATM_stock_int ( ATM_qs01_end ) 
    677 ATM_mas_qs02_beg  = ATM_stock_int ( ATM_qs02_beg ) 
    678 ATM_mas_qs02_end  = ATM_stock_int ( ATM_qs02_end ) 
    679 ATM_mas_qs03_beg  = ATM_stock_int ( ATM_qs03_beg ) 
    680 ATM_mas_qs03_end  = ATM_stock_int ( ATM_qs03_end ) 
    681 ATM_mas_qs04_beg  = ATM_stock_int ( ATM_qs04_beg ) 
    682 ATM_mas_qs04_end  = ATM_stock_int ( ATM_qs04_end ) 
     729     ATM_sno_beg       = ATM_sno_beg    [ATM_beg_keysort] 
     730     ATM_sno_end       = ATM_sno_end    [ATM_end_keysort] 
     731     ATM_qs_beg        = ATM_qs_beg     [ATM_beg_keysort] 
     732     ATM_qs_end        = ATM_qs_end     [ATM_end_keysort] 
     733     ATM_qsol_beg      = ATM_qsol_beg   [ATM_beg_keysort] 
     734     ATM_qsol_end      = ATM_qsol_end   [ATM_end_keysort] 
     735     ATM_qs01_beg      = ATM_qs01_beg   [ATM_beg_keysort] 
     736     ATM_qs01_end      = ATM_qs01_end   [ATM_end_keysort] 
     737     ATM_qs02_beg      = ATM_qs02_beg   [ATM_beg_keysort] 
     738     ATM_qs02_end      = ATM_qs02_end   [ATM_end_keysort] 
     739     ATM_qs03_beg      = ATM_qs03_beg   [ATM_beg_keysort] 
     740     ATM_qs03_end      = ATM_qs03_end   [ATM_end_keysort] 
     741     ATM_qs04_beg      = ATM_qs04_beg   [ATM_beg_keysort] 
     742     ATM_qs04_end      = ATM_qs04_end   [ATM_end_keysort] 
     743     LIC_sno_beg       = LIC_sno_beg    [ATM_beg_keysort] 
     744     LIC_sno_end       = LIC_sno_end    [ATM_end_keysort] 
     745     LIC_runlic0_beg   = LIC_runlic0_beg[ATM_beg_keysort] 
     746     LIC_runlic0_end   = LIC_runlic0_end[ATM_end_keysort] 
     747 
     748 
     749    
     750LIC_qs_beg = ATM_qs02_beg 
     751LIC_qs_end = ATM_qs02_end 
     752 
     753ATM_mas_sno_beg     = ATM_stock_int ( ATM_sno_beg  ) 
     754ATM_mas_sno_end     = ATM_stock_int ( ATM_sno_end  ) 
     755 
     756ATM_mas_qs_beg      = ATM_stock_int ( ATM_qs_beg   ) 
     757ATM_mas_qs_end      = ATM_stock_int ( ATM_qs_end   ) 
     758ATM_mas_qsol_beg    = ATM_stock_int ( ATM_qsol_beg ) 
     759ATM_mas_qsol_end    = ATM_stock_int ( ATM_qsol_end ) 
     760ATM_mas_qs01_beg    = ATM_stock_int ( ATM_qs01_beg ) 
     761ATM_mas_qs01_end    = ATM_stock_int ( ATM_qs01_end ) 
     762ATM_mas_qs02_beg    = ATM_stock_int ( ATM_qs02_beg ) 
     763ATM_mas_qs02_end    = ATM_stock_int ( ATM_qs02_end ) 
     764ATM_mas_qs03_beg    = ATM_stock_int ( ATM_qs03_beg ) 
     765ATM_mas_qs03_end    = ATM_stock_int ( ATM_qs03_end ) 
     766ATM_mas_qs04_beg    = ATM_stock_int ( ATM_qs04_beg ) 
     767ATM_mas_qs04_end    = ATM_stock_int ( ATM_qs04_end ) 
     768 
     769LIC_mas_sno_beg     = ATM_stock_int ( LIC_sno_beg     ) 
     770LIC_mas_sno_end     = ATM_stock_int ( LIC_sno_end     ) 
     771LIC_mas_runlic0_beg = ATM_stock_int ( LIC_runlic0_beg ) 
     772LIC_mas_runlic0_end = ATM_stock_int ( LIC_runlic0_end ) 
     773 
     774LIC_mas_qs_beg  = ATM_mas_qs02_beg 
     775LIC_mas_qs_end  = ATM_mas_qs02_end 
     776LIC_mas_wat_beg = LIC_mas_qs_beg + LIC_mas_sno_beg 
     777LIC_mas_wat_end = LIC_mas_qs_end + LIC_mas_sno_end 
    683778 
    684779dATM_mas_sno  = ATM_mas_sno_end  - ATM_mas_sno_beg 
     
    691786dATM_mas_qs04 = ATM_mas_qs04_end - ATM_mas_qs04_beg 
    692787 
    693 dATM_mas_sno_2 = ATM_stock_int ( ATM_sno_end - ATM_sno_beg ) 
    694  
    695 echo ( f'\nVariation du contenu en neige atmosphere (calottes)  -- {Title} ' ) 
     788dLIC_mas_qs      = LIC_mas_qs_end      - LIC_mas_qs_beg 
     789dLIC_mas_sno     = LIC_mas_sno_end     - LIC_mas_sno_beg 
     790dLIC_mas_runlic0 = LIC_mas_runlic0_end - LIC_mas_runlic0_beg 
     791dLIC_mas_wat     = dLIC_mas_qs + dLIC_mas_sno 
     792 
     793echo ( f'\nChange of atmosphere snow content (Land ice) -- {Title} ' ) 
    696794echo ( '------------------------------------------------------------------------------------' ) 
    697795echo ( 'ATM_mas_sno_beg  = {:12.6e} kg | ATM_mas_sno_end  = {:12.6e} kg'.format (ATM_mas_sno_beg, ATM_mas_sno_end) ) 
    698796prtFlux ( 'dMass (neige atm) ', dATM_mas_sno  , 'e', True  ) 
    699 prtFlux ( 'dMass (neige atm) ', dATM_mas_sno_2, 'e', True  ) 
    700  
    701 echo ( f'\nVariation du contenu humidite du sol  -- {Title} ' ) 
     797 
     798echo ( f'\nChange of soil humidity content -- {Title} ' ) 
    702799echo ( '------------------------------------------------------------------------------------' ) 
    703800echo ( 'ATM_mas_qs_beg  = {:12.6e} kg | ATM_mas_qs_end  = {:12.6e} kg'.format (ATM_mas_qs_beg, ATM_mas_qs_end) ) 
    704801prtFlux ( 'dMass (neige atm) ', dATM_mas_qs, 'e', True ) 
    705802 
    706 echo ( f'\nVariation du contenu en eau+neige atmosphere -- {Title}  ' ) 
     803echo ( f'\nChange of atmosphere water+snow content -- {Title}  ' ) 
    707804echo ( '------------------------------------------------------------------------------------' ) 
    708805prtFlux ( 'dMass (eau + neige atm) ', dDYN_mas_wat + dATM_mas_sno , 'e', True) 
     
    715812    RUN_mas_wat_slow_beg   = ONE_stock_int ( d_RUN_beg ['slow_reservoir']   ) 
    716813    RUN_mas_wat_stream_beg = ONE_stock_int ( d_RUN_beg ['stream_reservoir'] ) 
    717     RUN_mas_wat_flood_beg  = 0.0 
    718     RUN_mas_wat_lake_beg   = 0.0 
    719     RUN_mas_wat_pond_beg   = 0.0 
     814     
     815    RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  ) 
     816    RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   ) 
     817    RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   ) 
    720818     
    721819    RUN_mas_wat_fast_end   = ONE_stock_int ( d_RUN_end ['fast_reservoir']   ) 
    722820    RUN_mas_wat_slow_end   = ONE_stock_int ( d_RUN_end ['slow_reservoir']   ) 
    723821    RUN_mas_wat_stream_end = ONE_stock_int ( d_RUN_end ['stream_reservoir'] ) 
    724     RUN_mas_wat_flood_end  = 0.0 
    725     RUN_mas_wat_lake_end   = 0.0 
    726     RUN_mas_wat_pond_end   = 0.0 
    727  
    728 if Routing == 'SECHIBA' : 
    729     RUN_mas_wat_fast_beg   = ONE_stock_int ( d_SRF_beg ['fastres']   ) 
    730     RUN_mas_wat_slow_beg   = ONE_stock_int ( d_SRF_beg ['slowres']   ) 
    731     RUN_mas_wat_stream_beg = ONE_stock_int ( d_SRF_beg ['streamres'] ) 
    732     RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  ) 
    733     RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   ) 
    734     RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   ) 
    735  
    736      
    737     RUN_mas_wat_fast_end   = ONE_stock_int ( d_SRF_end ['fastres']   ) 
    738     RUN_mas_wat_slow_end   = ONE_stock_int ( d_SRF_end ['slowres']   ) 
    739     RUN_mas_wat_stream_end = ONE_stock_int ( d_SRF_end ['streamres'] ) 
     822     
    740823    RUN_mas_wat_flood_end  = ONE_stock_int ( d_SRF_end ['floodres']  ) 
    741824    RUN_mas_wat_lake_end   = ONE_stock_int ( d_SRF_end ['lakeres']   ) 
    742825    RUN_mas_wat_pond_end   = ONE_stock_int ( d_SRF_end ['pondres']   ) 
     826 
     827if Routing == 'SECHIBA' : 
     828        RUN_mas_wat_fast_beg   = ONE_stock_int ( d_SRF_beg ['fastres']   ) 
     829        RUN_mas_wat_slow_beg   = ONE_stock_int ( d_SRF_beg ['slowres']   ) 
     830        RUN_mas_wat_stream_beg = ONE_stock_int ( d_SRF_beg ['streamres'] ) 
     831        RUN_mas_wat_flood_beg  = ONE_stock_int ( d_SRF_beg ['floodres']  ) 
     832        RUN_mas_wat_lake_beg   = ONE_stock_int ( d_SRF_beg ['lakeres']   ) 
     833        RUN_mas_wat_pond_beg   = ONE_stock_int ( d_SRF_beg ['pondres']   ) 
     834         
     835        RUN_mas_wat_fast_end   = ONE_stock_int ( d_SRF_end ['fastres']   ) 
     836        RUN_mas_wat_slow_end   = ONE_stock_int ( d_SRF_end ['slowres']   ) 
     837        RUN_mas_wat_stream_end = ONE_stock_int ( d_SRF_end ['streamres'] ) 
     838        RUN_mas_wat_flood_end  = ONE_stock_int ( d_SRF_end ['floodres']  ) 
     839        RUN_mas_wat_lake_end   = ONE_stock_int ( d_SRF_end ['lakeres']   ) 
     840        RUN_mas_wat_pond_end   = ONE_stock_int ( d_SRF_end ['pondres']   ) 
    743841 
    744842RUN_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 
     
    754852dRUN_mas_wat        = RUN_mas_wat_end        - RUN_mas_wat_beg 
    755853 
    756 echo ( f'\nLes differents reservoirs  -- {Title} ') 
    757 echo ( '------------------------------------------------------------------------------------' ) 
    758 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   ) ) 
    759 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   ) ) 
    760 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 ) ) 
    761 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  ) ) 
    762 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   ) ) 
    763 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   ) ) 
     854echo ( f'\nRunoff reservoirs -- {Title} ') 
     855echo ( f'------------------------------------------------------------------------------------' ) 
     856echo ( 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 ' ) 
     857echo ( 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 ' ) 
     858echo ( 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 ' ) 
     859echo ( 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 ' ) 
     860echo ( 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 ' ) 
     861echo ( 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 ' ) 
     862echo ( f'RUN_mas_wat_beg        = {RUN_mas_wat_beg       :12.6e} kg | RUN_mas_wat_end        = {RUN_mas_wat_end       :12.6e} kg ' ) 
    764863 
    765864echo ( '------------------------------------------------------------------------------------' ) 
     
    776875echo ( '------------------------------------------------------------------------------------' ) 
    777876echo ( 'RUN_mas_wat_beg = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_end, RUN_mas_wat_end) ) 
    778 prtFlux ( 'dMass (routing) ', dRUN_mas_wat       ) 
     877prtFlux ( 'dMass (routing) ', dRUN_mas_wat , 'e', True   ) 
    779878 
    780879echo ( '\n====================================================================================' ) 
    781880print (f'Reading SRF restart') 
    782 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.) 
    783 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.) 
    784 SRF_snow_beg        = d_SRF_beg['snow_beg']        ; SRF_snow_beg        = SRF_snow_beg       .where (SRF_snow_beg       < 1E15, 0.) 
    785 SRF_lakeres_beg     = d_SRF_beg['lakeres']         ; SRF_lakeres_beg     = SRF_lakeres_beg    .where (SRF_lakeres_beg    < 1E15, 0.) 
    786  
    787 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.) 
    788 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.) 
    789 SRF_snow_end        = d_SRF_end['snow_beg']        ; SRF_snow_end        = SRF_snow_end       .where (SRF_snow_end       < 1E15, 0.) 
    790 SRF_lakeres_end     = d_SRF_end['lakeres']         ; SRF_lakeres_end     = SRF_lakeres_end    .where (SRF_lakeres_end    < 1E15, 0.) 
     881SRF_tot_watveg_beg  = d_SRF_beg['tot_watveg_beg']  ; SRF_tot_watveg_beg  = SRF_tot_watveg_beg .where (SRF_tot_watveg_beg  < 1E15, 0.) 
     882SRF_tot_watsoil_beg = d_SRF_beg['tot_watsoil_beg'] ; SRF_tot_watsoil_beg = SRF_tot_watsoil_beg.where (SRF_tot_watsoil_beg < 1E15, 0.) 
     883SRF_snow_beg        = d_SRF_beg['snow_beg']        ; SRF_snow_beg        = SRF_snow_beg       .where (SRF_snow_beg        < 1E15, 0.) 
     884SRF_lakeres_beg     = d_SRF_beg['lakeres']         ; SRF_lakeres_beg     = SRF_lakeres_beg    .where (SRF_lakeres_beg     < 1E15, 0.) 
     885 
     886SRF_tot_watveg_end  = d_SRF_end['tot_watveg_beg']  ; SRF_tot_watveg_end  = SRF_tot_watveg_end .where (SRF_tot_watveg_end  < 1E15, 0.) 
     887SRF_tot_watsoil_end = d_SRF_end['tot_watsoil_beg'] ; SRF_tot_watsoil_end = SRF_tot_watsoil_end.where (SRF_tot_watsoil_end < 1E15, 0.) 
     888SRF_snow_end        = d_SRF_end['snow_beg']        ; SRF_snow_end        = SRF_snow_end       .where (SRF_snow_end        < 1E15, 0.) 
     889SRF_lakeres_end     = d_SRF_end['lakeres']         ; SRF_lakeres_end     = SRF_lakeres_end    .where (SRF_lakeres_end     < 1E15, 0.) 
    791890 
    792891if LMDZ : 
    793     SRF_tot_watveg_beg  = lmdz.geo2point (SRF_tot_watveg_beg ) 
    794     SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg) 
    795     SRF_snow_beg        = lmdz.geo2point (SRF_snow_beg       ) 
    796     SRF_lakeres_beg     = lmdz.geo2point (SRF_lakeres_beg    ) 
    797     SRF_tot_watveg_end  = lmdz.geo2point (SRF_tot_watveg_end ) 
    798     SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end) 
    799     SRF_snow_end        = lmdz.geo2point (SRF_snow_end       ) 
    800     SRF_lakeres_end     = lmdz.geo2point (SRF_lakeres_end    ) 
     892    SRF_tot_watveg_beg  = lmdz.geo2point (SRF_tot_watveg_beg , dim1D='cell') 
     893    SRF_tot_watsoil_beg = lmdz.geo2point (SRF_tot_watsoil_beg, dim1D='cell') 
     894    SRF_snow_beg        = lmdz.geo2point (SRF_snow_beg       , dim1D='cell') 
     895    SRF_lakeres_beg     = lmdz.geo2point (SRF_lakeres_beg    , dim1D='cell') 
     896    SRF_tot_watveg_end  = lmdz.geo2point (SRF_tot_watveg_end , dim1D='cell') 
     897    SRF_tot_watsoil_end = lmdz.geo2point (SRF_tot_watsoil_end, dim1D='cell') 
     898    SRF_snow_end        = lmdz.geo2point (SRF_snow_end       , dim1D='cell') 
     899    SRF_lakeres_end     = lmdz.geo2point (SRF_lakeres_end    , dim1D='cell') 
    801900   
    802901if ICO : 
    803     SRF_tot_watveg_beg  = SRF_tot_watveg_beg .rename ( {'y':'cell_mesh'} ) 
    804     SRF_tot_watsoil_beg = SRF_tot_watsoil_beg.rename ( {'y':'cell_mesh'} ) 
    805     SRF_snow_beg        = SRF_snow_beg       .rename ( {'y':'cell_mesh'} ) 
    806     SRF_lakeres_beg     = SRF_lakeres_beg    .rename ( {'y':'cell_mesh'} ) 
    807     SRF_tot_watveg_end  = SRF_tot_watveg_end .rename ( {'y':'cell_mesh'} ) 
    808     SRF_tot_watsoil_end = SRF_tot_watsoil_end.rename ( {'y':'cell_mesh'} ) 
    809     SRF_snow_end        = SRF_snow_end       .rename ( {'y':'cell_mesh'} ) 
    810     SRF_lakeres_end     = SRF_lakeres_end    .rename ( {'y':'cell_mesh'} ) 
     902    SRF_tot_watveg_beg  = SRF_tot_watveg_beg  [SRF_beg_keysort] 
     903    SRF_tot_watsoil_beg = SRF_tot_watsoil_beg [SRF_beg_keysort] 
     904    SRF_snow_beg        = SRF_snow_beg        [SRF_beg_keysort] 
     905    SRF_lakeres_beg     = SRF_lakeres_beg     [SRF_beg_keysort] 
     906    SRF_tot_watveg_end  = SRF_tot_watveg_end  [SRF_end_keysort] 
     907    SRF_tot_watsoil_end = SRF_tot_watsoil_end [SRF_end_keysort] 
     908    SRF_snow_end        = SRF_snow_end        [SRF_end_keysort] 
     909    SRF_lakeres_end     = SRF_lakeres_end     [SRF_end_keysort] 
    811910 
    812911# Stock dSoilHum dInterce dSWE dStream dFastR dSlowR dLake dPond dFlood 
     
    844943 
    845944 
    846  
    847945echo ( '------------------------------------------------------------------------------------' ) 
    848 echo ( f'\nLes differents reservoirs  -- {Title} ') 
    849 echo ( 'SRF_mas_watveg_beg   = {:12.6e} kg | SRF_mas_watveg_end   = {:12.6e} kg '.format (SRF_mas_watveg_beg  , SRF_mas_watveg_end   ) ) 
    850 echo ( 'SRF_mas_watsoil_beg  = {:12.6e} kg | SRF_mas_watsoil_end  = {:12.6e} kg '.format (SRF_mas_watsoil_beg , SRF_mas_watsoil_end  ) ) 
    851 echo ( 'SRF_mas_snow_beg     = {:12.6e} kg | SRF_mas_snow_end     = {:12.6e} kg '.format (SRF_mas_snow_beg    , SRF_mas_snow_end     ) ) 
    852 echo ( 'SRF_mas_lake_beg     = {:12.6e} kg | SRF_mas_lake_end     = {:12.6e} kg '.format (SRF_mas_lake_beg    , SRF_mas_lake_end     ) ) 
     946echo ( f'\nSurface reservoirs  -- {Title} ') 
     947echo ( f'SRF_mas_watveg_beg   = {SRF_mas_watveg_beg :12.6e} kg | SRF_mas_watveg_end   = {SRF_mas_watveg_end :12.6e} kg ' ) 
     948echo ( f'SRF_mas_watsoil_beg  = {SRF_mas_watsoil_beg:12.6e} kg | SRF_mas_watsoil_end  = {SRF_mas_watsoil_end:12.6e} kg ' ) 
     949echo ( f'SRF_mas_snow_beg     = {SRF_mas_snow_beg   :12.6e} kg | SRF_mas_snow_end     = {SRF_mas_snow_end   :12.6e} kg ' ) 
     950echo ( f'SRF_mas_lake_beg     = {SRF_mas_lake_beg   :12.6e} kg | SRF_mas_lake_end     = {SRF_mas_lake_end   :12.6e} kg ' ) 
    853951 
    854952prtFlux ('dMass (watveg) ', dSRF_mas_watveg , 'e' , True) 
     
    863961echo ( '------------------------------------------------------------------------------------' ) 
    864962echo ( f'Water content in surface  -- {Title} ' ) 
    865 echo ( 'SRF_mas_wat_beg   = {:12.6e} kg | SRF_mas_wat_end  = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) ) 
     963echo ( f'SRF_mas_wat_beg   = {SRF_mas_wat_beg:12.6e} kg | SRF_mas_wat_end  = {SRF_mas_wat_end:12.6e} kg ') 
    866964prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', True ) 
    867965 
     
    876974echo ( f'-- ATM Fluxes  -- {Title} ' ) 
    877975 
    878 ATM_wbilo_oce   = lmdz.geo2point ( d_ATM_his ['wbilo_oce']   ) 
    879 ATM_wbilo_sic   = lmdz.geo2point ( d_ATM_his ['wbilo_sic']   ) 
    880 ATM_wbilo_ter   = lmdz.geo2point ( d_ATM_his ['wbilo_ter']   ) 
    881 ATM_wbilo_lic   = lmdz.geo2point ( d_ATM_his ['wbilo_lic']   ) 
    882 ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic']   ) 
    883 ATM_fqcalving   = lmdz.geo2point ( d_ATM_his ['fqcalving']   ) 
    884 ATM_fqfonte     = lmdz.geo2point ( d_ATM_his ['fqfonte']     ) 
    885 ATM_precip      = lmdz.geo2point ( d_ATM_his ['precip']      ) 
    886 ATM_snowf       = lmdz.geo2point ( d_ATM_his ['snow']        ) 
    887 ATM_evap        = lmdz.geo2point ( d_ATM_his ['evap']        ) 
     976print ( 'Step 1', end='' ) 
     977if ATM_HIS == 'latlon' : 
     978    ATM_wbilo_oce   = lmdz.geo2point ( d_ATM_his ['wbilo_oce'], dim1D='cell' ) 
     979    ATM_wbilo_sic   = lmdz.geo2point ( d_ATM_his ['wbilo_sic'], dim1D='cell' ) 
     980    ATM_wbilo_ter   = lmdz.geo2point ( d_ATM_his ['wbilo_ter'], dim1D='cell' ) 
     981    ATM_wbilo_lic   = lmdz.geo2point ( d_ATM_his ['wbilo_lic'], dim1D='cell' ) 
     982    ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell' ) 
     983    ATM_fqcalving   = lmdz.geo2point ( d_ATM_his ['fqcalving'], dim1D='cell' ) 
     984    ATM_fqfonte     = lmdz.geo2point ( d_ATM_his ['fqfonte']  , dim1D='cell' ) 
     985    ATM_precip      = lmdz.geo2point ( d_ATM_his ['precip']   , dim1D='cell' ) 
     986    ATM_snowf       = lmdz.geo2point ( d_ATM_his ['snow']     , dim1D='cell' ) 
     987    ATM_evap        = lmdz.geo2point ( d_ATM_his ['evap']     , dim1D='cell' ) 
     988    ATM_wevap_ter   = lmdz.geo2point ( d_ATM_his ['wevap_ter'], dim1D='cell' ) 
     989    ATM_wevap_oce   = lmdz.geo2point ( d_ATM_his ['wevap_oce'], dim1D='cell' ) 
     990    ATM_wevap_lic   = lmdz.geo2point ( d_ATM_his ['wevap_lic'], dim1D='cell' ) 
     991    ATM_wevap_sic   = lmdz.geo2point ( d_ATM_his ['wevap_sic'], dim1D='cell' ) 
     992    ATM_runofflic   = lmdz.geo2point ( d_ATM_his ['runofflic'], dim1D='cell' ) 
     993     
     994print ( ' - Step 2', end='' ) 
     995if ATM_HIS == 'ico' : 
     996    ATM_wbilo_oce   = d_ATM_his ['wbilo_oce'][..., ATM_his_keysort] 
     997    ATM_wbilo_sic   = d_ATM_his ['wbilo_sic'][..., ATM_his_keysort] 
     998    ATM_wbilo_ter   = d_ATM_his ['wbilo_ter'][..., ATM_his_keysort] 
     999    ATM_wbilo_lic   = d_ATM_his ['wbilo_lic'][..., ATM_his_keysort] 
     1000    ATM_runofflic   = d_ATM_his ['runofflic'][..., ATM_his_keysort] 
     1001    ATM_fqcalving   = d_ATM_his ['fqcalving'][..., ATM_his_keysort] 
     1002    ATM_fqfonte     = d_ATM_his ['fqfonte']  [..., ATM_his_keysort] 
     1003    ATM_precip      = d_ATM_his ['precip']   [..., ATM_his_keysort] 
     1004    ATM_snowf       = d_ATM_his ['snow']     [..., ATM_his_keysort] 
     1005    ATM_evap        = d_ATM_his ['evap']     [..., ATM_his_keysort] 
     1006    ATM_wevap_ter   = d_ATM_his ['wevap_ter'][..., ATM_his_keysort] 
     1007    ATM_wevap_oce   = d_ATM_his ['wevap_oce'][..., ATM_his_keysort] 
     1008    ATM_wevap_lic   = d_ATM_his ['wevap_lic'][..., ATM_his_keysort] 
     1009    ATM_wevap_sic   = d_ATM_his ['wevap_sic'][..., ATM_his_keysort] 
     1010    ATM_runofflic   = d_ATM_his ['runofflic'][..., ATM_his_keysort] 
     1011 
     1012print ( ' - Step 3', end='' ) 
    8881013ATM_wbilo       = ATM_wbilo_oce + ATM_wbilo_sic + ATM_wbilo_ter + ATM_wbilo_lic 
    8891014ATM_emp         = ATM_evap - ATM_precip 
    890  
    891 RUN_coastalflow = lmdz.geo2point ( d_RUN_his ['coastalflow'] )  
    892 RUN_riverflow   = lmdz.geo2point ( d_RUN_his ['riverflow']   ) 
    893 RUN_runoff      = lmdz.geo2point ( d_RUN_his ['runoff']      ) 
    894 RUN_drainage    = lmdz.geo2point ( d_RUN_his ['drainage']    ) 
    895 RUN_riversret   = lmdz.geo2point ( d_RUN_his ['riversret']   ) 
    896  
    897 RUN_coastalflow_cpl = lmdz.geo2point ( d_RUN_his ['coastalflow_cpl'] )  
    898 RUN_riverflow_cpl   = lmdz.geo2point ( d_RUN_his ['riverflow_cpl']   ) 
    899  
    900 SRF_rain     = lmdz.geo2point ( d_SRF_his ['rain']  ) 
    901 SRF_evap     = lmdz.geo2point ( d_SRF_his ['evap']  ) 
    902 SRF_snowf    = lmdz.geo2point ( d_SRF_his ['snowf'] ) 
    903 SRF_subli    = lmdz.geo2point ( d_SRF_his ['subli'] ) 
    904 SRF_transpir = lmdz.geo2point ( np.sum(d_SRF_his ['transpir'], axis=1) ) ; SRF_transpir.attrs['units'] = d_SRF_his ['transpir'].attrs['units'] 
     1015ATM_wbilo_sea   = ATM_wbilo_oce + ATM_wbilo_sic 
     1016ATM_wevap_sea   = ATM_wevap_sic + ATM_wevap_oce 
     1017 
     1018ATM_wemp_ter = ATM_wevap_ter - ATM_precip * ATM_fter 
     1019ATM_wemp_oce = ATM_wevap_oce - ATM_precip * ATM_foce 
     1020ATM_wemp_sic = ATM_wevap_sic - ATM_precip * ATM_fsic 
     1021ATM_wemp_lic = ATM_wevap_lic - ATM_precip * ATM_flic 
     1022ATM_wemp_sea = ATM_wevap_sic + ATM_wevap_oce - ATM_precip * ATM_fsea 
     1023 
     1024print ( ' - Step 4', end='' ) 
     1025if RUN_HIS == 'latlon' :  
     1026    RUN_coastalflow = lmdz.geo2point ( d_RUN_his ['coastalflow'], dim1D='cell' )  
     1027    RUN_riverflow   = lmdz.geo2point ( d_RUN_his ['riverflow']  , dim1D='cell' ) 
     1028    RUN_runoff      = lmdz.geo2point ( d_RUN_his ['runoff']     , dim1D='cell' ) 
     1029    RUN_drainage    = lmdz.geo2point ( d_RUN_his ['drainage']   , dim1D='cell' ) 
     1030    RUN_riversret   = lmdz.geo2point ( d_RUN_his ['riversret']  , dim1D='cell' ) 
     1031     
     1032    RUN_coastalflow_cpl = lmdz.geo2point ( d_RUN_his ['coastalflow_cpl'], dim1D='cell' )  
     1033    RUN_riverflow_cpl   = lmdz.geo2point ( d_RUN_his ['riverflow_cpl']  , dim1D='cell' ) 
     1034 
     1035print ( ' - Step 5', end='' ) 
     1036if RUN_HIS == 'ico' : 
     1037    RUN_coastalflow =  d_RUN_his ['coastalflow'][..., RUN_his_keysort] 
     1038    RUN_riverflow   =  d_RUN_his ['riverflow']  [..., RUN_his_keysort] 
     1039    RUN_runoff      =  d_RUN_his ['runoff']     [..., RUN_his_keysort] 
     1040    RUN_drainage    =  d_RUN_his ['drainage']   [..., RUN_his_keysort] 
     1041    RUN_riversret   =  d_RUN_his ['riversret']  [..., RUN_his_keysort] 
     1042     
     1043    RUN_coastalflow_cpl = d_RUN_his ['coastalflow_cpl'][..., RUN_his_keysort] 
     1044    RUN_riverflow_cpl   = d_RUN_his ['riverflow_cpl']  [..., RUN_his_keysort] 
     1045 
     1046print ( ' - Step 6', end='' ) 
     1047if SRF_HIS == 'latlon' : 
     1048    SRF_rain     = lmdz.geo2point ( d_SRF_his ['rain']  , dim1D='cell') 
     1049    SRF_evap     = lmdz.geo2point ( d_SRF_his ['evap']  , dim1D='cell') 
     1050    SRF_snowf    = lmdz.geo2point ( d_SRF_his ['snowf'] , dim1D='cell') 
     1051    SRF_subli    = lmdz.geo2point ( d_SRF_his ['subli'] , dim1D='cell') 
     1052    SRF_transpir = lmdz.geo2point ( np.sum (d_SRF_his ['transpir'], axis=1), dim1D='cell' ) 
     1053 
     1054print ( '- Step 7', end='' ) 
     1055if SRF_HIS == 'ico' : 
     1056    SRF_rain     = d_SRF_his ['rain'] [..., SRF_his_keysort] 
     1057    SRF_evap     = d_SRF_his ['evap'] [..., SRF_his_keysort] 
     1058    SRF_snowf    = d_SRF_his ['snowf'][..., SRF_his_keysort] 
     1059    SRF_subli    = d_SRF_his ['subli'][..., SRF_his_keysort] 
     1060    SRF_transpir = np.sum (d_SRF_his ['transpir'], axis=1)[..., SRF_his_keysort] 
     1061 
     1062print ( '- Step 8', end='' ) 
     1063SRF_transpir.attrs['units'] = d_SRF_his ['transpir'].attrs['units'] 
    9051064SRF_emp      = SRF_evap - SRF_rain - SRF_snowf ; SRF_emp.attrs['units'] = SRF_rain.attrs['units'] 
    906  
     1065     
    9071066## Correcting units of SECHIBA variables 
    9081067def mmd2SI ( Var ) : 
    9091068    '''Change unit from mm/d or m^3/s to kg/s if needed''' 
    9101069    if 'units' in VarT.attrs :  
    911         if VarT.attrs['units'] in ['m^3/s', 'm3/s', 'm3.s-3'] : 
     1070        if VarT.attrs['units'] in ['m^3/s', 'm3/s', 'm3.s-1',] : 
    9121071            VarT.values = VarT.values  * ATM_rho                 ;  VarT.attrs['units'] = 'kg/s' 
    9131072        if VarT.attrs['units'] == 'mm/d' : 
    9141073            VarT.values = VarT.values  * ATM_rho * (1e-3/86400.) ;  VarT.attrs['units'] = 'kg/s' 
    915  
     1074        if VarT.attrs['units'] in ['m^3', 'm3', ] : 
     1075            VarT.values = VarT.values  * ATM_rho                 ;  VarT.attrs['units'] = 'kg' 
     1076             
    9161077for var in [ 'runoff', 'drainage', 'riversret', 'coastalflow', 'riverflow', 'coastalflow_cpl', 'riverflow_cpl' ] : 
    9171078    VarT = locals()['RUN_' + var] 
     
    9221083    mmd2SI (VarT) 
    9231084 
    924  
     1085print ( '- Step 9', end='' ) 
    9251086RUN_input  = RUN_runoff      + RUN_drainage 
    9261087RUN_output = RUN_coastalflow + RUN_riverflow 
    9271088 
    928 ATM_wbilo_sea = ATM_wbilo_oce + ATM_wbilo_sic 
    929  
    930 ATM_flx_oce         = ATM_flux_int ( ATM_wbilo_oce  ) 
    931 ATM_flx_sic         = ATM_flux_int ( ATM_wbilo_sic  ) 
    932 ATM_flx_sea         = ATM_flux_int ( ATM_wbilo_sea  ) 
    933 ATM_flx_ter         = ATM_flux_int ( ATM_wbilo_ter  ) 
    934 ATM_flx_lic         = ATM_flux_int ( ATM_wbilo_lic  ) 
     1089print ( '- Step 10', end='' ) 
     1090ATM_flx_wbilo       = ATM_flux_int ( ATM_wbilo      ) 
     1091ATM_flx_wbilo_oce   = ATM_flux_int ( ATM_wbilo_oce  ) 
     1092ATM_flx_wbilo_sic   = ATM_flux_int ( ATM_wbilo_sic  ) 
     1093ATM_flx_wbilo_sea   = ATM_flux_int ( ATM_wbilo_sea  ) 
     1094ATM_flx_wbilo_ter   = ATM_flux_int ( ATM_wbilo_ter  ) 
     1095ATM_flx_wbilo_lic   = ATM_flux_int ( ATM_wbilo_lic  ) 
    9351096ATM_flx_calving     = ATM_flux_int ( ATM_fqcalving  ) 
    936 ATM_flx_qfonte      = ATM_flux_int ( ATM_fqfonte    ) 
     1097ATM_flx_fqfonte     = ATM_flux_int ( ATM_fqfonte    ) 
     1098 
     1099print ( '- Step 11', end='' ) 
    9371100ATM_flx_precip      = ATM_flux_int ( ATM_precip     ) 
    9381101ATM_flx_snowf       = ATM_flux_int ( ATM_snowf      ) 
     
    9401103ATM_flx_runlic      = ATM_flux_int ( ATM_runofflic  ) 
    9411104 
     1105print ( '- Step 12', end='' ) 
     1106ATM_flx_wevap_ter   = ATM_flux_int ( ATM_wevap_ter ) 
     1107ATM_flx_wevap_sea   = ATM_flux_int ( ATM_wevap_sea ) 
     1108ATM_flx_precip_ter  = ATM_flux_int ( ATM_precip * ATM_fter ) 
     1109ATM_flx_precip_sea  = ATM_flux_int ( ATM_precip * ATM_fsea ) 
     1110ATM_flx_emp         = ATM_flux_int ( ATM_emp) 
     1111ATM_flx_wemp_ter    = ATM_flux_int ( ATM_wemp_ter ) 
     1112ATM_flx_wemp_oce    = ATM_flux_int ( ATM_wemp_oce ) 
     1113ATM_flx_wemp_lic    = ATM_flux_int ( ATM_wemp_lic ) 
     1114ATM_flx_wemp_sea    = ATM_flux_int ( ATM_wemp_sea ) 
     1115 
     1116print ( '- Step 13', end='' ) 
    9421117RUN_flx_coastal     = ONE_flux_int ( RUN_coastalflow) 
    9431118RUN_flx_river       = ONE_flux_int ( RUN_riverflow  ) 
     
    9501125RUN_flx_output      = ONE_flux_int ( RUN_output     ) 
    9511126 
    952 ATM_flx_emp   = ATM_flux_int (ATM_emp) 
    953 ATM_flx_wbilo = ATM_flux_int (ATM_wbilo) 
    954  
    955 RUN_flx_bil   = RUN_flx_input - RUN_flx_output 
     1127print ( '- Step 14' ) 
     1128RUN_flx_bil    = RUN_flx_input   - RUN_flx_output 
    9561129RUN_flx_rivcoa = RUN_flx_coastal + RUN_flx_river 
    9571130 
    958 prtFlux ('wbilo_oce     ', ATM_flx_oce, 'f' ) 
    959 prtFlux ('wbilo_oce     ', ATM_flx_oce, 'f' )           
    960 prtFlux ('wbilo_sic     ', ATM_flx_sic, 'f' )           
    961 prtFlux ('wbilo_sic+oce ', ATM_flx_sea, 'f' )           
    962 prtFlux ('wbilo_ter     ', ATM_flx_ter, 'f' )           
    963 prtFlux ('wbilo_lic     ', ATM_flx_lic, 'f' )           
     1131prtFlux ('wbilo_oce     ', ATM_flx_wbilo_oce  , 'f' )           
     1132prtFlux ('wbilo_sic     ', ATM_flx_wbilo_sic  , 'f' )           
     1133prtFlux ('wbilo_sic+oce ', ATM_flx_wbilo_sea  , 'f' )           
     1134prtFlux ('wbilo_ter     ', ATM_flx_wbilo_ter  , 'f' )           
     1135prtFlux ('wbilo_lic     ', ATM_flx_wbilo_lic  , 'f' )           
    9641136prtFlux ('Sum wbilo_*   ', ATM_flx_wbilo      , 'f', True)   
    9651137prtFlux ('E-P           ', ATM_flx_emp        , 'f', True)   
    9661138prtFlux ('calving       ', ATM_flx_calving    , 'f' )  
    967 prtFlux ('fqfonte       ', ATM_flx_qfonte     , 'f' )        
     1139prtFlux ('fqfonte       ', ATM_flx_fqfonte    , 'f' )        
    9681140prtFlux ('precip        ', ATM_flx_precip     , 'f' )        
    9691141prtFlux ('snowf         ', ATM_flx_snowf      , 'f' )         
     
    9821154prtFlux ('runoff lic    ', ATM_flx_runlic     , 'f' )    
    9831155 
    984 ATM_flx_budget = -ATM_flx_sea + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_qfonte + RUN_flx_river 
     1156ATM_flx_budget = -ATM_flx_wbilo + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_fqfonte + RUN_flx_river 
    9851157echo ('') 
    986 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 )) 
     1158#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 )) 
    9871159 
    9881160#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 )) 
     1161 
     1162ATM_flx_toSRF = -ATM_flx_wbilo_ter 
    9891163 
    9901164echo (' ') 
    9911165echo ( '\n====================================================================================' ) 
    9921166echo ( f'--  Atmosphere  -- {Title} ' ) 
    993 echo ( 'Mass begin = {:12.6e} kg | Mass end = {:12.6e} kg'.format (DYN_mas_wat_beg, DYN_mas_wat_end) ) 
    994 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. )) 
    995 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. )) 
    996 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. )) 
     1167echo ( f'Mass begin = {DYN_mas_wat_beg:12.6e} kg | Mass end = {DYN_mas_wat_end:12.6e} kg' ) 
     1168prtFlux ( 'dmass (atm)  = ', dDYN_mas_wat , 'e', True ) 
     1169prtFlux ( 'Sum wbilo_*  = ', ATM_flx_wbilo, 'e', True ) 
     1170prtFlux ( 'E-P          = ', ATM_flx_emp  , 'e', True ) 
    9971171echo ( ' ' ) 
    998 prtFlux ( 'Perte eau atm ', ATM_flx_wbilo - dDYN_mas_wat, 'e', True ) 
    999 echo ( 'Perte eau atm = {:12.3e} (rel)  '.format ( (ATM_flx_wbilo - dDYN_mas_wat)/dDYN_mas_wat  ) ) 
     1172prtFlux ( 'Water loss atm', ATM_flx_wbilo - dDYN_mas_wat, 'f', True ) 
     1173echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_wbilo - dDYN_mas_wat)/dDYN_mas_wat  ) ) 
    10001174 
    10011175echo (' ') 
    1002 prtFlux ( 'Perte eau atm', ATM_flx_emp  - dDYN_mas_wat , 'e', True ) 
    1003 echo ( 'Perte eau atm = {:12.3e} (rel)  '.format ( (ATM_flx_emp-dDYN_mas_wat)/dDYN_mas_wat  ) ) 
     1176prtFlux ( 'Water loss atm', ATM_flx_emp  - dDYN_mas_wat , 'f', True ) 
     1177echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_emp-dDYN_mas_wat)/dDYN_mas_wat  ) ) 
    10041178echo (' ') 
     1179 
     1180echo (' ') 
     1181echo ( '\n====================================================================================' ) 
     1182 
     1183ATM_flx_runofflic_lic = ATM_flux_int ( ATM_runofflic * ATM_flic ) 
     1184 
     1185LIC_flx_budget1 = -ATM_flx_wemp_lic  - ATM_flx_calving - ATM_flx_fqfonte 
     1186LIC_flx_budget2 = -ATM_flx_wbilo_lic - ATM_flx_calving - ATM_flx_fqfonte 
     1187LIC_flx_budget3 = -ATM_flx_wbilo_lic - ATM_flx_runofflic_lic 
     1188 
     1189echo ( f'--  LIC  -- {Title} ' ) 
     1190echo ( f'Mass total   begin = {LIC_mas_wat_beg    :12.6e} kg | Mass end = {LIC_mas_wat_end    :12.6e} kg' ) 
     1191echo ( f'Mass snow    begin = {LIC_mas_sno_beg    :12.6e} kg | Mass end = {LIC_mas_sno_end    :12.6e} kg' ) 
     1192echo ( f'Mass qs      begin = {LIC_mas_qs_beg     :12.6e} kg | Mass end = {LIC_mas_qs_end     :12.6e} kg' ) 
     1193echo ( f'Mass runlic0 begin = {LIC_mas_runlic0_beg:12.6e} kg | Mass end = {LIC_mas_runlic0_end:12.6e} kg' ) 
     1194prtFlux ( 'dmass (LIC sno)       ', dLIC_mas_sno          , 'f', True, width=65 ) 
     1195prtFlux ( 'dmass (LIC qs)        ', dLIC_mas_qs           , 'e', True, width=65 ) 
     1196prtFlux ( 'dmass (LIC wat)       ', dLIC_mas_wat          , 'f', True, width=65 ) 
     1197prtFlux ( 'dmass (LIC runlic0)   ', dLIC_mas_runlic0      , 'e', True, width=65 ) 
     1198prtFlux ( 'dmass (LIC total)     ', dLIC_mas_wat          , 'e', True, width=65 ) 
     1199prtFlux ( 'LIC ATM_flx_wemp_lic  ', ATM_flx_wemp_lic      , 'f', True, width=65 ) 
     1200prtFlux ( 'LIC ATM_flx_fqfonte   ', ATM_flx_fqfonte       , 'f', True, width=65 ) 
     1201prtFlux ( 'LIC ATM_flx_calving   ', ATM_flx_calving       , 'f', True, width=65 ) 
     1202prtFlux ( 'LIC ATM_flx_runofflic ', ATM_flx_runofflic_lic , 'f', True, width=65 ) 
     1203prtFlux ( 'LIC fqfonte + calving ', ATM_flx_calving+ATM_flx_fqfonte , 'f', True, width=65 ) 
     1204prtFlux ( 'LIC fluxes 1 (wevap - precip*frac_lic  - fqcalving - fqfonte) ', LIC_flx_budget1              , 'f', True, width=65 ) 
     1205prtFlux ( 'LIC fluxes 2 (-wbilo_lic - fqcalving - fqfonte)               ', LIC_flx_budget2              , 'f', True, width=65 ) 
     1206prtFlux ( 'LIC fluxes 3 (-wbilo_lic - runofflic*frac_lic)                ', LIC_flx_budget3              , 'f', True, width=65 ) 
     1207prtFlux ( 'LIC error 1                                                   ', LIC_flx_budget1-dLIC_mas_wat , 'e', True, width=65 ) 
     1208prtFlux ( 'LIC error 2                                                   ', LIC_flx_budget2-dLIC_mas_wat , 'e', True, width=65 ) 
     1209prtFlux ( 'LIC error 3                                                   ', LIC_flx_budget3-dLIC_mas_wat , 'e', True, width=65 ) 
     1210echo ( 'LIC error (wevap - precip*frac_lic  - fqcalving - fqfonte)    = {:12.4e} (rel) '.format ( (LIC_flx_budget1-dLIC_mas_wat)/dLIC_mas_wat) ) 
     1211echo ( 'LIC error (-wbilo_lic - fqcalving - fqfonte)                  = {:12.4e} (rel) '.format ( (LIC_flx_budget2-dLIC_mas_wat)/dLIC_mas_wat) ) 
     1212echo ( 'LIC error (-wbilo_lic - runofflic*frac_lic)                   = {:12.4e} (rel) '.format ( (LIC_flx_budget3-dLIC_mas_wat)/dLIC_mas_wat) ) 
    10051213 
    10061214echo ( '\n====================================================================================' ) 
     
    10191227SRF_flx_all = SRF_flx_rain + SRF_flx_snowf - SRF_flx_evap - RUN_flx_runoff - RUN_flx_drainage 
    10201228 
    1021 prtFlux ('rain       ', SRF_flx_rain     , 'f' ) 
    1022 prtFlux ('evap       ', SRF_flx_evap     , 'f' ) 
    1023 prtFlux ('snowf      ', SRF_flx_snowf    , 'f' ) 
    1024 prtFlux ('E-P        ', SRF_flx_emp      , 'f' ) 
    1025 prtFlux ('subli      ', SRF_flx_subli    , 'f' ) 
    1026 prtFlux ('transpir   ', SRF_flx_transpir , 'f' ) 
    1027 prtFlux ('to routing ', RUN_flx_torouting, 'f' ) 
    1028 prtFlux ('budget     ', SRF_flx_all      , 'f', True ) 
     1229prtFlux ('rain         ', SRF_flx_rain       , 'f' ) 
     1230prtFlux ('evap         ', SRF_flx_evap       , 'f' ) 
     1231prtFlux ('snowf        ', SRF_flx_snowf      , 'f' ) 
     1232prtFlux ('E-P          ', SRF_flx_emp        , 'f' ) 
     1233prtFlux ('subli        ', SRF_flx_subli      , 'f' ) 
     1234prtFlux ('transpir     ', SRF_flx_transpir  , 'f' ) 
     1235prtFlux ('to routing   ', RUN_flx_torouting  , 'f' ) 
     1236prtFlux ('budget       ', SRF_flx_all        , 'f', small=True ) 
    10291237 
    10301238echo ( '\n------------------------------------------------------------------------------------' ) 
    10311239echo ( 'Water content in surface ' ) 
    1032 echo ( 'SRF_mas_wat_beg  = {:12.6e} kg | SRF_mas_wat_end  = {:12.6e} kg '.format (SRF_mas_wat_beg, SRF_mas_wat_end) ) 
    1033 prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', True) 
     1240echo ( f'SRF_mas_wat_beg  = {SRF_mas_wat_beg:12.6e} kg | SRF_mas_wat_end  = {SRF_mas_wat_end:12.6e} kg ' ) 
     1241prtFlux ( 'dMass (water srf)', dSRF_mas_wat, 'e', small=True) 
     1242prtFlux ( 'Error            ',  SRF_flx_all-dSRF_mas_wat, 'e', small=True ) 
    10341243echo ( 'dMass (water srf) = {:12.4e} (rel)   '.format ( (SRF_flx_all-dSRF_mas_wat)/dSRF_mas_wat) ) 
     1244 
     1245echo ( '\n====================================================================================' ) 
     1246echo ( f'-- Check ATM vs. SRF -- {Title} ' ) 
     1247prtFlux ('E-P ATM       ', ATM_flx_wemp_ter   , 'f' ) 
     1248prtFlux ('wbilo ter     ', ATM_flx_wbilo_ter  , 'f' ) 
     1249prtFlux ('E-P SRF       ', SRF_flx_emp        , 'f' ) 
     1250prtFlux ('SRF/ATM error ', ATM_flx_wbilo_ter - SRF_flx_emp, 'e', True) 
     1251echo ( 'SRF/ATM error {:12.3e} (rel)  '.format ( (ATM_flx_wbilo_ter - SRF_flx_emp)/SRF_flx_emp ) ) 
    10351252 
    10361253echo ('') 
     
    10441261prtFlux ('coastal   ', RUN_flx_coastal     , 'f' )  
    10451262prtFlux ('riv+coa   ', RUN_flx_fromrouting , 'f' )  
    1046 prtFlux ('budget    ', RUN_flx_all         , 'f' , True) 
     1263prtFlux ('budget    ', RUN_flx_all         , 'f' , small=True) 
     1264 
     1265echo ( '\n------------------------------------------------------------------------------------' ) 
     1266echo ( f'Water content in routing+lake  -- {Title} ' ) 
     1267echo ( f'RUN_mas_wat_beg  = {RUN_mas_wat_beg:12.6e} kg | RUN_mas_wat_end = {RUN_mas_wat_end:12.6e} kg ' ) 
     1268prtFlux ( 'dMass (routing)  ', dRUN_mas_wat+dSRF_mas_lake, 'f', small=True) 
     1269prtFlux ( 'Routing error    ', RUN_flx_all+dSRF_mas_lake-dRUN_mas_wat, 'e', small=True ) 
     1270echo ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dSRF_mas_lake-dRUN_mas_wat)/(dRUN_mas_wat+dSRF_mas_lake) ) ) 
    10471271 
    10481272echo ( '\n------------------------------------------------------------------------------------' ) 
    10491273echo ( f'Water content in routing  -- {Title} ' ) 
    1050 echo ( 'RUN_mas_wat_beg  = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_beg, RUN_mas_wat_end) ) 
    1051 prtFlux ( 'dMass (routing)  ', dRUN_mas_wat+dSRF_mas_lake, 'f', True) 
    1052  
    1053 echo ( '\n------------------------------------------------------------------------------------' ) 
    1054 echo ( f'Water content in routing  -- {Title} ' ) 
    1055 echo ( 'RUN_mas_wat_beg  = {:12.6e} kg | RUN_mas_wat_end = {:12.6e} kg '.format (RUN_mas_wat_beg, RUN_mas_wat_end) ) 
    1056 prtFlux ( 'dMass (routing)  ', dRUN_mas_wat, 'f', True  ) 
    1057  
    1058 print ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dRUN_mas_wat)/dRUN_mas_wat ) ) 
     1274echo ( f'RUN_mas_wat_beg  = {RUN_mas_wat_beg:12.6e} kg | RUN_mas_wat_end = {RUN_mas_wat_end:12.6e} kg ' ) 
     1275prtFlux ( 'dMass (routing) ', dRUN_mas_wat, 'f', small=True  ) 
     1276prtFlux ( 'Routing error   ', RUN_flx_all-dRUN_mas_wat, 'e', small=True) 
     1277echo ( 'Routing error : {:12.3e} (rel)'.format ( (RUN_flx_all-dRUN_mas_wat)/dRUN_mas_wat ) ) 
    10591278 
    10601279# PRINT *,"routing water Balance ;  before : ", water_balance_before," ; after : ",water_balance_after,  &a 
    10611280# 1150              " ; delta : ", 100*(water_balance_after-water_balance_before)/(0.5*(water_balance_after+water_balance_before)),"%" 
     1281 
     1282echo ( ' ' ) 
     1283echo ( f'{Title = }' ) 
  • TOOLS/WATER_BUDGET/CPL_waterbudget.py

    r6277 r6508  
    2222### 
    2323## Import system modules 
    24 import sys, os, shutil, subprocess 
     24import sys, os, shutil, subprocess, platform 
    2525import numpy as np 
    2626import configparser, re 
    27  
    28 ## Creates parser 
    29 config = configparser.ConfigParser() 
     27from pathlib import Path 
     28 
     29# Check python version 
     30if sys.version_info < (3, 8, 0) : 
     31    print ( f'Python version : {platform.python_version()}' )  
     32    raise Exception ( "Minimum Python version is 3.8" ) 
     33 
     34## Import local module 
     35import WaterUtils as wu 
     36 
     37## Creates parser for reading .ini input file 
     38config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    3039config.optionxform = str # To keep capitals 
    3140 
    32 config['Files']  = {} 
    33 config['System'] = {} 
    34  
    35 ##-- Some physical constants 
    36 #-- Earth Radius 
    37 Ra = 6366197.7236758135 
    38 #-- Gravity 
    39 grav = 9.81 
    40 #-- Ice volumic mass (kg/m3) in LIM3/SI3 
    41 ICE_rho_ice = 917.0 
    42 #-- Snow volumic mass (kg/m3) in LIM3/SI3 
    43 ICE_rho_sno = 330.0 
    44 #-- Water in ponds coluclic mass (kg/m3) in LIM3/SI3 
    45 ICE_rho_pnd = 1000. 
    46 #-- Ocean water volumic mass (kg/m3) in NEMO 
    47 OCE_rho_liq = 1026. 
    48 #-- Water volumic mass in atmosphere 
    49 ATM_rho = 1.0e3 
    50 #-- Water volumic mass in surface reservoirs 
    51 SRF_rho = 1.0e3 
    52 #-- Water volumic mass of rivers 
    53 RUN_rho = 1.0e3 
    54  
    55 ## Read experiment parameters 
    56 ATM = None ; ORCA = None ; NEMO = None ; OCE_relax = False ; OCE_icb = False ; Coupled = False ; Routing = None 
    57  
    58 # Arguments passed 
     41## Experiment parameters 
     42ATM=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 
     43 
     44## 
     45ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None 
     46TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 
     47file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None 
     48tar_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 
     49file_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 
     50 
     51# Read command line arguments 
    5952print ( "Name of Python script:", sys.argv[0] ) 
    60 IniFile =  sys.argv[1] 
     53IniFile = sys.argv[1] 
     54# Text existence of IniFile 
     55if not os.path.exists (IniFile ) : 
     56    raise FileExistsError ( f"File not found : {IniFile = }" ) 
     57 
     58if 'full' in IniFile : FullIniFile = IniFile 
     59else                 : FullIniFile = 'full_' + IniFile 
     60     
    6161print ("Input file : ", IniFile ) 
    6262config.read (IniFile) 
    63  
    64 def setBool (chars) : 
    65     '''Convert specific char string in boolean if possible''' 
    66     setBool = chars 
    67     for key in configparser.ConfigParser.BOOLEAN_STATES.keys () : 
    68         if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key] 
    69     return setBool 
    70  
    71 def setNum (chars) : 
    72     '''Convert specific char string in integer or real if possible''' 
    73     if type (chars) == str : 
    74         realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$") 
    75         isReal = realnum.match(chars.strip()) != None 
    76         isInt  = chars.strip().isdigit() 
    77         if isReal : 
    78             if isInt : setNum = int   (chars) 
    79             else     : setNum = float (chars) 
    80         else : setNum = chars 
    81     else : setNum = chars 
    82     return setNum 
    83  
    84 print ('[Experiment]') 
    85 for VarName in config['Experiment'].keys() : 
    86     locals()[VarName] = config['Experiment'][VarName] 
    87     locals()[VarName] = setBool (locals()[VarName]) 
    88     locals()[VarName] = setNum  (locals()[VarName]) 
    89     print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) ) 
    90      
    91 ### 
    92 ICO  = ( 'ICO' in ATM ) 
    93 LMDZ = ( 'LMD' in ATM ) 
    94      
    95 ### 
    96 ## Import system modules 
    97 import sys, os, shutil, subprocess 
    98  
    99 # Where do we run ? 
    100 SysName, NodeName, Release, Version, Machine = os.uname() 
    101 TGCC  = ( 'irene'   in NodeName ) 
    102 IDRIS = ( 'jeanzay' in NodeName ) 
    103  
    104 ## Set site specific libIGCM directories, and other specific stuff 
    105 if TGCC : 
    106     CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' ) 
    107     if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene' 
    108     if "AMD"                       in CPU : Machine = 'irene-amd' 
    109          
    110     ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' ) 
    111     STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' ) 
    112     SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' ) 
    113     R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM') 
    114     rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' ) 
    115  
    116     ## Specific to run at TGCC. 
    117     # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...) 
    118     import mpi4py 
    119     mpi4py.rc.initialize = False 
    120          
    121     ## Creates output directory 
    122     #TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
    123     TmpDir = os.path.join ( '/ccc/scratch/cont003/drf/p86mart', f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
    124  
    125 if IDRIS : 
    126     raise Exception("Pour IDRIS : repertoires et chemins a definir")  
    127  
    128 ## Import specific module 
     63FullIniFile = 'full_' + IniFile 
     64 
     65## Reading config file 
     66for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] : 
     67   if Section in config.keys () :  
     68        print ( f'Reading [{Section}]' ) 
     69        for VarName in config[Section].keys() : 
     70            locals()[VarName] = config[Section][VarName] 
     71            exec ( f'{VarName} = wu.setBool ({VarName})' ) 
     72            exec ( f'{VarName} = wu.setNum  ({VarName})' ) 
     73            exec ( f'{VarName} = wu.setNone ({VarName})' ) 
     74            exec (  f'wu.{VarName} = {VarName}' ) 
     75            print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) ) 
     76            #exec ( f'del {VarName}' ) 
     77 
     78#-- Some physical constants 
     79if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m) 
     80if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s 
     81if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3 
     82if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3 
     83if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO 
     84if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3) 
     85if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3) 
     86if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3) 
     87if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3) 
     88if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s) - Use only to compute drif in approximate unit  
     89 
     90# Set libIGCM and machine dependant values 
     91if not 'Files' in config.keys() : config['Files'] = {} 
     92 
     93config['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} 
     94 
     95## -------------------------- 
     96ICO  = ( 'ICO' in wu.ATM ) 
     97LMDZ = ( 'LMD' in wu.ATM ) 
     98 
     99with open ('SetLibIGCM.py') as f: exec ( f.read() ) 
     100config['Files']['TmpDir'] = TmpDir 
     101 
     102if libIGCM : 
     103    config['libIGCM'] = {'ARCHIVE':ARCHIVE, 'STORAGE':STORAGE, 'SCRATCHDIR':SCRATCHDIR, 'R_IN':R_IN, 'rebuild':rebuild } 
     104 
     105# Import specific module 
    129106import nemo, lmdz 
    130107## Now import needed scientific modules 
    131108import xarray as xr 
    132109     
    133 # Output file 
    134 FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
     110# Output file with water budget diagnostics 
     111if wu.unDefined ( 'FileOut' ) : FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
     112config['Files']['FileOut'] = FileOut 
     113 
    135114f_out = open ( FileOut, mode = 'w' ) 
    136  
    137 # Function to print to stdout *and* output file 
     115     
     116# Useful functions 
     117def kg2Sv    (val, rho=ATM_rho) : 
     118    '''From kg to Sverdrup''' 
     119    return val/dtime_sec*1.0e-6/rho 
     120 
     121def kg2myear (val, rho=ATM_rho) : 
     122    '''From kg to m/year''' 
     123    return val/ATM_aire_sea_tot/rho/NbYear 
     124 
     125def var2prt (var, small=False, rho=ATM_rho) : 
     126    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000. 
     127    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho) 
     128 
     129def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) : 
     130    if small : 
     131        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
     132        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year " 
     133    else : 
     134        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  " 
     135        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  " 
     136    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) ) 
     137    return None 
     138 
    138139def echo (string, end='\n') : 
    139     print ( string, end=end  ) 
     140    '''Function to print to stdout *and* output file''' 
     141    print ( str(string), end=end  ) 
    140142    sys.stdout.flush () 
    141     f_out.write ( string + end ) 
     143    f_out.write ( str(string) + end ) 
    142144    f_out.flush () 
    143145    return None 
    144146     
    145147## Set libIGCM directories 
    146 R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT') 
    147 R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT') 
    148  
    149 L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    150 R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    151 R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    152 POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' ) 
    153 REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' ) 
    154 R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    155 R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    156  
    157 #if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir ) 
    158 if not os.path.isdir (TmpDir) : os.mkdir (TmpDir) 
    159 TmpDirOCE = os.path.join (TmpDir, 'OCE') 
    160 TmpDirICE = os.path.join (TmpDir, 'ICE') 
    161 if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE ) 
    162 if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE ) 
    163  
    164 echo ( f'Working in TMPDIR : {TmpDir}' ) 
    165  
    166 echo ( f'\nDealing with {L_EXP}' ) 
     148if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
     149if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
     150if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
     151if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
     152if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
     153if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
     154if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' ) 
     155if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
     156if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
     157 
     158config['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 } 
     159 
     160# Set directory to extract filesa 
     161if RunDir == None : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
     162config['Files']['RunDir'] = RunDir 
     163 
     164if not os.path.isdir ( RunDir ) : os.makedirs ( RunDir ) 
     165 
     166# Set directories to rebuild ocean and ice restart files 
     167RunDirOCE = os.path.join ( RunDir, 'OCE' ) 
     168RunDirICE = os.path.join ( RunDir, 'ICE' ) 
     169#RunDirATM = os.path.join ( RunDir, 'ATM' ) 
     170#RunDirSRF = os.path.join ( RunDir, 'SRF' ) 
     171#RunDirRUN = os.path.join ( RunDir, 'RUN' ) 
     172#RunDirDYN = os.path.join ( RunDir, 'DYN' ) 
     173if not os.path.exists ( RunDirOCE ) : os.mkdir ( RunDirOCE ) 
     174if not os.path.exists ( RunDirICE ) : os.mkdir ( RunDirICE ) 
     175 
     176echo (' ') 
     177echo ( f'JobName   : {JobName}'   ) 
     178echo ( f'Comment   : {Comment}'   ) 
     179echo ( f'TmpDir    : {TmpDir}'    ) 
     180echo ( f'RunDirOCE : {RunDirOCE}' ) 
     181echo ( f'RunDirICE : {RunDirICE}' ) 
     182 
     183echo ( f'\nDealing with {L_EXP}'  ) 
    167184 
    168185#-- Model output directories 
    169186if Freq == "MO" : FreqDir =  os.path.join ('Output' , 'MO' ) 
    170187if Freq == "SE" : FreqDir =  os.path.join ('Analyse', 'SE' ) 
    171 dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) 
    172 dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) 
    173 dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) 
    174 dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) 
     188if dir_ATM_his == None : 
     189    dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) 
     190    config['Files']['dir_ATM_his'] = dir_ATM_his 
     191if dir_SRF_his == None :  
     192    dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) 
     193    config['Files']['dir_SRF_his'] = dir_SRF_his 
     194if dir_OCE_his == None : 
     195    dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) 
     196    config['Files']['dir_OCE_his'] = dir_OCE_his 
     197if dir_ICE_his == None :  
     198    dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) 
     199    config['Files']['dir_ICE_his'] = dir_ICE_his 
    175200 
    176201echo ( f'The analysis relies on files from the following model output directories : ' ) 
     
    180205echo ( f'{dir_SRF_his}' ) 
    181206 
    182 #-- Files Names 
    183 if Freq == 'MO' : FileCommon = f'{JobName}_{YearBegin}0101_{YearEnd}1231_1M' 
    184 if Freq == 'SE' : FileCommon = f'{JobName}_SE_{YearBegin}0101_{YearEnd}1231_1M' 
     207#-- Creates files names 
     208if Period == None : 
     209    if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M' 
     210    if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M' 
     211    config['Files']['Period'] = Period 
     212if FileCommon == None : 
     213    FileCommon = f'{JobName}_{Period}' 
     214    config['Files']['FileCommon'] = FileCommon 
     215 
     216if Title == None : 
     217    Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31' 
     218    config['Files']['Title'] = Title 
    185219 
    186220echo ('\nOpen history files' ) 
    187 file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' ) 
    188 file_OCE_his = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
    189 file_OCE_sca = os.path.join (  dir_OCE_his, f'{FileCommon}_scalar.nc' ) 
    190 file_ICE_his = os.path.join (  dir_ICE_his, f'{FileCommon}_icemod.nc' ) 
    191 file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    192 file_OCE_srf = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
     221if file_ATM_his == None :  
     222    file_ATM_his = os.path.join (  dir_ATM_his, f'{FileCommon}_histmth.nc' ) 
     223    config['Files']['file_ATM_his'] = file_ATM_his 
     224if file_SRF_his == None : 
     225    file_SRF_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
     226    config['Files']['file_SRF_his'] = file_SRF_his 
     227#if Routing == 'SECHIBA'  : 
     228#     file_RUN_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
     229if Routing == 'SIMPLE' : 
     230    if file_RUN_his == None :  
     231        file_RUN_his = os.path.join (  dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
     232        config['Files']['file_RUN_his'] = file_RUN_his 
     233if file_OCE_his == None : 
     234    file_OCE_his = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
     235    config['Files']['file_OCE_his'] = file_OCE_his 
     236if file_OCE_sca == None : 
     237    file_OCE_sca = os.path.join (  dir_OCE_his, f'{FileCommon}_scalar.nc' ) 
     238    config['Files']['file_OCE_sca'] = file_OCE_sca 
     239if file_ICE_his == None : 
     240    file_ICE_his = os.path.join (  dir_ICE_his, f'{FileCommon}_icemod.nc' ) 
     241    config['Files']['file_ICE_his'] = file_ICE_his 
     242if file_OCE_srf == None : 
     243    file_OCE_srf = os.path.join (  dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
     244    config['Files']['file_OCE_srf'] = file_OCE_srf 
    193245 
    194246d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     
    199251d_SRF_his = xr.open_dataset ( file_SRF_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    200252d_OCE_srf = xr.open_dataset ( file_OCE_srf, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    201  
    202 echo ( file_ATM_his ) 
    203 echo ( file_OCE_his ) 
    204 echo ( file_OCE_sca ) 
    205 echo ( file_ICE_his ) 
    206 echo ( file_SRF_his ) 
     253if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his 
     254if Routing == 'SIMPLE'  : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     255 
     256     
     257echo ( f'{file_ATM_his = }' ) 
     258echo ( f'{file_SRF_his = }' ) 
     259if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' ) 
     260echo ( f'{file_OCE_his = }' ) 
     261echo ( f'{file_ICE_his = }' ) 
     262echo ( f'{file_OCE_sca = }' ) 
     263echo ( f'{file_OCE_srf = }' ) 
    207264 
    208265## Compute run length 
     
    216273dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds 
    217274dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] ) 
     275dtime_per_sec.attrs['unit'] = 's' 
     276 
     277# Number of years 
     278NbYear = dtime_sec / YearLength 
    218279 
    219280#-- Open restart files 
     
    221282YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation 
    222283 
     284config['Files']['YearPre'] = f'{YearBegin}' 
     285 
    223286echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
    224287 
    225 file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearPre}0101_{YearRes}1231_restart.tar' ) 
    226 file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{YearBegin}0101_{YearEnd}1231_restart.tar' ) 
    227  
    228 echo ( f'{file_restart_beg}' ) 
    229 echo ( f'{file_restart_end}' ) 
    230  
    231 file_OCE_beg = f'OCE_{JobName}_{YearRes}1231_restart.nc' 
    232 file_OCE_end = f'OCE_{JobName}_{YearEnd}1231_restart.nc' 
    233 file_ICE_beg = f'ICE_{JobName}_{YearRes}1231_restart_icemod.nc' 
    234 file_ICE_end = f'ICE_{JobName}_{YearEnd}1231_restart_icemod.nc' 
    235  
    236 echo ( f'{file_OCE_beg}' ) 
    237 echo ( f'{file_OCE_end}' ) 
    238 echo ( f'{file_ICE_beg}' ) 
    239 echo ( f'{file_ICE_end}' ) 
    240  
    241 file_ATM_beg = f'ATM_{JobName}_{YearRes}1231_restartphy.nc' 
    242 file_ATM_end = f'ATM_{JobName}_{YearEnd}1231_restartphy.nc' 
    243 if LMDZ : 
    244     file_DYN_beg = f'ATM_{JobName}_{YearRes}1231_restart.nc' 
    245     file_DYN_end = f'ATM_{JobName}_{YearEnd}1231_restart.nc' 
    246 if ICO : 
    247     file_DYN_beg = f'ICO_{JobName}_{YearRes}1231_restart.nc' 
    248     file_DYN_end = f'ICO_{JobName}_{YearEnd}1231_restart.nc' 
    249 file_SRF_beg = f'SRF_{JobName}_{YearRes}1231_sechiba_rest.nc' 
    250 file_SRF_end = f'SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc' 
    251 liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg, ] 
    252 liste_end = [file_ATM_end, file_DYN_end, file_SRF_end, ] 
    253 echo ( f'{file_ATM_beg}') 
    254 echo ( f'{file_ATM_end}') 
    255 echo ( f'{file_SRF_beg}') 
    256 echo ( f'{file_SRF_end}') 
    257  
    258 if Routing == 'SIMPLE' :  
    259     file_RUN_beg = f'SRF_{JobName}_{YearRes}1231_routing_restart.nc' 
    260     file_RUN_end = f'SRF_{JobName}_{YearEnd}1231_routing_restart.nc' 
     288if TarRestartPeriod_beg == None :  
     289    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
     290    TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231' 
     291    config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg 
     292 
     293if TarRestartPeriod_end == None :  
     294    YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation 
     295    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
     296    TarRestartPeriod_end = f'{YearBegin}0101_{YearEnd}1231' 
     297    config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end 
     298 
     299if tar_restart_beg == None : 
     300    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
     301    config['Files']['tar_restart_beg'] = tar_restart_beg 
     302if tar_restart_end == None : 
     303    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
     304    config['Files']['tar_restart_end'] = tar_restart_end 
     305 
     306echo ( f'{tar_restart_beg}' ) 
     307echo ( f'{tar_restart_end}' ) 
     308 
     309if file_ATM_beg == None :  
     310    file_ATM_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restartphy.nc' 
     311    config['Files']['file_ATM_beg'] = file_ATM_beg 
     312if file_ATM_end == None : 
     313    file_ATM_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restartphy.nc' 
     314    config['Files']['file_ATM_end'] = file_ATM_end 
     315 
     316if file_DYN_beg == None : 
     317    if LMDZ : file_DYN_beg = f'{RunDir}/ATM_{JobName}_{YearRes}1231_restart.nc' 
     318    if ICO  : file_DYN_beg = f'{RunDir}/ICO_{JobName}_{YearRes}1231_restart.nc' 
     319    config['Files']['file_DYN_beg'] = file_DYN_beg 
     320     
     321if file_DYN_end == None :  
     322    if LMDZ : file_DYN_end = f'{RunDir}/ATM_{JobName}_{YearEnd}1231_restart.nc' 
     323    if ICO  : file_DYN_end = f'{RunDir}/ICO_{JobName}_{YearEnd}1231_restart.nc' 
     324    config['Files']['file_DYN_end'] = file_DYN_end 
     325     
     326if file_SRF_beg == None : 
     327    file_SRF_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_sechiba_rest.nc' 
     328    config['Files']['file_SRF_beg'] = file_SRF_beg 
     329if file_SRF_end == None : 
     330    file_SRF_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_sechiba_rest.nc' 
     331    config['Files']['file_SRF_end'] = file_SRF_end 
     332     
     333if file_OCE_beg == None :  
     334    file_OCE_beg = f'{RunDir}/OCE_{JobName}_{YearRes}1231_restart.nc' 
     335    config['Files']['file_OCE_beg'] = file_OCE_beg 
     336if file_OCE_end == None : 
     337    file_OCE_end = f'{RunDir}/OCE_{JobName}_{YearEnd}1231_restart.nc' 
     338    config['Files']['file_OCE_end'] = file_OCE_end 
     339if file_ICE_beg == None : 
     340    file_ICE_beg = f'{RunDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc' 
     341    config['Files']['file_ICE_beg'] = file_ICE_beg 
     342if file_ICE_end == None :  
     343    file_ICE_end = f'{RunDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc' 
     344    config['Files']['file_ICE_end'] = file_ICE_end 
     345 
     346liste_beg = [file_ATM_beg, file_DYN_beg, file_SRF_beg] 
     347liste_end = [file_ATM_end, file_DYN_end, file_SRF_end] 
     348 
     349if Routing == 'SIMPLE' : 
     350    if file_RUN_beg == None :  
     351        file_RUN_beg = f'{RunDir}/SRF_{JobName}_{YearRes}1231_routing_restart.nc' 
     352        config['Files']['file_RUN_beg'] = file_RUN_beg 
     353    if file_RUN_end == None :  
     354        file_RUN_end = f'{RunDir}/SRF_{JobName}_{YearEnd}1231_routing_restart.nc' 
     355        config['Files']['file_RUN_end'] = file_RUN_end 
     356         
    261357    liste_beg.append ( file_RUN_beg ) 
    262358    liste_end.append ( file_RUN_end ) 
    263     echo ( f'{file_RUN_beg}') 
    264     echo ( f'{file_RUN_end}') 
     359    echo ( f'{file_RUN_beg = }' ) 
     360    echo ( f'{file_RUN_end = }' ) 
     361 
     362echo ( f'{file_ATM_beg = }' ) 
     363echo ( f'{file_ATM_end = }' ) 
     364echo ( f'{file_DYN_beg = }' ) 
     365echo ( f'{file_DYN_end = }' ) 
     366echo ( f'{file_SRF_beg = }' ) 
     367echo ( f'{file_SRF_end = }' ) 
     368echo ( f'{file_RUN_beg = }' ) 
     369echo ( f'{file_RUN_end = }' ) 
     370echo ( f'{file_OCE_beg = }' ) 
     371echo ( f'{file_OCE_end = }' ) 
     372echo ( f'{file_ICE_beg = }' ) 
     373echo ( f'{file_ICE_end = }' ) 
    265374 
    266375echo ('\nExtract restart files from tar : ATM, ICO and SRF') 
    267 for resFile in liste_beg : 
    268     if not os.path.exists ( os.path.join (TmpDir, resFile) ) : 
    269         command =  f'cd {TmpDir} ; tar xf {file_restart_beg} {resFile}' 
     376for resFile in liste_beg + liste_end : 
     377    if os.path.exists ( os.path.join (RunDir, resFile) ) : 
     378        echo ( f'file found : {resFile = }' ) 
     379    else : 
     380        base_file = Path (file_name).stem # basename, and remove suffix 
     381        command =  f'cd {RunDir} ; tar xf {tar_restart_beg} {base_resFile}.nc' 
    270382        echo ( command ) 
    271         os.system ( command ) 
    272          
    273 for resFile in liste_end : 
    274     if not os.path.exists ( os.path.join (TmpDir, resFile) ) : 
    275         command =  f'cd {TmpDir} ; tar xf {file_restart_end} {resFile}' 
    276         echo ( command ) 
    277         os.system ( command ) 
     383        ierr = os.system ( command ) 
     384        if ierr == 0 : echo ( f'tar done : {base_resFile}') 
     385        else         : raise Exception ( f'command failed : {command}' ) 
    278386 
    279387echo ('\nOpening ATM SRF and ICO restart files') 
    280 d_ATM_beg = xr.open_dataset ( os.path.join (TmpDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze() 
    281 d_ATM_end = xr.open_dataset ( os.path.join (TmpDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze() 
    282 d_SRF_beg = xr.open_dataset ( os.path.join (TmpDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze() 
    283 d_SRF_end = xr.open_dataset ( os.path.join (TmpDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze() 
    284 d_DYN_beg = xr.open_dataset ( os.path.join (TmpDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze() 
    285 d_DYN_end = xr.open_dataset ( os.path.join (TmpDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze() 
    286  
    287 for var in d_SRF_beg.variables : 
    288     d_SRF_beg[var] = d_SRF_beg[var].where (  d_SRF_beg[var]<1.e20, 0.) 
    289     d_SRF_end[var] = d_SRF_end[var].where (  d_SRF_end[var]<1.e20, 0.) 
    290  
    291 if ICO : 
    292     d_RUN_beg = xr.open_dataset ( os.path.join (TmpDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze() 
    293     d_RUN_end = xr.open_dataset ( os.path.join (TmpDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze() 
     388d_ATM_beg = xr.open_dataset ( os.path.join (RunDir, file_ATM_beg), decode_times=False, decode_cf=True).squeeze() 
     389d_ATM_end = xr.open_dataset ( os.path.join (RunDir, file_ATM_end), decode_times=False, decode_cf=True).squeeze() 
     390d_SRF_beg = xr.open_dataset ( os.path.join (RunDir, file_SRF_beg), decode_times=False, decode_cf=True).squeeze() 
     391d_SRF_end = xr.open_dataset ( os.path.join (RunDir, file_SRF_end), decode_times=False, decode_cf=True).squeeze() 
     392d_DYN_beg = xr.open_dataset ( os.path.join (RunDir, file_DYN_beg), decode_times=False, decode_cf=True).squeeze() 
     393d_DYN_end = xr.open_dataset ( os.path.join (RunDir, file_DYN_end), decode_times=False, decode_cf=True).squeeze() 
    294394 
    295395echo ('\nExtract and rebuild OCE and ICE restarts') 
     
    298398    #ndomain_opa = d_zfile.attrs['DOMAIN_number_total'] 
    299399    #d_zfile.close () 
    300     ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ).format() 
     400    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format() 
    301401    return int (ndomain_opa) 
    302402 
    303  
    304 if not os.path.exists ( os.path.join (TmpDir, file_OCE_beg) ) : 
    305     if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart_0000.nc') ): 
    306         command =  f'cd {TmpDirOCE} ; tar xf {file_restart_beg}  OCE_{JobName}_{YearRes}1231_restart_*.nc' 
     403def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, RunDirComp=RunDirOCE ) : 
     404    '''Extract restart file from tar. Rebuild ocean files if needed''' 
     405    echo ( f'file to extract : {file_name} ' ) 
     406    if os.path.exists ( file_name ) : 
     407        echo ( f'-- File ready : {file_name}' ) 
     408    else :  
     409        echo ( f'-- Extracting {file_name}' ) 
     410        base_resFile = Path (file_name).stem # basename, and remove suffix 
     411        # Try to extract the rebuilded file 
     412        command =  f'cd {RunDirComp} ; tar xf {tar_restart} {base_resFile}.nc' 
    307413        echo ( command ) 
    308         os.system ( command ) 
    309     ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart') ) 
    310     command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearRes}1231_restart {ndomain_opa} ; mv {file_OCE_beg} {TmpDir}' 
    311     echo ( command ) 
    312     os.system ( command ) 
    313     echo ( f'Rebuild done : {file_OCE_beg}') 
    314      
    315 if not os.path.exists ( os.path.join (TmpDir, file_OCE_end) ) : 
    316     if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart_0000.nc') ): 
    317         command =  f'cd {TmpDirOCE} ; tar xf {file_restart_end}  OCE_{JobName}_{YearEnd}1231_restart_*.nc' 
    318         echo ( command ) 
    319         os.system ( command ) 
    320     ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart') ) 
    321     command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearEnd}1231_restart {ndomain_opa} ; mv {file_OCE_end} {TmpDir}' 
    322     echo ( command ) 
    323     os.system ( command ) 
    324     echo ( f'Rebuild done : {file_OCE_end}') 
    325  
    326 if not os.path.exists ( os.path.join (TmpDir, file_ICE_beg) ) : 
    327     if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ): 
    328         command =  f'cd {TmpDirICE} ; tar xf {file_restart_beg}  ICE_{JobName}_{YearRes}1231_restart_icemod_*.nc' 
    329         echo ( command ) 
    330         os.system ( command ) 
    331     ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) 
    332     command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearRes}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_beg} {TmpDir} ' 
    333     echo ( command ) 
    334     os.system ( command ) 
    335     echo ( f'Rebuild done : {file_OCE_beg}') 
    336      
    337 if not os.path.exists ( os.path.join (TmpDir, file_ICE_end) ) : 
    338     if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearEnd}1231_restart_icemod') ): 
    339         command =  f'cd {TmpDirICE} ; tar xf {file_restart_end} ICE_{JobName}_{YearEnd}1231_restart_icemod_*.nc' 
    340         echo ( command ) 
    341         os.system ( command ) 
    342     ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) 
    343     command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearEnd}1231_restart_icemod {ndomain_opa} ; mv {file_ICE_end} {TmpDir}' 
    344     echo ( command ) 
    345     os.system ( command ) 
    346     echo ( f'Rebuild done : {file_ICE_end}') 
     414        ierr = os.system ( command ) 
     415        if ierr == 0 : 
     416            echo ( f'tar done : {base_resFile}') 
     417            command = f'cd {RunDirComp} ; mv {base_resFile}.nc {RunDir}' 
     418            ierr = os.system ( command ) 
     419            if ierr == 0 : echo ( f'command done : {command}' ) 
     420            else         : raise Exception ( f'command failed : {command}' ) 
     421        else : 
     422            if not os.path.exists ( os.path.join (RunDir, f'{base_resFile}_0000.nc') ): 
     423                command =  f'cd {RunDirComp} ; tar xf {tar_restart_end} {base_resFile}_*.nc' 
     424                echo ( command ) 
     425                ierr = os.system ( command ) 
     426                if ierr == 0 : echo ( f'tar done : {file_OCE_beg}') 
     427                else         : raise Exception ( f'command failed : {command}' ) 
     428                echo ('extract ndomain' ) 
     429            ndomain_opa = get_ndomain ( os.path.join (RunDir, f'{base_resFile}') ) 
     430            command = f'cd {RunDirComp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {RunDir}' 
     431            echo ( command ) 
     432            ierr = os.system ( command ) 
     433            if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc') 
     434            else         : raise Exception ( f'command failed : {command}' ) 
     435 
     436extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirOCE ) 
     437extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, RunDirComp=RunDirOCE ) 
     438extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirICE ) 
     439extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, RunDirComp=RunDirICE ) 
    347440 
    348441echo ('Opening OCE and ICE restart files') 
    349442if NEMO == 3.6 :  
    350     d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    351     d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze() 
    352     d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze() 
    353     d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze() 
     443    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     444    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze() 
     445    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze() 
     446    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze() 
    354447if NEMO == 4.0 or NEMO == 4.2 :  
    355     d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    356     d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    357     d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    358     d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    359      
    360 echo ( file_ATM_beg ) 
    361 echo ( file_ATM_end ) 
    362 echo ( file_DYN_beg ) 
    363 echo ( file_DYN_end ) 
    364 echo ( file_SRF_beg ) 
    365 echo ( file_SRF_end ) 
    366 if Routing == 'SIMPLE' : 
    367     echo ( file_RUN_beg ) 
    368     echo ( file_RUN_end ) 
    369 echo ( file_OCE_beg ) 
    370 echo ( file_OCE_end ) 
    371 echo ( file_ICE_beg ) 
    372 echo ( file_ICE_end ) 
    373  
    374 def ATM_stock_int (stock) : 
    375     '''Integrate stock on atmosphere grid''' 
    376     ATM_stock_int  = np.sum (  np.sort ( (stock * DYN_aire).to_masked_array().ravel()) ) 
    377     return ATM_stock_int 
    378  
    379 def OCE_stock_int (stock) : 
    380     '''Integrate stock on ocean grid''' 
    381     OCE_stock_int  = np.sum (  np.sort ( (stock * OCE_aire).to_masked_array().ravel()) ) 
    382     return OCE_stock_int 
    383  
    384 def ONE_stock_int (stock) :  
    385     '''Sum stock for field already integrated by cell''' 
    386     ONE_stock_int  = np.sum (  np.sort ( (stock).to_masked_array().ravel()) ) 
    387     return ONE_stock_int 
    388  
    389 # ATM grid with cell surfaces 
     448    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     449    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     450    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     451    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     452 
     453## Write the full configuration 
     454config_out = open (FullIniFile, 'w') 
     455config.write (config_out ) 
     456config_out.close () 
     457 
     458for var in d_SRF_beg.variables : 
     459    d_SRF_beg[var] = d_SRF_beg[var].where (  d_SRF_beg[var]<1.e20, 0.) 
     460    d_SRF_end[var] = d_SRF_end[var].where (  d_SRF_end[var]<1.e20, 0.) 
     461 
     462if ICO : 
     463    d_RUN_beg = xr.open_dataset ( os.path.join (RunDir, file_RUN_beg), decode_times=False, decode_cf=True).squeeze() 
     464    d_RUN_end = xr.open_dataset ( os.path.join (RunDir, file_RUN_end), decode_times=False, decode_cf=True).squeeze() 
     465 
     466def kg2Sv  (val, rho=OCE_rho_liq) : 
     467    '''From kg to Sverdrup''' 
     468    return val/dtime_sec*1.0e-6/rho 
     469 
     470def kg2myear (val, rho=OCE_rho_liq) : 
     471    '''From kg to m/year''' 
     472    return val/OCE_aire_tot/rho/NbYear 
     473 
     474def var2prt (var, small=False) : 
     475    if small :  return var , kg2Sv(var)*1000., kg2myear(var)*1000. 
     476    else     :  return var , kg2Sv(var)      , kg2myear(var) 
     477 
     478def prtFlux (Desc, var, Form='F', small=False) : 
     479    if small : 
     480        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
     481        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year " 
     482    else : 
     483        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  " 
     484        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  " 
     485    echo ( (' {:>15} = ' +ff).format (Desc, *var2prt(var, small) ) ) 
     486    return None 
     487 
     488 
     489 
    390490# ATM grid with cell surfaces 
    391491if ICO : 
    392     jpja, jpia = d_ATM_his['aire'][0].shape    
    393     file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' ) 
    394     d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze() 
    395     ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True ) 
    396     ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] ) 
    397     ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] + d_ATM_his ['fract_lic'][0] ) 
    398     SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] ) 
    399      
     492    if ATM_HIS == 'latlon' : 
     493        jpja, jpia = d_ATM_his['aire'][0].shape    
     494        file_ATM_aire = os.path.join ( R_IN, 'ATM', 'GRID', f'aire_{ATM}_to_{jpia}x{jpja}.nc' ) 
     495        config['Files']['file_ATM_aire'] = file_ATM_aire 
     496        echo ( f'Aire sur grille reguliere : {file_ATM_aire = }' ) 
     497        d_ATM_aire = xr.open_dataset ( file_ATM_aire, decode_times=False ).squeeze() 
     498        ATM_aire = lmdz.geo2point ( d_ATM_aire ['aire'].squeeze(), cumulPoles=True ) 
     499        ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) 
     500        ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] ) 
     501        ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] ) 
     502        ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] ) 
     503        SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] ) 
     504        #SRF_aire = ATM_aire * lmdz.geo2point (d_SRF_his ['Contfrac'] ) 
     505        #SRF_aire = ATM_aire * ATM_fter 
     506    if ATM_HIS == 'ico' : 
     507        echo ( f'Aire sur grille icosaedre : {file_ATM_aire = }' ) 
     508         
    400509if LMDZ : 
    401510    ATM_aire = lmdz.geo2point ( d_ATM_his ['aire'][0], cumulPoles=True ) 
    402     ATM_fsea = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] + d_ATM_his ['fract_sic'][0] ) 
    403     ATM_flnd = lmdz.geo2point ( d_ATM_his ['fract_ter'][0]  ) 
    404     SRF_aire = lmdz.geo2point ( d_SRF_his ['Areas'] * d_SRF_his ['Contfrac'] ) 
     511    ATM_fter = lmdz.geo2point ( d_ATM_his ['fract_ter'][0] ) 
     512    ATM_foce = lmdz.geo2point ( d_ATM_his ['fract_oce'][0] ) 
     513    ATM_fsic = lmdz.geo2point ( d_ATM_his ['fract_sic'][0] ) 
     514    ATM_flic = lmdz.geo2point ( d_ATM_his ['fract_lic'][0] ) 
     515    #SRF_aire = lmdz.geo2point ( d_SRF_his['Areas'] * d_SRF_his['Contfrac'] ) 
     516    SRF_aire = ATM_aire * lmdz.geo2point ( d_SRF_his['Contfrac'] ) 
     517     
     518ATM_fsea      = ATM_foce + ATM_fsic 
     519ATM_flnd      = ATM_fter + ATM_flic 
     520ATM_aire_fter = ATM_aire * ATM_fter 
     521ATM_aire_flic = ATM_aire * ATM_flic 
     522ATM_aire_fsic = ATM_aire * ATM_fsic 
     523ATM_aire_foce = ATM_aire * ATM_foce 
     524ATM_aire_flnd = ATM_aire * ATM_flnd 
     525ATM_aire_fsea = ATM_aire * ATM_fsea 
     526 
     527SRF_aire = SRF_aire.where ( SRF_aire < 1E15, 0.) 
    405528 
    406529if ICO : 
     
    415538     
    416539if LMDZ : 
     540    # Area on lon/lat grid 
    417541    DYN_aire = ATM_aire 
    418542    DYN_fsea = ATM_fsea 
    419543    DYN_flnd = ATM_flnd 
    420  
     544    DYN_fter = d_ATM_beg['FTER'] 
     545    DYN_flic = d_ATM_beg['FTER'] 
     546 
     547def ATM_stock_int (stock) : 
     548    '''Integrate (* surface) stock on atmosphere grid''' 
     549    ATM_stock_int  = wu.Psum ( (stock * DYN_aire).to_masked_array().ravel() )  
     550    return ATM_stock_int 
     551 
     552def ATM_flux_int (flux) : 
     553    '''Integrate (* time * surface) flux on atmosphere grid''' 
     554    ATM_flux_int  = wu.Psum ( (flux * dtime_per_sec * ATM_aire).to_masked_array().ravel() ) 
     555    return ATM_flux_int 
     556 
     557def SRF_stock_int (stock) : 
     558    '''Integrate (* surface) stock on land grid''' 
     559    ATM_stock_int  = wu.Ksum (  ( (stock * DYN_aire_fter).to_masked_array().ravel()) ) 
     560    return ATM_stock_int 
     561 
     562def SRF_flux_int (flux) : 
     563    '''Integrate (* time * surface) flux on land grid''' 
     564    SRF_flux_int  = wu.Psum (  (flux * dtime_per_sec * SRF_aire).to_masked_array().ravel() ) 
     565    return SRF_flux_int 
     566 
     567def OCE_stock_int (stock) : 
     568    '''Integrate stock on ocean grid''' 
     569    OCE_stock_int = np.sum (  np.sort ( (stock * OCE_aire ).to_masked_array().ravel()) ) 
     570    return OCE_stock_int 
     571 
     572def ONE_stock_int (stock) : 
     573    '''Sum stock''' 
     574    ONE_stock_int = np.sum (  np.sort ( (stock ).to_masked_array().ravel()) ) 
     575    return ONE_stock_int 
     576 
     577def OCE_flux_int (flux) : 
     578    '''Integrate flux on oce grid''' 
     579    OCE_flux_int = np.sum (  np.sort ( (flux * OCE_aire * dtime_per_sec).to_masked_array().ravel()) ) 
     580    return OCE_flux_int 
     581 
     582def ONE_flux_int (flux) : 
     583    '''Integrate flux on oce grid''' 
     584    OCE_flux_int = np.sum (  np.sort ( (flux * dtime_per_sec).to_masked_array().ravel()) ) 
     585    return OCE_flux_int 
     586     
    421587#if LMDZ : 
    422588#    d_ATM_beg = d_ATM_beg.assign ( coords={'lon':d_ATM_beg.lon*180./np.pi} ) 
     
    440606ATM_aire_sea_tot = ONE_stock_int ( ATM_aire_sea ) 
    441607 
    442 echo ( '\n------------------------------------------------------------------------------------' ) 
     608echo ( '\n====================================================================================' ) 
    443609echo ( '-- NEMO change in stores (for the records)' ) 
    444610#-- Note that the total number of days of the run should be diagnosed rather than assumed 
     
    522688    dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat 
    523689 
    524 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) ) 
    525 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) ) 
    526 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) ) 
    527 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) ) 
    528  
    529 echo ( 'dICE_vol_ice   = {:12.3e} m^3'.format (dICE_vol_ice) ) 
    530 echo ( 'dICE_vol_sno   = {:12.3e} m^3'.format (dICE_vol_sno) ) 
    531 echo ( 'dICE_vol_pnd   = {:12.3e} m^3'.format (dICE_vol_pnd) ) 
    532 echo ( 'dICE_mas_ice   = {:12.3e} m^3'.format (dICE_mas_ice) ) 
    533 echo ( 'dICE_mas_sno   = {:12.3e} m^3'.format (dICE_mas_sno) 
    534 echo ( 'dICE_mas_pnd   = {:12.3e} m^3'.format (dICE_mas_pnd) 
    535 echo ( 'dICE_mas_fzl   = {:12.3e} m^3'.format (dICE_mas_fzl) 
    536 echo ( 'dICE_mas_wat   = {:12.3e} m^3'.format (dICE_mas_wat) )  
     690echo ( 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' ) 
     691echo ( 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' ) 
     692echo ( 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' ) 
     693echo ( 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' ) 
     694 
     695echo ( f'dICE_vol_ice   = {dICE_vol_ice:12.3e} m^3' ) 
     696echo ( f'dICE_vol_sno   = {dICE_vol_sno:12.3e} m^3' ) 
     697echo ( f'dICE_vol_pnd   = {dICE_vol_pnd:12.3e} m^3' ) 
     698echo ( f'dICE_mas_ice   = {dICE_mas_ice:12.3e} m^3' ) 
     699echo ( f'dICE_mas_sno   = {dICE_mas_sno:12.3e} m^3' 
     700echo ( f'dICE_mas_pnd   = {dICE_mas_pnd:12.3e} m^3' 
     701echo ( f'dICE_mas_fzl   = {dICE_mas_fzl:12.3e} m^3' 
     702echo ( f'dICE_mas_wat   = {dICE_mas_wat:12.3e} m^3' )  
    537703 
    538704 
     
    576742 
    577743for k in np.arange (klevp1-1) : 
    578     DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / grav 
    579     DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / grav 
     744    DYN_sigma_beg[k,:] = (DYN_p_beg[k,:] - DYN_p_beg[k+1,:]) / Grav 
     745    DYN_sigma_end[k,:] = (DYN_p_end[k,:] - DYN_p_end[k+1,:]) / Grav 
    580746 
    581747DYN_sigma_beg = DYN_sigma_beg.rename ( {'klevp1':'sigs'} ) 
     
    769935 
    770936echo ('\nLes differents reservoirs') 
    771 echo ( 'SRF_mas_watveg_beg   = {:12.6e} kg | SRF_mas_watveg_end   = {:12.6e} kg '.format (SRF_mas_watveg_beg , SRF_mas_watveg_end) ) 
    772 echo ( 'SRF_mas_watsoil_beg  = {:12.6e} kg | SRF_mas_watsoil_end  = {:12.6e} kg '.format (SRF_mas_watsoil_beg, SRF_mas_watsoil_end) ) 
    773 echo ( 'SRF_mas_snow_beg     = {:12.6e} kg | SRF_mas_snow_end     = {:12.6e} kg '.format (SRF_mas_snow_beg   , SRF_mas_snow_end) ) 
     937echo ( f'SRF_mas_watveg_beg   = {SRF_mas_watveg_beg :12.6e} kg | SRF_mas_watveg_end   = {SRF_mas_watveg_end :12.6e} kg ' ) 
     938echo ( f'SRF_mas_watsoil_beg  = {SRF_mas_watsoil_beg:12.6e} kg | SRF_mas_watsoil_end  = {SRF_mas_watsoil_end:12.6e} kg ' ) 
     939echo ( f'SRF_mas_snow_beg     = {SRF_mas_snow_beg   :12.6e} kg | SRF_mas_snow_end     = {SRF_mas_snow_end   :12.6e} kg ' ) 
    774940 
    775941echo ( '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) ) 
  • TOOLS/WATER_BUDGET/OCE_waterbudget.py

    r6277 r6508  
    2424import numpy as np 
    2525import configparser, re 
    26  
    27 ## Creates parser 
     26from pathlib import Path 
     27 
     28## Import local module 
     29import WaterUtils as wu 
     30 
     31# Check python version 
     32if sys.version_info < (3, 8, 0) : 
     33    print ( f'Python version : {platform.python_version()}' )  
     34    raise Exception ( "Minimum Python version is 3.8" ) 
     35 
     36## Creates parser for reading .ini input file 
    2837config = configparser.ConfigParser() 
    2938config.optionxform = str # To keep capitals 
     
    3342 
    3443## 
    35 ARCHIVE=None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None 
    36 TmpDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 
     44ARCHIVE=None ; STORAGE = None ; SCRATCHDIR=None ; R_IN=None ; rebuild='rebuild_nemo' 
     45TmpDir=None ; RunDir=None ; FileOut=None ; dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None ; FileCommon=None 
    3746file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None ; file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None  
    38 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 
     47tar_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 
    3948file_RUN_beg=None ; file_RUN_end=None ; file_OCE_beg=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 
    40  
    41 # Arguments passed 
     49ContinueOnError=False ; ErrorCount=0 
     50tar_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 
     51tar_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 
     52 
     53# Read command line arguments 
    4254print ( "Name of Python script:", sys.argv[0] ) 
    4355IniFile = sys.argv[1] 
     56# Text existence of IniFile 
     57print ("Input file : ", IniFile ) 
     58 
     59if 'full' in IniFile : FullIniFile = IniFile 
     60else                 : FullIniFile = 'full_' + IniFile 
     61 
    4462print ("Input file : ", IniFile ) 
    4563config.read (IniFile) 
    46 if 'full' in IniFile : FullIniFile = IniFile 
    47 else                 : FullIniFile = 'full_' + IniFile 
    48  
    49 def setBool (chars) : 
    50     '''Convert specific char string in boolean if possible''' 
    51     setBool = chars 
    52     for key in configparser.ConfigParser.BOOLEAN_STATES.keys () : 
    53         if chars.lower() == key : setBool = configparser.ConfigParser.BOOLEAN_STATES[key] 
    54     return setBool 
    55  
    56 def setNum (chars) : 
    57     '''Convert specific char string in integer or real if possible''' 
    58     if type (chars) == str : 
    59         realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$") 
    60         isReal = realnum.match(chars.strip()) != None 
    61         isInt  = chars.strip().isdigit() 
    62         if isReal : 
    63             if isInt : setNum = int   (chars) 
    64             else     : setNum = float (chars) 
    65         else : setNum = chars 
    66     else : setNum = chars 
    67     return setNum 
    68  
    69 def setNone (chars) : 
    70     '''Convert specific char string to None if possible''' 
    71     if type (chars) == str : 
    72         if chars in ['None', 'NONE', 'none'] : setNone = None 
    73         else : setNone = chars 
    74     else : setNone = chars 
    75     return setNone 
    76  
    77 ## Reading config 
     64FullIniFile = 'full_' + IniFile 
     65     
     66## Reading config file 
    7867for Section in ['Experiment', 'libIGCM', 'Files', 'Physics' ] : 
    79     if Section in config.keys() :  
    80         print ( f'[{Section}]' ) 
     68   if Section in config.keys () :  
     69        print ( f'Reading [{Section}]' ) 
    8170        for VarName in config[Section].keys() : 
    8271            locals()[VarName] = config[Section][VarName] 
    83             locals()[VarName] = setBool (locals()[VarName]) 
    84             locals()[VarName] = setNum  (locals()[VarName]) 
     72            exec ( f'{VarName} = wu.setBool ({VarName})' ) 
     73            exec ( f'{VarName} = wu.setNum  ({VarName})' ) 
     74            exec ( f'{VarName} = wu.setNone ({VarName})' ) 
     75            exec ( f'wu.{VarName} = {VarName}' ) 
    8576            print ( '{:25} set to : {:}'.format (VarName, locals()[VarName]) ) 
    86  
     77            #exec ( f'del {VarName}' ) 
     78 
     79#-- Some physical constants 
     80if wu.unDefined ( 'Ra' )           : Ra          = 6366197.7236758135 #-- Earth Radius (m) 
     81if wu.unDefined ( 'Grav' )         : Grav        = 9.81               #-- Gravity (m^2/s 
     82if wu.unDefined ( 'ICE_rho_ice' )  : ICE_rho_ice = 917.0              #-- Ice volumic mass (kg/m3) in LIM3 
     83if wu.unDefined ( 'ICE_rho_sno')   : ICE_rho_sno = 330.0              #-- Snow volumic mass (kg/m3) in LIM3 
     84if wu.unDefined ( 'OCE_rho_liq' )  : OCE_rho_liq = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO 
     85if wu.unDefined ( 'ATM_rho' )      : ATM_rho     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3) 
     86if wu.unDefined ( 'SRF_rho' )      : SRF_rho     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3) 
     87if wu.unDefined ( 'RUN_rho' )      : RUN_rho     = 1000.0             #-- Water volumic mass of rivers (kg/m^3) 
     88if wu.unDefined ( 'ICE_rho_pnd' )  : ICE_rho_pnd = 1000.              #-- Water volumic mass in ice ponds (kg/m^3) 
     89if wu.unDefined ( 'YearLength' )   : YearLength  = 365.25 * 24. * 60. * 60. #-- Year length (s) 
     90 
     91# Set libIGCM and machine dependant values 
    8792if not 'Files' in config.keys() : config['Files'] = {} 
    88  
    89 def unDefined (char) : 
    90     if char in globals () : 
    91         if char == None : return True 
    92         else : return False 
    93     else : return True 
    94  
    95 ##-- Some physical constants 
    96 #-- Earth Radius 
    97 if not 'Ra'            in locals () : Ra = 6366197.7236758135 
    98 #-- Gravity 
    99 if not 'Grav'          in locals () : Grav = 9.81 
    100 #-- Ice volumic mass (kg/m3) in LIM3 
    101 if not 'ICE_rho_ice'   in locals () : ICE_rho_ice = 917.0 
    102 #-- Snow volumic mass (kg/m3) in LIM3 
    103 if not 'ICE_rho_sno'   in locals () : ICE_rho_sno = 330.0 
    104     #-- Water density in ice pounds in SI3 
    105 if not 'ICE_rho_pnd'   in locals () : ICE_rho_pnd = 1000. 
    106 #-- Ocean water volumic mass (kg/m3) in NEMO 
    107 if not 'OCE_rho_liq'   in locals () : OCE_rho_liq = 1026. 
    108 #-- Water volumic mass in atmosphere 
    109 if not 'ATM_rho'       in locals () : ATM_rho = 1000. 
    110 #-- Water volumic mass in surface reservoirs 
    111 if not 'SRF_rho'       in locals () : SRF_rho = 1000. 
    112 #-- Water volumic mass of rivers 
    113 if not 'RUN_rho'       in locals () : RUN_rho = 1000. 
    114 #-- Year length 
    115 if not 'YearLength'    in locals () : YearLength = 365.25 * 24. * 60. * 60. 
    116  
    117 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, 
    118                           'ATM_rho':ATM_rho, 'SRF_rho':SRF_rho, 'RUN_rho':RUN_rho} 
     93     
     94config['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} 
    11995         
    120  
    121  
    122 # Where do we run ? 
    123 SysName, NodeName, Release, Version, Machine = os.uname() 
    124 TGCC  = ( 'irene'   in NodeName ) 
    125 IDRIS = ( 'jeanzay' in NodeName ) 
    126  
    127 ## Set site specific libIGCM directories, and other specific stuff 
    128 if TGCC : 
    129     CPU = subprocess.getoutput ( 'lscpu | grep "Model name"' ) 
    130     if "Intel(R) Xeon(R) Platinum" in CPU : Machine = 'irene' 
    131     if "AMD"                       in CPU : Machine = 'irene-amd' 
    132          
    133     ARCHIVE     = subprocess.getoutput ( f'ccc_home --cccstore   -d {Project} -u {User}' ) 
    134     STORAGE     = subprocess.getoutput ( f'ccc_home --cccwork    -d {Project} -u {User}' ) 
    135     SCRATCHDIR  = subprocess.getoutput ( f'ccc_home --cccscratch -d {Project} -u {User}' ) 
    136     R_IN        = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg'), 'IGCM') 
    137     rebuild     = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg'), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' ) 
    138  
    139     ## Specific to run at TGCC. 
    140     # Needed before importing a NetCDF library (netCDF4, xarray, cmds, etc ...) 
    141     import mpi4py 
    142     mpi4py.rc.initialize = False 
    143          
    144     ## Creates output directory 
    145     TmpDir = os.path.join ( subprocess.getoutput ( 'ccc_home --cccscratch' ), f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
    146  
    147 if IDRIS : 
    148     raise Exception ("Pour IDRIS : repertoires et chemins a definir")  
    149  
    150 config['System'] = {'SysName':SysName, 'NodeName':NodeName, 'Release':Release, 'Version':Version,'Machine':Machine, 'TGCC':TGCC,'IDRIS':IDRIS, 'CPU':CPU, 
    151                     'Program'  : "Generated by : " + str(sys.argv),  
    152                     'HOSTNAME' : platform.node (), 'LOGNAME'  : os.getlogin (), 
    153                     'Python'   : f'{platform.python_version ()}', 
    154                     'OS'       : f'{platform.system ()} release : {platform.release ()} hardware : {platform.machine ()}', 
    155                     'SVN_Author'   : "$Author$",  
    156                     'SVN_Date'     : "$Date$", 
    157                     'SVN_Revision' : "$Revision$", 
    158                     'SVN_Id'       : "$Id$", 
    159                     'SVN_HeadURL'  : "$HeadURL$"} 
     96with open ('SetLibIGCM.py') as f: exec ( f.read() ) 
     97config['Files']['TmpDir'] = TmpDir 
    16098 
    16199if libIGCM : 
     
    167105import xarray as xr 
    168106     
    169 # Output file 
    170 if FileOut == None :  
    171     FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
    172     config['Files']['FileOut'] = FileOut 
     107# Output file with water budget diagnostics 
     108if wu.unDefined ( 'FileOut' ) : FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}.out' 
     109config['Files']['FileOut'] = FileOut 
    173110 
    174111f_out = open ( FileOut, mode = 'w' ) 
    175      
    176 # Function to print to stdout *and* output file 
     112 
     113# Useful functions 
     114def kg2Sv    (val, rho=ATM_rho) : 
     115    '''From kg to Sverdrup''' 
     116    return val/dtime_sec*1.0e-6/rho 
     117 
     118def kg2myear (val, rho=ATM_rho) : 
     119    '''From kg to m/year''' 
     120    return val/ATM_aire_sea_tot/rho/NbYear 
     121 
     122def var2prt (var, small=False, rho=ATM_rho) : 
     123    if small :  return var , kg2Sv(var, rho=rho)*1000., kg2myear(var, rho=rho)*1000. 
     124    else     :  return var , kg2Sv(var, rho=rho)      , kg2myear(var, rho=rho) 
     125 
     126def prtFlux (Desc, var, Form='F', small=False, rho=ATM_rho, width=15) : 
     127    if small : 
     128        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
     129        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} mSv | {:12.4e} mm/year " 
     130    else : 
     131        if Form in ['f', 'F'] : ff=" {:12.4e} kg | {:12.4f} Sv  | {:12.4f} m/year  " 
     132        if Form in ['e', 'E'] : ff=" {:12.4e} kg | {:12.4e} Sv  | {:12.4e} m/year  " 
     133    echo ( (' {:>{width}} = ' +ff).format (Desc, *var2prt(var, small, rho=rho), width=width ) ) 
     134    return None 
     135 
    177136def echo (string, end='\n') : 
     137    '''Function to print to stdout *and* output file''' 
    178138    print ( str(string), end=end  ) 
    179139    sys.stdout.flush () 
     
    182142    return None 
    183143     
    184 ## Set libIGCM directories 
    185 R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT') 
    186 R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT') 
    187  
    188 L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    189 R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    190 R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    191 POST_DIR    = os.path.join ( R_BUF, L_EXP, 'Out' ) 
    192 REBUILD_DIR = os.path.join ( R_BUF, L_EXP, 'REBUILD' ) 
    193 R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    194 R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    195      
    196 #if os.path.isdir (TmpDir) : shutil.rmtree ( TmpDir ) 
    197 if not os.path.isdir (TmpDir) : os.mkdir (TmpDir) 
    198 TmpDirOCE = os.path.join (TmpDir, 'OCE') 
    199 TmpDirICE = os.path.join (TmpDir, 'ICE') 
    200 if not os.path.exists (TmpDirOCE) : os.mkdir (TmpDirOCE ) 
    201 if not os.path.exists (TmpDirICE) : os.mkdir (TmpDirICE ) 
     144### Set libIGCM directories 
     145if wu.unDefined ('R_OUT'      ) : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
     146if wu.unDefined ('R_BUF'      ) : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
     147if wu.unDefined ('L_EXP'      ) : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
     148if wu.unDefined ('R_SAVE'     ) : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
     149if wu.unDefined ('R_BUFR'     ) : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
     150if wu.unDefined ('POST_DIR'   ) : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
     151if wu.unDefined ('REBUILD_DIR') : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' ) 
     152if wu.unDefined ('R_BUF_KSH'  ) : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
     153if wu.unDefined ('R_FIGR'     ) : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
     154 
     155config['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 } 
     156 
     157# Set directory to extract files 
     158if wu.unDefined ( 'RunDir' ) : RunDir = os.path.join ( TmpDir, f'WATER_{JobName}_{YearBegin}_{YearEnd}' ) 
     159config['Files']['RunDir'] = RunDir 
     160 
     161if not os.path.isdir (RunDir) : os.makedirs (RunDir) 
     162 
     163# Set directories to rebuild ocean and ice restart files 
     164RunDirOCE = os.path.join (RunDir, 'OCE') 
     165RunDirICE = os.path.join (RunDir, 'ICE') 
     166if not os.path.exists (RunDirOCE) : os.mkdir (RunDirOCE ) 
     167if not os.path.exists (RunDirICE) : os.mkdir (RunDirICE ) 
    202168 
    203169echo (' ') 
    204 echo ( f'JobName : {JobName}' ) 
    205 echo (Comment) 
    206 echo ( f'Working in TMPDIR : {TmpDir}' ) 
    207  
    208 echo ( f'\nDealing with {L_EXP}' ) 
    209  
    210 #-- Model output directories 
    211 if Freq == "MO" : FreqDir =  os.path.join ('Output' , 'MO' ) 
    212 if Freq == "SE" : FreqDir =  os.path.join ('Analyse', 'SE' ) 
    213 if dir_OCE_his == None : 
     170echo ( f'JobName   : {JobName}'   ) 
     171echo ( f'Comment   : {Comment}'   ) 
     172echo ( f'TmpDir    : {TmpDir}'    ) 
     173echo ( f'RunDirOCE : {RunDirOCE}' ) 
     174echo ( f'RunDirICE : {RunDirICE}' ) 
     175 
     176echo ( f'\nDealing with {L_EXP}'  ) 
     177 
     178#-- Creates model output directory names 
     179if Freq == "MO" : FreqDir = os.path.join ( 'Output' , 'MO' ) 
     180if Freq == "SE" : FreqDir = os.path.join ( 'Analyse', 'SE' ) 
     181if wu.unDefined ( 'dir_OCE_his' ) : 
    214182    dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) 
    215183    config['Files']['dir_OCE_his'] = dir_OCE_his 
    216 if dir_ICE_his == None : 
     184if wu.unDefined ( 'dir_ICE_his' ) : 
    217185    dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) 
    218186    config['Files']['dir_OCE_his'] = dir_OCE_his 
     
    222190echo ( f'{dir_ICE_his}' ) 
    223191 
    224 #-- Files Names 
    225 if Period == None : 
     192#-- Creates files names 
     193if wu.unDefined ( 'Period ' ) : 
    226194    if Freq == 'MO' : Period = f'{YearBegin}0101_{YearEnd}1231_1M' 
    227195    if Freq == 'SE' : Period = f'SE_{YearBegin}0101_{YearEnd}1231_1M' 
    228196    config['Files']['Period'] = Period 
    229 if FileCommon == None : 
     197if wu.unDefined ( 'FileCommon' ) : 
    230198    FileCommon = f'{JobName}_{Period}' 
    231199    config['Files']['FileCommon'] = FileCommon 
    232200 
    233 if Title == None : 
     201if wu.unDefined ( 'Title' ) : 
    234202    Title = f'{JobName} : {Freq} : {YearBegin}-01-01 - {YearEnd}-12-31' 
    235203    config['Files']['Title'] = Title 
     
    237205         
    238206echo ('\nOpen history files' ) 
    239 if file_OCE_his == None : 
     207if wu.unDefined ('file_OCE_his' ) : 
    240208    file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
    241209    file_OCE_his = file_OCE_his 
    242 if file_OCE_sca == None :     
     210if wu.unDefined ('file_OCE_sca' ) :     
    243211    file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' ) 
    244212    config['Files']['file_OCE_sca'] = file_OCE_sca 
    245 if file_ICE_his == None :  
     213if wu.unDefined ( 'file_ICE_hi' ) :  
    246214    file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' ) 
    247215    config['Files']['file_ICE_his'] = file_ICE_his 
     
    258226## Compute run length 
    259227dtime = ( d_OCE_his.time_counter_bounds.max() - d_OCE_his.time_counter_bounds.min() ) 
    260 echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) ) 
     228echo ( f'\nRun length : {(dtime/np.timedelta64(1, "D")).values:8.2f} days' ) 
    261229dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds 
    262230 
    263231## Compute length of each period 
    264232dtime_per = ( d_OCE_his.time_counter_bounds[:,-1] - d_OCE_his.time_counter_bounds[:,0] ) 
    265 echo ('\nPeriods lengths (days) : ') 
    266 echo (' {:}'.format ( (dtime_per/np.timedelta64(1, "D")).values ) ) 
     233echo ( f'\nPeriods lengths (days) : ') 
     234echo ( f' {(dtime_per/np.timedelta64(1, "D")).values}' ) 
    267235dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds 
    268236dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_OCE_his.time_counter,] ) 
     
    271239## Number of years 
    272240NbYear = dtime_sec / YearLength 
     241 
    273242#-- Open restart files 
    274243YearRes = YearBegin - 1              # Year of the restart of beginning of simulation 
     
    277246echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
    278247 
    279 if TarRestartPeriod_beg == None :  
     248if wu.unDefined ( 'TarRestartPeriod_beg' ) :  
    280249    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
    281250    TarRestartPeriod_beg = f'{YearPre}0101_{YearRes}1231' 
    282251    config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg 
    283252 
    284 if TarRestartPeriod_end == None :  
     253if wu.unDefined ( 'TarRestartPeriod_end' ) :  
    285254    YearPre = YearBegin - PackFrequency  # Year to find the tarfile of the restart of beginning of simulation 
    286255    echo (f'Restart dates - Start : {YearRes}-12-31  /  End : {YearEnd}-12-31 ') 
     
    288257    config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end 
    289258 
    290 if file_restart_beg == None : 
    291     file_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
    292     config['Files']['file_restart_beg'] = file_restart_beg 
    293 if file_restart_end == None : 
    294     file_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
    295     config['Files']['file_restart_end'] = file_restart_end 
    296  
    297 echo ( f'{file_restart_beg}' ) 
    298 echo ( f'{file_restart_end}' ) 
    299  
    300 if file_OCE_beg == None :  
    301     file_OCE_beg = f'{TmpDir}/OCE_{JobName}_{YearRes}1231_restart.nc' 
     259if wu.unDefined ( 'tar_restart_beg' ) : 
     260    tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
     261    config['Files']['tar_restart_beg'] = tar_restart_beg 
     262if wu.unDefined ( 'tar_restart_end' ) : 
     263    tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
     264    config['Files']['tar_restart_end'] = tar_restart_end 
     265 
     266echo ( f'{tar_restart_beg}' ) 
     267echo ( f'{tar_restart_end}' ) 
     268 
     269# 
     270if wu.unDefined ('tar_restart_beg_ATM' ) : tar_restart_beg_ATM = tar_restart_beg 
     271if wu.unDefined ('tar_restart_beg_DYN' ) : tar_restart_beg_DYN = tar_restart_beg 
     272if wu.unDefined ('tar_restart_beg_SRF' ) : tar_restart_beg_SRF = tar_restart_beg 
     273if wu.unDefined ('tar_restart_beg_RUN' ) : tar_restart_beg_RUN = tar_restart_beg 
     274if wu.unDefined ('tar_restart_beg_OCE' ) : tar_restart_beg_OCE = tar_restart_beg 
     275if wu.unDefined ('tar_restart_beg_ICE' ) : tar_restart_beg_ICE = tar_restart_beg 
     276 
     277if wu.unDefined ('tar_restart_end_ATM' ) : tar_restart_end_ATM = tar_restart_end 
     278if wu.unDefined ('tar_restart_end_DYN' ) : tar_restart_end_DYN = tar_restart_end 
     279if wu.unDefined ('tar_restart_end_SRF' ) : tar_restart_end_SRF = tar_restart_end 
     280if wu.unDefined ('tar_restart_end_RUN' ) : tar_restart_end_RUN = tar_restart_end 
     281if wu.unDefined ('tar_restart_end_OCE' ) : tar_restart_end_OCE = tar_restart_end 
     282if wu.unDefined ('tar_restart_end_ICE' ) : tar_restart_end_ICE = tar_restart_end 
     283 
     284if wu.unDefined ( 'file_OCE_beg' ) :  
     285    file_OCE_beg = f'{RunDir}/OCE_{JobName}_{YearRes}1231_restart.nc' 
    302286    config['Files']['file_OCE_beg'] = file_OCE_beg 
    303 if file_OCE_end == None : 
    304     file_OCE_end = f'{TmpDir}/OCE_{JobName}_{YearEnd}1231_restart.nc' 
     287if wu.unDefined ( 'file_OCE_end' ) : 
     288    file_OCE_end = f'{RunDir}/OCE_{JobName}_{YearEnd}1231_restart.nc' 
    305289    config['Files']['file_OCE_end'] = file_OCE_end 
    306 if file_ICE_beg == None : 
    307     file_ICE_beg = f'{TmpDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc' 
     290if wu.unDefined ( 'file_ICE_beg' ) : 
     291    file_ICE_beg = f'{RunDir}/ICE_{JobName}_{YearRes}1231_restart_icemod.nc' 
    308292    config['Files']['file_ICE_beg'] = file_ICE_beg 
    309 if file_ICE_end == None :  
    310     file_ICE_end = f'{TmpDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc' 
     293if wu.unDefined ( 'file_ICE_end' ) :  
     294    file_ICE_end = f'{RunDir}/ICE_{JobName}_{YearEnd}1231_restart_icemod.nc' 
    311295    config['Files']['file_ICE_end'] = file_ICE_end 
    312296 
     
    321305    #ndomain_opa = d_zfile.attrs['DOMAIN_number_total'] 
    322306    #d_zfile.close () 
    323     ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ).format() 
     307    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format() 
    324308    return int (ndomain_opa) 
    325309 
    326 if not os.path.exists ( file_OCE_beg) : 
    327     echo ( f'Extracting {file_OCE_beg}' ) 
    328     base_file_OCE_beg = os.path.basename (file_OCE_beg) 
    329     if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart_0000.nc') ) : 
    330         command =  f'cd {TmpDirOCE} ; tar xf {file_restart_beg}  OCE_{JobName}_{YearRes}1231_restart_*.nc' 
    331         echo ( command ) 
    332         os.system ( command ) 
    333     echo ('extract ndomain' ) 
    334     ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearRes}1231_restart') ) 
    335     command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearRes}1231_restart {ndomain_opa} ; mv {base_file_OCE_beg} {TmpDir}' 
    336     echo ( command ) 
    337     os.system ( command ) 
    338     echo ( f'Rebuild done : {file_OCE_beg}') 
    339      
    340 if not os.path.exists ( file_OCE_end) : 
    341     echo ( f'Extracting {file_OCE_end}' ) 
    342     base_file_OCE_end = os.path.basename (file_OCE_end) 
    343     if not os.path.exists ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart_0000.nc') ): 
    344         command =  f'cd {TmpDirOCE} ; tar xf {file_restart_end}  OCE_{JobName}_{YearEnd}1231_restart_*.nc' 
    345         echo ( command ) 
    346         os.system ( command ) 
    347     echo ('extract ndomain' ) 
    348     ndomain_opa = get_ndomain ( os.path.join (TmpDirOCE, f'OCE_{JobName}_{YearEnd}1231_restart') ) 
    349     command = f'cd {TmpDirOCE} ; {rebuild} OCE_{JobName}_{YearEnd}1231_restart {ndomain_opa} ; mv {base_file_OCE_end} {TmpDir}' 
    350     echo ( command ) 
    351     os.system ( command ) 
    352     echo ( f'Rebuild done : {file_OCE_end}') 
    353  
    354 if not os.path.exists ( file_ICE_beg) : 
    355     echo ( f'Extracting {file_ICE_beg}' ) 
    356     base_file_ICE_beg = os.path.basename (file_ICE_beg) 
    357     if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod_0000.nc') ): 
    358         command =  f'cd {TmpDirICE} ; tar xf {file_restart_beg}  ICE_{JobName}_{YearRes}1231_restart_icemod_*.nc' 
    359         echo ( command ) 
    360         os.system ( command ) 
    361     echo ('extract ndomain' ) 
    362     ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) 
    363     command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearRes}1231_restart_icemod {ndomain_opa} ; mv {base_file_ICE_beg} {TmpDir} ' 
    364     echo ( command ) 
    365     os.system ( command ) 
    366     echo ( f'Rebuild done : {file_OCE_beg}') 
    367      
    368 if not os.path.exists ( file_ICE_end ) : 
    369     echo ( f'Extracting {file_ICE_end}' ) 
    370     base_file_ICE_end = os.path.basename (file_ICE_end) 
    371     if not os.path.exists ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearEnd}1231_restart_icemod_0000.nc') ): 
    372         command =  f'cd {TmpDirICE} ; tar xf {file_restart_end} ICE_{JobName}_{YearEnd}1231_restart_icemod_*.nc' 
    373         echo ( command ) 
    374         os.system ( command ) 
    375     echo ('extract ndomain' ) 
    376     ndomain_opa = get_ndomain ( os.path.join (TmpDirICE, f'ICE_{JobName}_{YearRes}1231_restart_icemod') ) 
    377     command = f'cd {TmpDirICE} ; {rebuild} ICE_{JobName}_{YearEnd}1231_restart_icemod {ndomain_opa} ; mv {base_file_ICE_end} {TmpDir}' 
    378     echo ( command ) 
    379     os.system ( command ) 
    380     echo ( f'Rebuild done : {file_ICE_end}') 
     310def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, RunDirComp=RunDirOCE, ErrorCount=ErrorCount ) : 
     311    '''Extract restart file from tar. Rebuild ocean files if needed''' 
     312    echo ( f'----------') 
     313    if os.path.exists ( file_name ) : 
     314        echo ( f'-- File ready : {file_name = }' ) 
     315    else :  
     316        echo ( f'-- Extracting {file_name = }' ) 
     317        base_resFile = Path (file_name).stem # basename, and remove suffix 
     318        # Try to extract the rebuilded file 
     319        if os.path.exists ( tar_restart ) : 
     320            command =  f'cd {RunDirComp} ; tar xf {tar_restart} {base_resFile}.nc' 
     321            echo ( command ) 
     322            try :  
     323                os.system ( command ) 
     324            except : 
     325                if not os.path.exists ( os.path.join (RunDir, f'{base_resFile}_0000.nc') ): 
     326                    command =  f'cd {RunDirComp} ; tar xf {tar_restart_end} {base_file}_*.nc' 
     327                    echo ( command ) 
     328                    ierr = os.system ( command ) 
     329                    if ierr == 0 : echo ( f'tar done : {base_resFile}.nc') 
     330                    else         : raise Exception ( f'command failed : {command}' ) 
     331                    echo ( f'extract ndomain' ) 
     332                ndomain_opa = get_ndomain ( os.path.join (RunDir, f'{base_file}') ) 
     333                command = f'cd {RunDirComp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {RunDir}' 
     334                echo ( command ) 
     335                ierr = os.system ( command ) 
     336                if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc') 
     337                else         : raise Exception ( f'command failed : {command}' ) 
     338            else :  
     339                echo ( f'tar done : {base_resFile}') 
     340                command = f'cd {RunDirComp} ; mv {base_resFile}.nc {RunDir}' 
     341                ierr = os.system ( command ) 
     342                if ierr == 0 : echo ( f'command done : {command}' ) 
     343                else         : raise Exception ( f'command failed : {command = }' )                    
     344        else : 
     345            echo ( f'****** Tar restart file {tar_restart = } not found ' ) 
     346            if ContinueOnError : 
     347                ErrorCount += 1 
     348            else :  
     349                raise Exception ( f'****** tar file not found {tar_restart = } - Stopping' ) 
     350    return ErrorCount 
     351 
     352             
     353ErrorCount += extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirOCE ) 
     354ErrorCount += extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, RunDirComp=RunDirOCE ) 
     355ErrorCount += extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, RunDirComp=RunDirICE ) 
     356ErrorCount += extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, RunDirComp=RunDirICE ) 
    381357 
    382358echo ('Opening OCE and ICE restart files') 
    383359if NEMO == 3.6 :  
    384     d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    385     d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze() 
    386     d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze() 
    387     d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze() 
     360    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     361    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True).squeeze() 
     362    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True).squeeze() 
     363    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True).squeeze() 
    388364if NEMO == 4.0 or NEMO == 4.2 :  
    389     d_OCE_beg = xr.open_dataset ( os.path.join (TmpDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    390     d_OCE_end = xr.open_dataset ( os.path.join (TmpDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    391     d_ICE_beg = xr.open_dataset ( os.path.join (TmpDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    392     d_ICE_end = xr.open_dataset ( os.path.join (TmpDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    393  
    394 ## 
     365    d_OCE_beg = xr.open_dataset ( os.path.join (RunDir, file_OCE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     366    d_OCE_end = xr.open_dataset ( os.path.join (RunDir, file_OCE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     367    d_ICE_beg = xr.open_dataset ( os.path.join (RunDir, file_ICE_beg), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     368    d_ICE_end = xr.open_dataset ( os.path.join (RunDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
     369 
     370## Write the full configuration 
    395371config_out = open (FullIniFile, 'w') 
    396372config.write (config_out ) 
     
    473449    OCE_sum_e3tn_end = OCE_stock_int ( OCE_e3tn_end * OCE_msk3) 
    474450 
    475 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) ) 
     451echo ( 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' ) 
    476452dOCE_ssh_vol = ( OCE_sum_ssh_end - OCE_sum_ssh_beg ) 
    477453dOCE_ssh_mas = dOCE_ssh_vol * OCE_rho_liq 
    478454 
    479455if NEMO == 3.6 : 
    480     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) ) 
     456    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' ) 
    481457    dOCE_e3tn_vol = ( OCE_sum_e3tn_end - OCE_sum_e3tn_beg ) 
    482458    dOCE_e3tn_mas = dOCE_e3tn_vol * OCE_rho_liq 
     
    484460dOCE_vol_wat = dOCE_ssh_vol ; dOCE_mas_wat = dOCE_ssh_mas 
    485461 
    486 echo ( 'dOCE vol    = {:12.3e} m^3'.format ( dOCE_vol_wat) ) 
    487 echo ( 'dOCE ssh    = {:12.3e} m  '.format ( dOCE_vol_wat/OCE_aire_tot) ) 
     462echo ( f'dOCE vol    = {dOCE_vol_wat             :12.3e} m^3' ) 
     463echo ( f'dOCE ssh    = {dOCE_vol_wat/OCE_aire_tot:12.3e} m  ' ) 
    488464prtFlux ( 'dOCE mass ', dOCE_mas_wat, 'e' ) 
    489465 
    490466if NEMO == 3.6 : 
    491     echo ( 'dOCE e3tn   vol    = {:12.3e} m^3'.format ( dOCE_e3tn_vol) ) 
     467    echo ( f'dOCE e3tn   vol    = {dOCE_e3tn_vol:12.3e} m^3' ) 
    492468    prtFlux ( 'dOCE e3tn   mass', dOCE_e3tn_mas, 'e' ) 
    493469 
     
    547523    dSEA_mas_wat = dOCE_mas_wat + dICE_mas_wat 
    548524 
    549 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) ) 
    550 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) ) 
    551 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) ) 
    552 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) ) 
    553  
    554 echo ( 'dICE_vol_ice   = {:12.3e} m^3'.format (dICE_vol_ice) ) 
    555 echo ( 'dICE_vol_sno   = {:12.3e} m^3'.format (dICE_vol_sno) ) 
    556 echo ( 'dICE_vol_pnd   = {:12.3e} m^3'.format (dICE_vol_pnd) ) 
    557 echo ( 'dICE_mas_ice   = {:12.3e} m^3'.format (dICE_mas_ice) ) 
    558 echo ( 'dICE_mas_sno   = {:12.3e} m^3'.format (dICE_mas_sno) 
    559 echo ( 'dICE_mas_pnd   = {:12.3e} m^3'.format (dICE_mas_pnd) 
    560 echo ( 'dICE_mas_fzl   = {:12.3e} m^3'.format (dICE_mas_fzl) 
     525echo ( 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' ) 
     526echo ( 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' ) 
     527echo ( 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' ) 
     528echo ( 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' ) 
     529 
     530echo ( f'dICE_vol_ice   = {dICE_vol_ice:12.3e} m^3' ) 
     531echo ( f'dICE_vol_sno   = {dICE_vol_sno:12.3e} m^3' ) 
     532echo ( f'dICE_vol_pnd   = {dICE_vol_pnd:12.3e} m^3' ) 
     533echo ( f'dICE_mas_ice   = {dICE_mas_ice:12.3e} m^3' ) 
     534echo ( f'dICE_mas_sno   = {dICE_mas_sno:12.3e} m^3' 
     535echo ( f'dICE_mas_pnd   = {dICE_mas_pnd:12.3e} m^3' 
     536echo ( f'dICE_mas_fzl   = {dICE_mas_fzl:12.3e} m^3' 
    561537 
    562538echo ( '\n------------------------------------------------------------') 
    563 echo ( 'Variation du contenu en eau ocean + glace ' ) 
     539echo ( 'Change in water content (ocean + ice) ' ) 
    564540prtFlux ( 'dMass (ocean)', dSEA_mas_wat, 'e', True ) 
    565541 
     
    584560 
    585561echo ( '\n------------------------------------------------------------------------------------' ) 
    586 echo ( '-- Checks in NEMO - from budget_modipsl.sh (Clement Rousset)' ) 
     562echo ( '-- Checks in NEMO - from budget_modipsl.sh (Clément Rousset)' ) 
    587563 
    588564# Read variable and computes integral over space and time 
     
    658634prtFlux ('  WFXSNW_PRE   ', ICE_mas_wfxsnw_pre, 'e', True) 
    659635prtFlux ('  WFXSUB_ERR   ', ICE_mas_wfxsub_err, 'e', True) 
    660 prtFlux ('  EVAP_OCE     ', OCE_mas_evap_oce  , 'e' ) 
     636prtFlux ('  EVAP_OCE     ', OCE_mas_evap_oce  , 'e'      ) 
    661637prtFlux ('  EVAP_ICE     ', ICE_mas_evap_ice  , 'e', True) 
    662638prtFlux ('  SNOW_OCE     ', OCE_mas_snow_oce  , 'e', True) 
    663639prtFlux ('  SNOW_ICE     ', OCE_mas_snow_ice  , 'e', True) 
    664 prtFlux ('  RAIN         ', OCE_mas_rain      , 'e' ) 
     640prtFlux ('  RAIN         ', OCE_mas_rain      , 'e'      ) 
    665641prtFlux ('  FWB          ', OCE_mas_fwb       , 'e', True) 
    666642prtFlux ('  SSR          ', OCE_mas_ssr       , 'e', True) 
     
    705681 
    706682echo ( '\n------------------------------------------------------------------------------------' ) 
    707 echo ( '-- Calculs dans la note PDF de Clement') 
     683echo ( '-- Computations in the PDF note of Clément Rousset') 
    708684echo ( '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 )) 
    709685echo ( '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 )) 
  • TOOLS/WATER_BUDGET/lmdz.py

    r6265 r6508  
    238238    if math == xr : 
    239239        p2D = xr.DataArray (p2D) 
    240         p2D.attrs = p1D.attrs 
     240        for attr in p1D.attrs :  
     241            p2D.attrs[attr] = p1D.attrs[attr] 
    241242        p2D = p2D.rename ( {p2D.dims[0]:p1D.dims[0], p2D.dims[-1]:'x', p2D.dims[-2]:'y'} ) 
    242243         
    243244    return p2D 
    244245 
    245 def geo2point ( p2D, cumulPoles=False, dim1D='points_physiques' ) :  
     246def geo2point ( p2D, cumulPoles=False, dim1D='cell', debug=False ) :  
    246247    ''' 
    247248    From 2D (lat, lon) to 1D (points_phyiques) 
     
    259260 
    260261    jpn = jpi*(jpj-2) + 2 
     262 
     263    if debug : 
     264        print ( f'{jpi=} {jpj=} {jpn=} {jpt=}' ) 
    261265 
    262266    if jpt == -1 : 
     
    277281    if math == xr : 
    278282        p1D       = xr.DataArray (p1D) 
    279         p1D.attrs = p2D.attrs 
     283        for attr in p2D.attrs : 
     284            p1D.attrs[attr] = p2D.attrs[attr] 
    280285        p1D       = p1D.rename ( {p1D.dims[0]:p2D.dims[0], p1D.dims[-1]:dim1D} ) 
    281286 
     
    286291    return p1D 
    287292 
    288 def geo3point ( p3D, cumulPoles=False, dim1D='points_physiques' ) :  
     293def geo3point ( p3D, cumulPoles=False, dim1D='cell' ) :  
    289294    ''' 
    290295    From 3D (lev, lat, lon) to 2D (lev, points_phyiques) 
     
    314319    if math == xr : 
    315320        p2D       = xr.DataArray (p2D) 
    316         p2D.attrs = p3D.attrs 
     321        for attr in p2D.attrs :  
     322            p2D.attrs[attr] = p3D.attrs[attr] 
    317323        p2D       = p2D.rename ( {p2D.dims[-1]:dim1D, p2D.dims[-2]:p3D.dims[-3]} ) 
    318324         
Note: See TracChangeset for help on using the changeset viewer.