Changeset 6676 for TOOLS


Ignore:
Timestamp:
11/15/23 16:41:21 (5 months ago)
Author:
omamce
Message:

O.M. : WATER_BUDGET

Code restructuration

Location:
TOOLS/WATER_BUDGET
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • TOOLS/WATER_BUDGET/ATM_waterbudget.py

    r6665 r6676  
    3333## Import local modules 
    3434import WaterUtils as wu 
    35 import libIGCM_sys 
    3635import lmdz 
    37  
    38 from WaterUtils import RA, GRAV, ICE_RHO_ICE, ICE_RHO_SNO, \ 
    39                        OCE_RHO_LIQ, ATM_RHO, SRF_RHO, RUN_RHO, ICE_RHO_PND, YEAR_LENGTH 
    40  
    41 ## Creates parser for reading .ini input file 
    42 ## ------------------------------------------- 
    43 config = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
    44 config.optionxform = str # To keep capitals 
    45  
    46 ## Experiment parameters 
    47 ## --------------------- 
    48 JobName=None ; TagName=None ; ExperimentName=None ; SpaceName=None 
    49 SRF=True ; RUN=True 
    50 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None 
    51 NEMO=None ; OCE_relax=False 
    52 OCE_icb=False ; Coupled=False ; Rsouting=None ; TestInterp=None 
    53 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None 
    54 Period=None ; Title=None 
    55 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 
    56 Freq=None ; libIGCM=None ; User=None; Group=None ; Routing=None 
    57 PackFrequency = None ; FreqDir=None 
    58  
    59 Timer=False ; Debug=False 
    60 ## 
    61 ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None 
    62 TmpDir=None ; FileDir=None ; FileOut=None ; R_OUT=None ; R_FIG=None 
    63 R_FIGR=None ; R_BUF=None ; R_BUFR=None ; R_SAVE=None 
    64 R_BUF_KSH=None ; POST_DIR=None ; L_EXP=None 
    65  
    66 dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None 
    67 FileCommon=None ; file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None 
    68 file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None 
    69 tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None 
    70 file_ATM_end=None ; file_DYN_beg=None 
    71 file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None 
    72 file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None 
    73 file_ICE_beg=None ; file_OCE_beg=None 
    74 file_OCE_end=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 
    75 TarRestartDate_beg=None ; TarRestartDate_end=None 
    76 file_DYN_aire=None 
    77 tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None 
    78 tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None 
    79 tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None 
    80 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 
    81 ContinueOnError=False ; ErrorCount=0 ; SortIco = False 
    82  
    83 FileDirOCE=None ; FileDirATM=None ; FileDirICE=None ; FileDirSRF=None ; FileDirRUN=None 
    84  
    85 ## 
    86 ## Precision of history file reading 
    87 ## --------------------------------- 
    88 # Default is float (full precision). Degrade the precision by using np.float32 
    89 # Restart files are always read at the full precision 
    90 readPrec=float 
    9136 
    9237## Read command line arguments 
     
    9944    raise FileExistsError ( f"File not found : {IniFile = }" ) 
    10045 
    101 if 'full' in IniFile : FullIniFile = IniFile 
    102 else                 : FullIniFile = 'full_' + IniFile 
    103  
    104 print ("Input file : ", IniFile ) 
    105 config.read (IniFile) 
    106 FullIniFile = 'full_' + IniFile 
    107  
    108 ## Reading config.card if possible 
    109 ## ------------------------------- 
    110 ConfigCard = None 
    111  
    112 if 'Experiment' in config.keys ()  : ## Read Experiment on Config file if possible 
    113     if 'ConfigCard' in config['Experiment'].keys () : 
    114         ConfigCard = config['Experiment']['ConfigCard'] 
    115         print ( f'{ConfigCard=}' ) 
    116  
    117 if ConfigCard : ## Read config card if it exists 
    118     # Text existence of ConfigCard 
    119     if os.path.exists ( ConfigCard ) : 
    120         print ( f'Reading Config Card : {ConfigCard}' ) 
    121         ## Creates parser for reading .ini input file 
    122         MyReader = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    123         MyReader.optionxform = str # To keep capitals 
    124  
    125         MyReader.read (ConfigCard) 
    126  
    127         for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName'] : 
    128             if VarName in MyReader['UserChoices'].keys() : 
    129                 locals()[VarName] = MyReader['UserChoices'][VarName] 
    130                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    131                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    132                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    133                 exec  ( f'wu.{VarName} = {VarName}' ) 
    134                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    135  
    136         for VarName in ['PackFrequency'] : 
    137             if VarName in MyReader['Post'].keys() : 
    138                 locals()[VarName] = MyReader['Post'][VarName] 
    139                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    140                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    141                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    142                 exec  ( f'wu.{VarName} = {VarName}' ) 
    143                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    144     else : 
    145         raise FileExistsError ( f"File not found : {ConfigCard = }" ) 
    146  
    147 ## Reading config file 
    148 ## ------------------- 
    149 # Each entry in the .ini file will create a Python variable with the same name 
    150 for Section in config.keys () :  
    151     print ( f'\nReading [{Section}]' ) 
    152     for VarName in config[Section].keys() : 
    153         locals()[VarName] = config[Section][VarName] 
    154         exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    155         exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    156         exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    157         exec  ( f'wu.{VarName} = {VarName}' ) 
    158         print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
    159  
    160 print ( f'\nConfig file readed : {IniFile} ' ) 
    161  
    162 ## 
    163 ## Reading prec 
    164 if readPrec : 
    165     readPrec = np.float64 
     46if 'full' in IniFile or 'ATM' in IniFile : 
     47    FullIniFile = IniFile 
    16648else : 
    167     if readPrec in ["float", "float64", "r8", "double", "<class 'float'>"         ] : readPrec = float 
    168     if readPrec in [         "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 
    169     if readPrec in [         "float16", "r2", "half"  , "<class 'numpy.float16'>" ] : readPrec = np.float16 
    170  
    171 ## Some physical constants 
    172 ## ======================= 
    173 if not RA           : RA          = wu.RA           #-- Earth Radius (m) 
    174 if not GRAV         : GRAV        = wu.GRAV         #-- Gravity (m^2/s 
    175 if not ICE_RHO_ICE  : ICE_RHO_ICE = wu.ICE_RHO_ICE  #-- Ice volumic mass (kg/m3) in LIM3 
    176 if not ICE_RHO_SNO  : ICE_RHO_SNO = wu.ICE_RHO_SNO  #-- Snow volumic mass (kg/m3) in LIM3 
    177 if not OCE_RHO_LIQ  : OCE_RHO_LIQ = wu.OCE_RHO_LIQ  #-- Ocean water volumic mass (kg/m3) in NEMO 
    178 if not ATM_RHO      : ATM_RHO     = wu.ATM_RHO      #-- Water volumic mass in atmosphere (kg/m^3) 
    179 if not SRF_RHO      : SRF_RHO     = wu.SRF_RHO      #-- Water volumic mass in surface reservoir (kg/m^3) 
    180 if not RUN_RHO      : RUN_RHO     = wu.RUN_RHO      #-- Water volumic mass of rivers (kg/m^3) 
    181 if not ICE_RHO_PND  : ICE_RHO_PND = wu.ICE_RHO_PND  #-- Water volumic mass in ice ponds (kg/m^3) 
    182 if not YEAR_LENGTH  : YEAR_LENGTH = wu.YEAR_LENGTH  #-- Year length (s) 
    183  
    184 ## Set libIGCM and machine dependant values 
    185 ## ---------------------------------------- 
    186 if 'Files'   not in config.keys () : config['Files']   = {} 
    187 if 'Physics' not in config.keys () : config['Physics'] = {} 
    188 if 'Config'  not in config.keys () : config['Physics'] = {} 
    189  
    190  
    191 config['Physics'].update ( { 'RA':str(RA), 'GRAV':str(GRAV), 'ICE_RHO_ICE':str(ICE_RHO_ICE), 'ICE_RHO_SNO':str(ICE_RHO_SNO), 
    192                              'OCE_RHO_LIQ':str(OCE_RHO_LIQ), 'ATM_RHO':str(ATM_RHO), 'SRF_RHO':str(SRF_RHO), 'RUN_RHO':str(RUN_RHO), 
    193                              'YEAR_LENGTH':str(YEAR_LENGTH)} ) 
    194  
    195 config['Config'].update ( { 'ContinueOnError':str(ContinueOnError), 'TestInterp':str(TestInterp), 'readPrec':str(readPrec), 
    196                             'Debug':str(Debug), 'Timer':str(Timer)    } ) 
    197  
    198 ## -------------------------- 
    199 ICO  = 'ICO' in ATM 
    200 LMDZ = 'LMD' in ATM 
    201  
    202 mm = libIGCM_sys.config ( TagName=TagName, SpaceName=SpaceName, ExperimentName=ExperimentName, JobName=JobName, User=User, Group=Group, 
    203              ARCHIVE=ARCHIVE, SCRATCHDIR=SCRATCHDIR, STORAGE=STORAGE, R_IN=R_IN, R_OUT=R_OUT, R_FIG=R_FIG, TmpDir=TmpDir, 
    204              R_SAVE=R_SAVE, R_FIGR=R_FIGR, R_BUFR=R_BUFR, R_BUF_KSH=R_BUF_KSH, POST_DIR=POST_DIR, L_EXP=L_EXP ) 
    205 globals().update(mm) 
    206  
    207 config['Files']['TmpDir'] = TmpDir 
    208  
    209 if 'libIGCM' not in config.keys () : config['libIGCM'] = {} 
    210 config['libIGCM'].update ( { 'ARCHIVE':str(ARCHIVE), 'STORAGE':str(STORAGE), 'TmpDir':str(TmpDir), 'R_IN':str(R_IN) } ) 
    211  
    212 ## Debuging and timer 
    213 Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timer) 
    214  
    215 ## Defines begining and end of experiment 
    216 ## -------------------------------------- 
    217 if not DateBegin : 
    218     DateBegin = f'{YearBegin}0101' 
    219     config['Experiment']['DateBegin'] = str(DateBegin) 
    220 else : 
    221     YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 
    222     DateBegin = wu.FormatToGregorian (DateBegin) 
    223     config['Experiment']['YearBegin'] = str(YearBegin) 
    224  
    225 if not DateEnd  : 
    226     DateEnd   = f'{YearEnd}1231' 
    227     config['Experiment']['DateEnd'] = str(DateEnd) 
    228 else : 
    229     YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 
    230     DateEnd   = wu.FormatToGregorian (DateEnd) 
    231     config['Experiment']['DateEnd'] = str(DateEnd) 
    232  
    233 if not PackFrequency : 
    234     PackFrequency = YearEnd - YearBegin + 1 
    235     config['Experiment']['PackFrequency']   = f'{PackFrequency}' 
    236  
    237 if isinstance ( PackFrequency, str) : 
    238     if 'Y' in PackFrequency : PackFrequency = PackFrequency.replace ( 'Y', '') 
    239     if 'M' in PackFrequency : PackFrequency = PackFrequency.replace ( 'M', '') 
    240     PackFrequency = int ( PackFrequency ) 
     49    FullIniFile = 'ATM_' + IniFile 
     50 
     51print ("Output file : ", FullIniFile ) 
     52 
     53## Experiment parameters 
     54## -------------------- 
     55dpar = wu.ReadConfig ( IniFile ) 
     56 
     57## Configure all needed parameter from existant parameters 
     58## ------------------------------------------------------- 
     59dpar = wu.SetDatesAndFiles ( dpar ) 
    24160 
    24261## Output file with water budget diagnostics 
    24362## ----------------------------------------- 
    244 if not FileOut : 
    245     FileOut = f'ATM_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 
    246     if ICO : 
    247         if ATM_HIS == 'latlon' : FileOut = f'{FileOut}_LATLON' 
    248         if ATM_HIS == 'ico'    : FileOut = f'{FileOut}_ICO' 
    249     if readPrec == np.float32  : FileOut = f'{FileOut}_float32' 
    250     FileOut = f'{FileOut}.out' 
    251  
    252 config['Files']['FileOut'] = FileOut 
    253  
    254 f_out = open ( FileOut, mode = 'w', encoding="utf-8" ) 
     63f_out = dpar['Files']['f_out'] 
     64 
     65## Put dpar values in local namespace 
     66## ---------------------------------- 
     67for Section in dpar.keys () :  
     68    print ( f'\nReading [{Section}]' ) 
     69    for VarName in dpar[Section].keys() : 
     70        globals()[VarName] = dpar[Section][VarName] 
     71        print ( f'    {VarName:21} set to : {globals()[VarName]}' ) 
     72 
     73## Debuging and timer 
     74Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timing) 
    25575 
    25676## Useful functions 
     
    282102 
    283103def prtFlux (Desc, pvar, Form='F', small=False, rho=ATM_RHO, width=15) : 
    284     '''Pretty print of formattd value''' 
     104    '''Pretty print of formatted value''' 
    285105    if small : 
    286106        if Form in ['f', 'F'] : ff=" {:14.6e} kg | {:12.4f} mSv | {:12.4f} mm/year " 
     
    298118    f_out.flush () 
    299119 
    300 echo ( f'{ContinueOnError = }' ) 
    301 echo ( f'{readPrec        = }' ) 
    302  
    303 echo ( f'{JobName         = }' ) 
    304 echo ( f'{ConfigCard      = }' ) 
    305 echo ( f'{libIGCM         = }' ) 
    306 echo ( f'{User            = }' ) 
    307 echo ( f'{Group           = }' ) 
    308 echo ( f'{Freq            = }' ) 
    309 echo ( f'{YearBegin       = }' ) 
    310 echo ( f'{YearEnd         = }' ) 
    311 echo ( f'{DateBegin       = }' ) 
    312 echo ( f'{DateEnd         = }' ) 
    313 echo ( f'{PackFrequency   = }' ) 
    314 echo ( f'{ATM             = }' ) 
    315 echo ( f'{Routing         = }' ) 
    316 echo ( f'{ORCA            = }' ) 
    317 echo ( f'{NEMO            = }' ) 
    318 echo ( f'{Coupled         = }' ) 
    319 echo ( f'{ATM_HIS         = }' ) 
    320 echo ( f'{SRF_HIS         = }' ) 
    321 echo ( f'{RUN_HIS         = }' ) 
    322  
    323 ## Set libIGCM directories 
    324 ## ----------------------- 
    325 if not R_OUT       : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
    326 if not R_BUF       : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
    327 if not L_EXP       : 
    328     if TagName and SpaceName and ExperimentName and JobName : L_EXP = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    329     else : L_EXP = '/' 
    330 if not R_SAVE      : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    331 if not R_BUFR      : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    332 if not POST_DIR    : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
    333 if not R_BUF_KSH   : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    334 if not R_FIGR      : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    335  
    336 config['libIGCM'].update ( { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'POST_DIR':POST_DIR, 'R_SAVE':R_SAVE, 
    337                        'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_BUFR } ) 
    338  
    339 ## Set directory to extract files 
    340 ## ------------------------------ 
    341 if not FileDir : FileDir = os.path.join ( TmpDir, f'WATER_{JobName}' ) 
    342 config['Files']['FileDir'] = FileDir 
    343  
    344 if not os.path.isdir ( FileDir ) : os.makedirs ( FileDir ) 
    345  
    346 echo (' ') 
    347 echo ( f'JobName     : {JobName}'    ) 
    348 echo ( f'Comment     : {Comment}'    ) 
    349 echo ( f'TmpDir      : {TmpDir}'     ) 
    350 echo ( f'FileDir     : {FileDir}'    ) 
    351  
    352 echo ( f'\nDealing with {L_EXP}'  ) 
    353  
    354 ## Creates model output directory names 
    355 ## ------------------------------------ 
    356 if Freq == "MO" : FreqDir = os.path.join ('Output' , 'MO' ) 
    357 if Freq == "SE" : FreqDir = os.path.join ('Analyse', 'SE' ) 
    358 if not dir_ATM_his : 
    359     dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) 
    360     config['Files']['dir_ATM_his'] = dir_ATM_his 
    361 if not dir_SRF_his : 
    362     dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) 
    363     config['Files']['dir_SRF_his'] = dir_SRF_his 
    364  
    365 echo (  'The analysis relies on files from the following model output directories : ' ) 
    366 echo ( f'{dir_ATM_his = }' ) 
    367 echo ( f'{dir_SRF_his = }' ) 
    368  
    369 ##-- Creates files names 
    370 if not Period : 
    371     if Freq == 'MO' : Period = f'{DateBegin}_{DateEnd}_1M' 
    372     if Freq == 'SE' : Period = f'SE_{DateBegin}_{DateEnd}_1M' 
    373     config['Files']['Period'] = Period 
    374  
    375 config['Files']['DateBegin'] = DateBegin 
    376 config['Files']['DateBegin'] = DateEnd 
    377  
    378 echo ( f'Period   : {Period}' ) 
    379  
    380 if not FileCommon : 
    381     FileCommon = f'{JobName}_{Period}' 
    382     config['Files']['FileCommon'] = FileCommon 
    383  
    384 if not Title : 
    385     Title = f'{JobName} : {Freq} : {DateBegin} - {DateEnd}' 
    386     config['Files']['Title'] = Title 
    387  
    388 echo ('\nOpen history files' ) 
    389 if not file_ATM_his : 
    390     if ATM_HIS == 'latlon' : 
    391         file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth.nc' ) 
    392     if ATM_HIS == 'ico' : 
    393         file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth_ico.nc' ) 
    394     config['Files']['file_ATM_his'] = file_ATM_his 
    395 if not file_SRF_his : 
    396     if ATM_HIS == 'latlon' : 
    397         file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    398     if ATM_HIS == 'ico' : 
    399         file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 
    400     config['Files']['file_SRF_his'] = file_SRF_his 
    401  
    402 if SRF and Routing == 'SIMPLE' : 
    403     if file_RUN_his is None : 
    404         if ATM_HIS == 'latlon' : 
    405             file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    406         if ATM_HIS == 'ico' : 
    407             file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 
    408         config['Files']['file_RUN_his'] = file_RUN_his 
    409  
     120## Open history files 
     121## ------------------ 
    410122d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    411123if SRF : 
     
    417129if SRF : 
    418130    echo ( f'{file_SRF_his = }' ) 
    419     if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' ) 
    420  
     131     
    421132## Compute run length 
    422133## ------------------ 
    423134dtime = ( d_ATM_his.time_counter_bounds.max() - d_ATM_his.time_counter_bounds.min() ) 
    424 echo ('\nRun length : {:8.2f} days'.format ( (dtime/np.timedelta64(1, "D")).values ) ) 
     135echo ( f'\nRun length : {(dtime/np.timedelta64(1, "D")).values:8.2f} days' ) 
    425136dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds 
    426137 
    427138##-- Compute length of each period 
    428139dtime_per = (d_ATM_his.time_counter_bounds[:,-1] -  d_ATM_his.time_counter_bounds[:,0] ) 
    429 echo ('\nPeriods lengths (days) : {:} days'.format ( (dtime_per/np.timedelta64(1, "D")).values ) ) 
     140echo ( '\nPeriods lengths (days) : {:} days'.format ( (dtime_per/np.timedelta64(1, "D")).values ) ) 
    430141dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds 
    431142dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_ATM_his.time_counter,] ) 
     
    435146NbYear = dtime_sec / YEAR_LENGTH 
    436147 
    437 ##-- Extract restart files from tar 
    438  
    439 if not TarRestartDate_beg : TarRestartDate_beg = wu.DateMinusOneDay ( DateBegin ) 
    440 if not TarRestartDate_end : TarRestartDate_end = wu.FormatToGregorian ( DateEnd ) 
    441  
    442 if not TarRestartPeriod_beg : 
    443  
    444     TarRestartPeriod_beg_DateEnd = TarRestartDate_beg 
    445     TarRestartPeriod_beg_DateBeg = wu.DateAddYear ( TarRestartPeriod_beg_DateEnd, -PackFrequency ) 
    446     TarRestartPeriod_beg_DateBeg = wu.DatePlusOneDay ( TarRestartPeriod_beg_DateBeg ) 
    447  
    448     TarRestartPeriod_beg = f'{TarRestartPeriod_beg_DateBeg}_{TarRestartPeriod_beg_DateEnd}' 
    449     echo (f'Tar period for initial restart : {TarRestartPeriod_beg}') 
    450     config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg 
    451  
    452 if not TarRestartPeriod_end : 
    453  
    454     TarRestartPeriod_end_DateEnd = TarRestartDate_end 
    455     TarRestartPeriod_end_DateBeg = wu.DateAddYear ( TarRestartPeriod_end_DateEnd, -PackFrequency ) 
    456     TarRestartPeriod_end_DateBeg = wu.DatePlusOneDay ( TarRestartPeriod_end_DateBeg ) 
    457  
    458     TarRestartPeriod_end = f'{TarRestartPeriod_end_DateBeg}_{TarRestartPeriod_end_DateEnd}' 
    459     echo (f'Tar period for final restart : {TarRestartPeriod_end}') 
    460     config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end 
    461  
    462 echo (f'Restart dates - Start : {TarRestartPeriod_beg}  /  End : {TarRestartPeriod_end}') 
    463  
    464 if not tar_restart_beg : 
    465     tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
    466     config['Files']['tar_restart_beg'] = tar_restart_beg 
    467 if not tar_restart_end : 
    468     tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
    469     config['Files']['tar_restart_end'] = tar_restart_end 
    470  
    471 echo ( f'{tar_restart_beg = }' ) 
    472 echo ( f'{tar_restart_end = }' ) 
    473  
    474 ##-- Names of tar files with restarts 
    475  
    476 if not tar_restart_beg_ATM : tar_restart_beg_ATM = tar_restart_beg 
    477 if not tar_restart_beg_DYN : tar_restart_beg_DYN = tar_restart_beg 
    478 if not tar_restart_beg_RUN : tar_restart_beg_RUN = tar_restart_beg 
    479 if not tar_restart_beg_OCE : tar_restart_beg_OCE = tar_restart_beg 
    480 if not tar_restart_beg_ICE : tar_restart_beg_ICE = tar_restart_beg 
    481  
    482 if not tar_restart_end_ATM : tar_restart_end_ATM = tar_restart_end 
    483 if not tar_restart_end_DYN : tar_restart_end_DYN = tar_restart_end 
    484 if not tar_restart_end_RUN : tar_restart_end_RUN = tar_restart_end 
    485 if not tar_restart_end_OCE : tar_restart_end_OCE = tar_restart_end 
    486 if not tar_restart_end_ICE : tar_restart_end_ICE = tar_restart_end 
    487  
    488 if SRF : 
    489     if not SRF_HIS : SRF_HIS = ATM_HIS 
    490     if not tar_restart_beg_SRF : tar_restart_beg_SRF = tar_restart_beg 
    491     if not tar_restart_end_SRF : tar_restart_end_SRF = tar_restart_end 
    492  
    493 if not file_ATM_beg : 
    494     file_ATM_beg = f'{FileDir}/ATM_{JobName}_{TarRestartDate_beg}_restartphy.nc' 
    495     config['Files']['file_ATM_beg'] = file_ATM_beg 
    496 if not file_ATM_end : 
    497     file_ATM_end = f'{FileDir}/ATM_{JobName}_{TarRestartDate_end}_restartphy.nc' 
    498     config['Files']['file_ATM_end'] = file_ATM_end 
     148## Define restart periods and file names 
     149## ------------------------------------- 
     150dpar = wu.SetRestartNames ( dpar, f_out)  
     151 
     152## Put dpar values in local namespace 
     153## ---------------------------------- 
     154for Section in dpar.keys () :  
     155    print ( f'\nReading [{Section}]' ) 
     156    for VarName in dpar[Section].keys() : 
     157        locals()[VarName] = dpar[Section][VarName] 
     158        print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
     159         
     160## Extract restart files from tar 
     161## ---------------------------------- 
    499162 
    500163liste_beg = [file_ATM_beg, ] 
    501164liste_end = [file_ATM_end, ] 
    502  
    503 if not file_DYN_beg : 
    504     if LMDZ : file_DYN_beg = f'{FileDir}/ATM_{JobName}_{TarRestartDate_beg}_restart.nc' 
    505     if ICO  : file_DYN_beg = f'{FileDir}/ICO_{JobName}_{TarRestartDate_beg}_restart.nc' 
    506     liste_beg.append (file_DYN_beg) 
    507     config['Files']['file_DYN_beg'] = file_DYN_beg 
    508  
    509 if not file_DYN_end : 
    510     if LMDZ : file_DYN_end = f'{FileDir}/ATM_{JobName}_{TarRestartDate_end}_restart.nc' 
    511     if ICO  : file_DYN_end = f'{FileDir}/ICO_{JobName}_{TarRestartDate_end}_restart.nc' 
    512     liste_end.append ( file_DYN_end ) 
    513     config['Files']['file_DYN_end'] = file_DYN_end 
    514  
    515 if SRF : 
    516     if not file_SRF_beg : 
    517         file_SRF_beg = f'{FileDir}/SRF_{JobName}_{TarRestartDate_beg}_sechiba_rest.nc' 
    518         config['Files']['file_SRF_beg'] = file_SRF_beg 
    519     if not file_SRF_end : 
    520         file_SRF_end = f'{FileDir}/SRF_{JobName}_{TarRestartDate_end}_sechiba_rest.nc' 
    521         config['Files']['file_SRF_end'] = file_SRF_end 
    522  
    523 liste_beg.append ( file_SRF_beg ) 
    524 liste_end.append ( file_SRF_end ) 
    525  
    526 echo ( f'{file_ATM_beg = }') 
    527 echo ( f'{file_ATM_end = }') 
    528 echo ( f'{file_DYN_beg = }') 
    529 echo ( f'{file_DYN_end = }') 
    530 if SRF : 
    531     echo ( f'{file_SRF_beg = }') 
    532     echo ( f'{file_SRF_end = }') 
     165if file_DYN_beg : liste_beg.append ( file_DYN_beg ) 
     166if file_DYN_end : liste_end.append ( file_DYN_end ) 
     167if file_SRF_beg : liste_beg.append ( file_SRF_beg ) 
     168if file_SRF_end : liste_end.append ( file_SRF_end ) 
    533169 
    534170if ICO : 
    535     if not file_DYN_aire : file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ATM+'_grid.nc' ) 
    536     config['Files']['file_DYN_aire'] = file_DYN_aire 
     171    if not file_DYN_aire : 
     172        file_DYN_aire = os.path.join ( R_IN, 'ATM', 'GRID', ResolAtm+'_grid.nc' ) 
     173    dpar['Files']['file_DYN_aire'] = file_DYN_aire 
    537174 
    538175if SRF and Routing == 'SIMPLE' : 
    539     if not file_RUN_beg : 
    540         file_RUN_beg = f'{FileDir}/SRF_{JobName}_{TarRestartDate_beg}_routing_restart.nc' 
    541         config['Files']['file_RUN_beg'] = file_RUN_beg 
    542     if not file_RUN_end : 
    543         file_RUN_end = f'{FileDir}/SRF_{JobName}_{TarRestartDate_end}_routing_restart.nc' 
    544         config['Files']['file_RUN_end'] = file_RUN_end 
    545  
    546176    liste_beg.append ( file_RUN_beg ) 
    547177    liste_end.append ( file_RUN_end ) 
    548     echo ( f'{file_RUN_beg = }' ) 
    549     echo ( f'{file_RUN_end = }' ) 
    550  
    551 echo ('\nExtract restart files from tar : ATM, ICO', end='') 
     178 
     179echo ( '\nExtract restart files from tar : ATM, ICO', end='') 
    552180if SRF : echo ( ' and SRF') 
    553181else   : echo (' ') 
    554182 
    555     
     183## Write the full configuration 
     184## ---------------------------- 
     185params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     186params = wu.dict2config ( dpar ) 
     187params.write ( params_out ) 
     188params_out.close () 
     189     
    556190@Timer 
    557 def extract ( file_name=file_ATM_beg, tar_restart=tar_restart_end, file_dir_comp=FileDir, error_count=ErrorCount ) : 
     191def extract ( file_name=file_ATM_beg, tar_restart=tar_restart_end, file_dir_comp=FileDir ) : 
    558192    ''' 
    559193    Extract restart files from a tar 
    560194    ''' 
    561195    echo ( f'----------') 
     196    error_count = 0 
    562197    echo ( f'file to extract : {file_name = }' ) 
    563198    if os.path.exists ( os.path.join (FileDir, file_name) ) : 
    564         echo ( f'file found : {file_name = }' ) 
     199        echo ( f'file found      : {file_name = }' ) 
    565200    else : 
    566         echo ( f'file not found : {file_name = }' ) 
     201        echo ( f'file not found  : {file_name = }' ) 
    567202        base_resFile = os.path.basename (file_name) 
    568203        if os.path.exists ( tar_restart ) : 
    569204            command =  f'cd {file_dir_comp} ; tar xf {tar_restart} {base_resFile}' 
    570205            echo ( f'{command = }' ) 
    571             try : os.system ( command ) 
    572             except : 
     206            err = os.system ( command ) 
     207            if err != 0 : 
    573208                if ContinueOnError : 
    574209                    error_count += 1 
    575                     echo ( '****** Command failed : {command}' ) 
     210                    echo ( f'****** Command failed : {command}' ) 
    576211                    echo ( '****** Trying to continue' ) 
    577212                    echo ( ' ') 
     
    584219            if ContinueOnError : 
    585220                error_count += 1 
     221                echo ( f'****** Command failed : {command}' ) 
     222                echo (  '****** Trying to continue' ) 
     223                echo (  ' ') 
    586224            else : 
    587225                raise OSError ( f'****** tar file not found {tar_restart = } - Stopping' ) 
    588226    return error_count 
    589227 
    590 ErrorCount += extract ( file_name=file_ATM_beg, tar_restart=tar_restart_beg_ATM, file_dir_comp=FileDir, error_count=ErrorCount ) 
    591 ErrorCount += extract ( file_name=file_DYN_beg, tar_restart=tar_restart_beg_DYN, file_dir_comp=FileDir, error_count=ErrorCount ) 
    592  
    593 ErrorCount += extract ( file_name=file_ATM_end, tar_restart=tar_restart_end_ATM, file_dir_comp=FileDir, error_count=ErrorCount ) 
    594 ErrorCount += extract ( file_name=file_DYN_end, tar_restart=tar_restart_end_DYN, file_dir_comp=FileDir, error_count=ErrorCount ) 
    595  
    596 if SRF : 
    597     ErrorCount += extract ( file_name=file_SRF_beg, tar_restart=tar_restart_beg_SRF, file_dir_comp=FileDir, error_count=ErrorCount ) 
    598     ErrorCount += extract ( file_name=file_SRF_end, tar_restart=tar_restart_end_SRF, file_dir_comp=FileDir, error_count=ErrorCount ) 
     228ErrorCount = 0 
     229 
     230ErrorCount += extract ( file_name=file_ATM_beg, tar_restart=tar_restart_beg_ATM, file_dir_comp=FileDir ) 
     231ErrorCount += extract ( file_name=file_DYN_beg, tar_restart=tar_restart_beg_DYN, file_dir_comp=FileDir ) 
     232 
     233ErrorCount += extract ( file_name=file_ATM_end, tar_restart=tar_restart_end_ATM, file_dir_comp=FileDir ) 
     234ErrorCount += extract ( file_name=file_DYN_end, tar_restart=tar_restart_end_DYN, file_dir_comp=FileDir ) 
     235 
     236if SRF : 
     237    ErrorCount += extract ( file_name=file_SRF_beg, tar_restart=tar_restart_beg_SRF, file_dir_comp=FileDir ) 
     238    ErrorCount += extract ( file_name=file_SRF_end, tar_restart=tar_restart_end_SRF, file_dir_comp=FileDir ) 
    599239 
    600240    if Routing == 'SIMPLE' : 
    601         ErrorCount += extract ( file_name=file_RUN_beg, tar_restart=tar_restart_beg_RUN, file_dir_comp=FileDir, error_count=ErrorCount ) 
    602         ErrorCount += extract ( file_name=file_RUN_end, tar_restart=tar_restart_end_RUN, file_dir_comp=FileDir, error_count=ErrorCount ) 
     241        ErrorCount += extract ( file_name=file_RUN_beg, tar_restart=tar_restart_beg_RUN, file_dir_comp=FileDir ) 
     242        ErrorCount += extract ( file_name=file_RUN_end, tar_restart=tar_restart_end_RUN, file_dir_comp=FileDir ) 
    603243 
    604244##-- Exit in case of error in the opening file phase 
     
    660300        echo ( f'{file_RUN_beg = }' ) 
    661301        echo ( f'{file_RUN_end = }' ) 
    662  
    663 ## Write the full configuration 
    664 config_out = open (FullIniFile, 'w', encoding = 'utf-8') 
    665 config.write ( config_out ) 
    666 config_out.close () 
    667302 
    668303# ATM grid with cell surfaces 
     
    685320if ICO : 
    686321    if ATM_HIS == 'latlon' : 
    687         echo ( 'ATM areas and fractions on latlon grid' ) 
     322        echo ( 'ATM areas and fractions on LATLON grid' ) 
    688323        if 'lat_dom_out' in d_ATM_his.variables : 
    689324            ATM_lat  = lmdz.geo2point (   rprec (d_ATM_his ['lat_dom_out'])+0*rprec (d_ATM_his ['lon_dom_out']), dim1d='cell' ) 
     
    710345    if SRF : 
    711346        if SRF_HIS == 'latlon' : 
    712             echo ( 'SRF areas and fractions on latlon grid' ) 
     347            echo ( 'SRF areas and fractions on LATLON grid' ) 
    713348            if 'lat_domain_landpoints_out' in d_SRF_his  : 
    714349                SRF_lat  = lmdz.geo2point (   rprec (d_SRF_his ['lat_domain_landpoints_out'])+0*rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1d='cell' ) 
     
    728363 
    729364        if SRF_HIS == 'ico' : 
    730             echo ( 'SRF areas and fractions on latlon grid' ) 
     365            echo ( 'SRF areas and fractions on ICO grid' ) 
    731366            SRF_lat       =  rprec (d_SRF_his ['lat']     ) 
    732367            SRF_lon       =  rprec (d_SRF_his ['lon']     ) 
     
    746381#SRF_aire = SRF_aire.where ( np.abs (SRF_aire) < 1E15, 0. ) 
    747382 
    748 ## Write the full configuration 
    749 config_out = open (FullIniFile, 'w', encoding='utf-8') 
    750 config.write ( config_out ) 
    751 config_out.close () 
    752  
    753383if ICO : 
    754384    # Area on icosahedron grid 
     385    echo ( f'{file_DYN_aire = }' ) 
    755386    d_DYN_aire = xr.open_dataset ( file_DYN_aire, decode_times=False ).squeeze() 
    756  
     387     
    757388    if SortIco : 
    758         # Creation d'une clef de tri pour le fichier aire 
    759         DYN_aire_keysort = np.lexsort ( (d_DYN_aire['lat'], d_DYN_aire['lon']) ) 
     389            # Creation d'une clef de tri pour le fichier aire 
     390            DYN_aire_keysort = np.lexsort ( (d_DYN_aire['lat'], d_DYN_aire['lon']) ) 
    760391    else : 
    761         DYN_aire_keysort = np.arange ( len ( d_DYN_aire['lat'] ) ) 
    762  
     392            DYN_aire_keysort = np.arange ( len ( d_DYN_aire['lat'] ) ) 
     393             
    763394    DYN_lat = d_DYN_aire['lat'] 
    764395    DYN_lon = d_DYN_aire['lon'] 
    765  
     396         
    766397    DYN_aire = d_DYN_aire['aire'] 
    767398    DYN_fsea = d_DYN_aire['fract_oce'] + d_DYN_aire['fract_sic'] 
     399         
    768400    DYN_flnd = 1.0 - DYN_fsea 
    769401    DYN_fter = d_ATM_beg['FTER'] 
    770402    DYN_flic = d_ATM_beg['FLIC'] 
     403    DYN_foce = d_ATM_beg['FOCE'] 
    771404    DYN_aire_fter = DYN_aire * DYN_fter 
     405 
     406#if ATM_HIS == 'ico' : 
     407#    ATM_aire      = DYN_aire 
     408#    ATM_aire_fter = DYN_aire * ATM_fter 
     409#    ATM_aire_flic = DYN_aire * ATM_flic 
     410#    ATM_aire_fsic = DYN_aire * ATM_fsic 
     411#    ATM_aire_foce = DYN_aire * ATM_foce 
     412#    ATM_aire_flnd = DYN_aire * ATM_flnd 
     413#    ATM_aire_fsea = DYN_aire * ATM_fsea 
     414 
     415if ATM_HIS == 'ico' : 
     416    DYN_aire      = ATM_aire 
     417    DYN_foce      = ATM_foce 
     418    DYN_fsic      = ATM_fsic 
     419    DYN_flic      = ATM_flic 
     420    DYN_fter      = ATM_fter 
     421    DYN_fsea      = ATM_fsea 
     422    DYN_flnd      = ATM_flnd 
     423    DYN_aire_fter = ATM_aire_fter 
     424    DYN_aire_flic = ATM_aire_flic 
     425    DYN_aire_fsic = ATM_aire_fsic 
     426    DYN_aire_foce = ATM_aire_foce 
     427    DYN_aire_flnd = ATM_aire_flnd 
     428    DYN_aire_fsea = ATM_aire_fsea 
    772429 
    773430if LMDZ : 
     
    780437    DYN_aire_fter = DYN_aire * DYN_fter 
    781438 
     439if ICO and ATM_HIS == 'ico' : 
     440    # Comparaison des aires sur ATM et DYN 
     441    aire_diff = ATM_aire - DYN_aire 
     442    echo ( 'f{Difference Aire hist file vs. grid file {aire_diff.mean()=} {aire_diff.min()=}  {aire_diff.max()=} ' ) 
     443     
     444 
    782445# Functions computing integrals and sum 
    783446@Timer 
     
    809472@Timer 
    810473def ONE_stock_int (stock) : 
    811     '''Sum stock ''' 
     474    '''Sum stock''' 
    812475    return wu.Psum ( stock.to_masked_array().ravel() ) 
    813476 
    814477@Timer 
    815478def ONE_flux_int (flux) : 
    816     '''Integrate (* time) flux on area=1 grid ''' 
     479    '''Integrate (* time) flux on area=1 grid''' 
    817480    return wu.Psum ( (flux * dtime_per_sec ).to_masked_array().ravel() ) 
    818481 
     
    929592if ICO : 
    930593    if 'H2Ov_g' in d_DYN_beg.variables : 
    931         echo ('reading ICO : H2O_g, H2O_l, H2O_s' ) 
    932         DYN_wat_beg = d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'] 
    933         DYN_wat_end = d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'] 
     594        echo ('reading ICO : H2Ov_g, H2Ov_l, H2Ov_s' ) 
     595        DYN_wat_beg = d_DYN_beg['H2Ov_g'] + d_DYN_beg['H2Ov_l'] + d_DYN_beg['H2Ov_s'] 
     596        DYN_wat_end = d_DYN_end['H2Ov_g'] + d_DYN_end['H2Ov_l'] + d_DYN_end['H2Ov_s'] 
    934597    elif 'H2O_g' in d_DYN_beg.variables : 
    935598        echo ('reading ICO : H2O_g, H2O_l, H2O_s' ) 
    936         DYN_wat_beg = d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l'] + d_DYN_beg['H2O_s'] 
    937         DYN_wat_end = d_DYN_end['H2O_g'] + d_DYN_end['H2O_l'] + d_DYN_end['H2O_s'] 
     599        DYN_wat_beg = d_DYN_beg['H2O_g'] + d_DYN_beg['H2O_l']   + d_DYN_beg['H2O_s'] 
     600        DYN_wat_end = d_DYN_end['H2O_g'] + d_DYN_end['H2O_l']   + d_DYN_end['H2O_s'] 
    938601    elif 'q' in d_DYN_beg.variables : 
    939602        echo ('reading ICO : q' ) 
     
    14941157prtFlux ('ATM_flx_wemp*        ', ATM_flx_wemp          , 'f', True ) 
    14951158 
     1159echo ( 'Errors <field> vs. wbil_<field>' ) 
    14961160prtFlux ('ERROR evap           ', ATM_flx_wevap   - ATM_flx_evap  , 'e', True ) 
    14971161prtFlux ('ERROR precip         ', ATM_flx_wprecip - ATM_flx_precip, 'e', True ) 
     
    15141178    prtFlux ('river bil     ', RUN_flx_bil        , 'f' ) 
    15151179 
    1516 ATM_flx_budget = -ATM_flx_wbilo + ATM_flx_calving + ATM_flx_runlic #+ ATM_flx_fqfonte + RUN_flx_river 
     1180ATM_flx_budget = -ATM_flx_wbilo + ATM_flx_calving + ATM_flx_runlic #+# ATM_flx_fqfonte #+ RUN_flx_river 
    15171181 
    15181182 
     
    15321196prtFlux ( 'E-P          = ', ATM_flx_emp  , 'e', True ) 
    15331197echo ( ' ' ) 
    1534 prtFlux ( 'Water loss atm', ATM_flx_wbilo - dDYN_mas_wat, 'f', True ) 
     1198prtFlux ( 'Water loss atm from wbil_*', ATM_flx_wbilo - dDYN_mas_wat, 'f', True ) 
    15351199echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_wbilo - dDYN_mas_wat)/dDYN_mas_wat  ) ) 
    15361200 
    15371201echo (' ') 
    1538 prtFlux ( 'Water loss atm', ATM_flx_emp  - dDYN_mas_wat , 'f', True ) 
     1202prtFlux ( 'Water loss atm from E-P', ATM_flx_emp  - dDYN_mas_wat , 'f', True ) 
    15391203echo ( 'Water loss atm = {:12.3e} (rel)  '.format ( (ATM_flx_emp-dDYN_mas_wat)/dDYN_mas_wat  ) ) 
    15401204echo (' ') 
     1205 
     1206ATM_error =  ATM_flx_emp  - dDYN_mas_wat 
     1207 
    15411208 
    15421209echo (' ') 
     
    16461313for kk in SVN.keys(): 
    16471314    print ( SVN[kk] ) 
     1315 
     1316## Write the full configuration 
     1317params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     1318params = wu.dict2config ( dpar ) 
     1319params.write ( params_out ) 
     1320params_out.close () 
  • TOOLS/WATER_BUDGET/CPL_waterbudget.py

    r6665 r6676  
    2828    } 
    2929### 
    30 ## Import system modules 
    31 import sys, os, shutil, subprocess, platform 
    32 import numpy as np 
    33 import configparser, re 
    34 from pathlib import Path 
    35  
    3630### 
    3731## Import system modules 
    38 import sys, os, shutil#, subprocess, platform 
    39 import configparser, re 
     32import sys 
     33import os 
     34import configparser 
    4035 
    4136## Import needed scientific modules 
    42 import numpy as np, xarray as xr 
     37import numpy as np 
     38import xarray as xr 
    4339 
    4440## Import local modules 
    4541import WaterUtils as wu 
    46 import libIGCM_sys 
    4742import nemo, lmdz 
    48  
    49 from WaterUtils import RA, GRAV, ICE_RHO_ICE, ICE_RHO_SNO, OCE_RHO_LIQ, \ 
    50                        ATM_RHO, SRF_RHO, RUN_RHO, ICE_RHO_PND, YEAR_LENGTH 
    51  
    52 ## Creates parser for reading .ini input file 
    53 ## ------------------------------------------- 
    54 config = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
    55 config.optionxform = str # To keep capitals 
    56  
    57 ## Experiment parameters 
    58 ## --------------------- 
    59 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None ; NEMO=None ; OCE_relax=False 
    60 OCE_icb=False ; Coupled=False ; Routing=None ; TestInterp=None 
    61 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None ; Period=None ; Title=None 
    62 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 
    63  
    64 Timer=False ; Debug=False 
    65 ## 
    66 ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None ; rebuild=None ; TmpDir=None 
    67 FileDir=None ; FileOut=None ; R_OUT=None ; R_FIG=None ; R_FIGR=None ; R_BUFR=None ; R_SAVE=None 
    68 R_BUF_KSH=None ; REBUILD_DIR=None ; POST_DIR=None ; L_EXP=None 
    69  
    70 dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None 
    71 FileCommon=None ; file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None 
    72 file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None ; file_OCE_srf=None 
    73 tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None ; file_ATM_end=None ; file_DYN_beg=None 
    74 file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None 
    75 file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None 
    76 file_ICE_beg=None ; file_OCE_beg=None 
    77 file_OCE_end=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 
    78 TarRestartDate_beg=None ; TarRestartDate_end=None 
    79 file_DYN_aire=None 
    80 tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None 
    81 tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None 
    82 tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None 
    83 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 
    84 ContinueOnError=False ; ErrorCount=0 
    85 FileDirOCE=None ; FileDirATM=None ; FileDirICE=None ; FileDirSRF=None ; FileDirRUN=None 
    86  
    87 ## 
    88 ## Precision of history file reading 
    89 ## --------------------------------- 
    90 # Default is float (full precision). Degrade the precision by using np.float32 
    91 # Restart files are always read at the full precision 
    92 readPrec=float 
    9343 
    9444## Read command line arguments 
     
    10151    raise FileExistsError ( f"File not found : {IniFile = }" ) 
    10252 
    103 if 'full' in IniFile : FullIniFile = IniFile 
    104 else                 : FullIniFile = 'full_' + IniFile 
    105      
    106 print ("Input file : ", IniFile ) 
    107 config.read (IniFile) 
    108 FullIniFile = 'full_' + IniFile 
    109  
    110 ## Reading config.card if possible 
    111 ## ------------------------------- 
    112 ConfigCard = None 
    113  
    114 if 'Experiment' in config.keys ()  : ## Read Experiment on Config file if possible 
    115     if 'ConfigCard' in config['Experiment'].keys () : 
    116         ConfigCard = config['Experiment']['ConfigCard'] 
    117         print ( f'{ConfigCard=}' ) 
    118  
    119 if ConfigCard : ## Read config card if it exists 
    120     # Text existence of ConfigCard 
    121     if os.path.exists ( ConfigCard ) : 
    122         print ( f'Reading Config Card : {ConfigCard}' ) 
    123         ## Creates parser for reading .ini input file 
    124         MyReader = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    125         MyReader.optionxform = str # To keep capitals 
    126          
    127         MyReader.read (ConfigCard) 
    128  
    129         for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName'] : 
    130             if VarName in MyReader['UserChoices'].keys() : 
    131                 locals()[VarName] = MyReader['UserChoices'][VarName] 
    132                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    133                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    134                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    135                 exec  ( f'wu.{VarName} = {VarName}' ) 
    136                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    137                  
    138         for VarName in ['PackFrequency'] : 
    139             if VarName in MyReader['Post'].keys() : 
    140                 locals()[VarName] = MyReader['Post'][VarName] 
    141                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    142                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    143                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    144                 exec  ( f'wu.{VarName} = {VarName}' ) 
    145                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    146     else : 
    147         raise FileExistsError ( f"File not found : {ConfigCard = }" ) 
    148  
    149      
    150 ## Reading config file 
    151 ## ------------------- 
    152 # Each entry in the .ini file will create a Python variable with the same name 
    153 for Section in config.keys () :  
    154     print ( f'\nReading [{Section}]' ) 
    155     for VarName in config[Section].keys() : 
    156         locals()[VarName] = config[Section][VarName] 
    157         exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    158         exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    159         exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    160         exec  ( f'wu.{VarName} = {VarName}' ) 
    161         print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
    162  
    163 print ( f'\nConfig file readed : {IniFile} ' ) 
    164  
    165 ## 
    166 ## Reading prec 
    167 if not readPrec  : 
    168     readPrec = np.float64 
     53if 'full' in IniFile or 'ATM' in IniFile : 
     54    FullIniFile = IniFile 
    16955else : 
    170     if readPrec in ["float", "float64", "r8", "double", "<class 'float'>"         ] : readPrec = float 
    171     if readPrec in [         "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 
    172     if readPrec in [         "float16", "r2", "half"  , "<class 'numpy.float16'>" ] : readPrec = np.float16 
    173      
    174 # Some physical constants 
    175 ## ======================= 
    176 if not RA           : RA          = wu.RA           #-- Earth Radius (m) 
    177 if not GRAV         : GRAV        = wu.GRAV         #-- Gravity (m^2/s 
    178 if not ICE_RHO_ICE  : ICE_RHO_ICE = wu.ICE_RHO_ICE  #-- Ice volumic mass (kg/m3) in LIM3 
    179 if not ICE_RHO_SNO  : ICE_RHO_SNO = wu.ICE_RHO_SNO  #-- Snow volumic mass (kg/m3) in LIM3 
    180 if not OCE_RHO_LIQ  : OCE_RHO_LIQ = wu.OCE_RHO_LIQ  #-- Ocean water volumic mass (kg/m3) in NEMO 
    181 if not ATM_RHO      : ATM_RHO     = wu.ATM_RHO      #-- Water volumic mass in atmosphere (kg/m^3) 
    182 if not SRF_RHO      : SRF_RHO     = wu.SRF_RHO      #-- Water volumic mass in surface reservoir (kg/m^3) 
    183 if not RUN_RHO      : RUN_RHO     = wu.RUN_RHO      #-- Water volumic mass of rivers (kg/m^3) 
    184 if not ICE_RHO_PND  : ICE_RHO_PND = wu.ICE_RHO_PND  #-- Water volumic mass in ice ponds (kg/m^3) 
    185 if not YEAR_LENGTH   : YEAR_LENGTH  = wu.YEAR_LENGTH   #-- Year length (s) 
    186  
    187 if not 'Files'   in config.keys () : config['Files']   = {} 
    188 if not 'Physics' in config.keys () : config['Physics'] = {} 
    189 if not 'Config'  in config.keys () : config['Physics'] = {} 
    190      
    191  
    192 config['Physics'].update ( { 'RA':str(RA), 'GRAV':str(GRAV), 'ICE_RHO_ICE':str(ICE_RHO_ICE), 'ICE_RHO_SNO':str(ICE_RHO_SNO), 
    193                       'OCE_RHO_LIQ':str(OCE_RHO_LIQ), 'ATM_RHO':str(ATM_RHO), 'SRF_RHO':str(SRF_RHO), 'RUN_RHO':str(RUN_RHO)} ) 
    194  
    195 config['Config'].update ( { 'ContinueOnError':str(ContinueOnError), 'TestInterp':str(TestInterp), 'readPrec':str(readPrec), 
    196                             'Debug':str(Debug), 'Timer':str(Timer) } ) 
    197  
    198 ## -------------------------- 
    199 ICO  = ( 'ICO' in wu.ATM ) 
    200 LMDZ = ( 'LMD' in wu.ATM ) 
    201  
    202 mm = libIGCM_sys.config ( TagName=TagName, SpaceName=SpaceName, ExperimentName=ExperimentName, JobName=JobName, User=User, Group=Group, 
    203              ARCHIVE=ARCHIVE, SCRATCHDIR=SCRATCHDIR, STORAGE=STORAGE, R_IN=R_IN, R_OUT=R_OUT, R_FIG=R_FIG, rebuild=rebuild, TmpDir=TmpDir,  
    204              R_SAVE=R_SAVE, R_FIGR=R_FIGR, R_BUFR=R_BUFR, R_BUF_KSH=R_BUF_KSH, REBUILD_DIR=REBUILD_DIR, POST_DIR=POST_DIR, L_EXP=L_EXP ) 
    205 globals().update(mm) 
    206  
    207 config['Files']['TmpDir'] = TmpDir 
    208 if not 'libIGCM'  in config.keys () : config['libIGCM'] = {} 
    209 config['libIGCM'].update ( { 'ARCHIVE':str(ARCHIVE), 'STORAGE':str(STORAGE), 'TmpDir':str(TmpDir), 'R_IN':str(R_IN), 'rebuild':str(rebuild) } ) 
    210  
    211 ## Debuging and timer 
    212 Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timer) 
    213  
    214 ## Defines begining and end of experiment 
    215 ## -------------------------------------- 
    216 if not DateBegin : 
    217     DateBegin = f'{YearBegin}0101' 
    218     config['Experiment']['DateBegin'] = str(DateBegin) 
    219 else : 
    220     YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 
    221     DateBegin = wu.FormatToGregorian (DateBegin) 
    222     config['Experiment']['YearBegin'] = str(YearBegin) 
    223  
    224 if not DateEnd : 
    225     DateEnd   = f'{YearEnd}1231' 
    226     config['Experiment']['DateEnd'] = str(DateEnd) 
    227 else : 
    228     YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 
    229     DateEnd   = wu.FormatToGregorian (DateEnd) 
    230     config['Experiment']['DateEnd'] = str(DateEnd) 
    231  
    232 if not PackFrequency :  
    233     PackFrequency = YearEnd - YearBegin + 1 
    234     config['Experiment']['PackFrequency']   = f'{PackFrequency}' 
    235  
    236 if type ( PackFrequency ) == str :  
    237     if 'Y' in PackFrequency : PackFrequency = PackFrequency.replace ( 'Y', '')  
    238     if 'M' in PackFrequency : PackFrequency = PackFrequency.replace ( 'M', '') 
    239     PackFrequency = int ( PackFrequency ) 
    240      
     56    FullIniFile = 'ATM_' + IniFile 
     57 
     58print ("Output file : ", FullIniFile ) 
     59 
     60## Experiment parameters 
     61## -------------------- 
     62dpar = wu.ReadConfig ( IniFile ) 
     63 
     64## Configure all needed parameter from existant parameters 
     65## ------------------------------------------------------- 
     66dpar = wu.SetDatesAndFiles ( dpar ) 
     67 
    24168## Output file with water budget diagnostics 
    24269## ----------------------------------------- 
    243 if not FileOut : 
    244     FileOut = f'CPL_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 
    245     if ICO :  
    246         if ATM_HIS == 'latlon' : FileOut = f'{FileOut}_LATLON' 
    247         if ATM_HIS == 'ico'    : FileOut = f'{FileOut}_ICO' 
    248     if readPrec == np.float32  : FileOut = f'{FileOut}_float32' 
    249     FileOut = f'{FileOut}.out' 
    250  
    251 config['Files']['FileOut'] = FileOut 
    252  
    253 f_out = open ( FileOut, mode = 'w' ) 
    254      
     70f_out = dpar['Files']['f_out'] 
     71 
     72## Put dpar values in local namespace 
     73## ---------------------------------- 
     74for Section in dpar.keys () :  
     75    print ( f'\nReading [{Section}]' ) 
     76    for VarName in dpar[Section].keys() : 
     77        locals()[VarName] = dpar[Section][VarName] 
     78        print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
     79         
     80## Debuging and timer 
     81Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timing) 
     82    
    25583## Useful functions 
    25684## ---------------- 
     
    299127    return None 
    300128 
    301 echo ( f'{ContinueOnError = }' ) 
    302 echo ( f'{readPrec        = }' ) 
    303  
    304 echo ( f'{JobName         = }' ) 
    305 echo ( f'{ConfigCard      = }' ) 
    306 echo ( f'{libIGCM         = }' )      
    307 echo ( f'{User            = }' )        
    308 echo ( f'{Group           = }' )        
    309 echo ( f'{Freq            = }' )        
    310 echo ( f'{YearBegin       = }' )      
    311 echo ( f'{YearEnd         = }' )      
    312 echo ( f'{DateBegin       = }' ) 
    313 echo ( f'{DateEnd         = }' ) 
    314 echo ( f'{PackFrequency   = }' )  
    315 echo ( f'{ATM             = }' )        
    316 echo ( f'{Routing         = }' )        
    317 echo ( f'{ORCA            = }' )       
    318 echo ( f'{NEMO            = }' )       
    319 echo ( f'{Coupled         = }' )       
    320 echo ( f'{ATM_HIS         = }' )       
    321 echo ( f'{SRF_HIS         = }' )       
    322 echo ( f'{RUN_HIS         = }' ) 
    323  
    324 ## Set libIGCM directories 
    325 ## ----------------------- 
    326 if not R_OUT       : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
    327 if not R_BUF       : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
    328 if not L_EXP       : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    329 if not R_SAVE      : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    330 if not R_BUFR      : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    331 if not POST_DIR    : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
    332 if not REBUILD_DIR : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' ) 
    333 if not R_BUF_KSH   : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    334 if not R_FIGR      : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    335  
    336 config['libIGCM'].update ( { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'R_SAVE':R_SAVE, 'POST_DIR':POST_DIR, 
    337                              'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR, 'rebuild':rebuild, 
    338                              'YEAR_LENGTH':str(YEAR_LENGTH)} ) 
    339  
    340 ## Set directory to extract files 
    341 ## ------------------------------ 
    342 if not FileDir : FileDir = os.path.join ( TmpDir, f'WATER_{JobName}' ) 
    343 config['Files']['FileDir'] = FileDir 
    344  
    345 if not os.path.isdir ( FileDir ) : os.makedirs ( FileDir ) 
    346  
    347 ##- Set directories to rebuild ocean and ice restart files 
    348 if not FileDirOCE : FileDirOCE = os.path.join ( FileDir, 'OCE' ) 
    349 if not FileDirICE : FileDirICE = os.path.join ( FileDir, 'ICE' ) 
    350 if not os.path.exists ( FileDirOCE ) : os.mkdir ( FileDirOCE ) 
    351 if not os.path.exists ( FileDirICE ) : os.mkdir ( FileDirICE ) 
    352  
    353 echo (' ') 
    354 echo ( f'JobName     : {JobName}'    ) 
    355 echo ( f'Comment     : {Comment}'    ) 
    356 echo ( f'TmpDir      : {TmpDir}'     ) 
    357 echo ( f'FileDir     : {FileDir}'    ) 
    358 echo ( f'FileDirOCE  : {FileDirOCE}' ) 
    359 echo ( f'FileDirICE  : {FileDirICE}' ) 
    360  
    361 echo ( f'\nDealing with {L_EXP}'  ) 
    362  
    363 echo (' ') 
    364 echo ( f'JobName   : {JobName}'   ) 
    365 echo ( f'Comment   : {Comment}'   ) 
    366 echo ( f'TmpDir    : {TmpDir}'    ) 
    367  
    368 echo ( f'\nDealing with {L_EXP}'  ) 
    369  
    370 ## Creates model output directory names 
    371 ## ------------------------------------ 
    372 if Freq == "MO" : FreqDir =  os.path.join ('Output' , 'MO' ) 
    373 if Freq == "SE" : FreqDir =  os.path.join ('Analyse', 'SE' ) 
    374 if dir_ATM_his == None : 
    375     dir_ATM_his = os.path.join ( R_SAVE, "ATM", FreqDir ) 
    376     config['Files']['dir_ATM_his'] = dir_ATM_his 
    377 if SRF :  
    378     if dir_SRF_his == None :  
    379         dir_SRF_his = os.path.join ( R_SAVE, "SRF", FreqDir ) 
    380         config['Files']['dir_SRF_his'] = dir_SRF_his 
    381 if dir_OCE_his == None : 
    382     dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) 
    383     config['Files']['dir_OCE_his'] = dir_OCE_his 
    384 if dir_ICE_his == None :  
    385     dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) 
    386     config['Files']['dir_ICE_his'] = dir_ICE_his 
    387  
    388 echo ( f'The analysis relies on files from the following model output directories : ' ) 
    389 echo ( f'{dir_ATM_his}' ) 
    390 echo ( f'{dir_OCE_his}' ) 
    391 echo ( f'{dir_ICE_his}' ) 
    392 if SRF :  
    393     echo ( f'{dir_SRF_his}' ) 
    394  
    395 ##-- Creates files names 
    396 if not Period : 
    397     if Freq == 'MO' : Period = f'{DateBegin}_{DateEnd}_1M' 
    398     if Freq == 'SE' : Period = f'SE_{DateBegin}_{DateEnd}_1M' 
    399     config['Files']['Period'] = Period 
    400  
    401 config['Files']['DateBegin'] = DateBegin 
    402 config['Files']['DateBegin'] = DateEnd 
    403  
    404 echo ( f'Period   : {Period}' ) 
    405  
    406 if not FileCommon : 
    407     FileCommon = f'{JobName}_{Period}' 
    408     config['Files']['FileCommon'] = FileCommon 
    409  
    410 if not Title : 
    411     Title = f'{JobName} : {Freq} : {DateBegin} - {DateEnd}' 
    412     config['Files']['Title'] = Title 
    413 echo ('\nOpen history files' ) 
    414 if not file_ATM_his : 
    415     if ATM_HIS == 'latlon' : 
    416         file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth.nc' ) 
    417     if ATM_HIS == 'ico' : 
    418         file_ATM_his = os.path.join ( dir_ATM_his, f'{FileCommon}_histmth_ico.nc' ) 
    419     config['Files']['file_ATM_his'] = file_ATM_his 
    420 if SRF :  
    421     if not file_SRF_his : 
    422         if ATM_HIS == 'latlon' : 
    423             file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    424         if ATM_HIS == 'ico' : 
    425             file_SRF_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 
    426         config['Files']['file_SRF_his'] = file_SRF_his 
    427  
    428     if Routing == 'SIMPLE' : 
    429         if file_RUN_his == None : 
    430             if ATM_HIS == 'latlon' : 
    431                 file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history.nc' ) 
    432             if ATM_HIS == 'ico' : 
    433                 file_RUN_his = os.path.join ( dir_SRF_his, f'{FileCommon}_sechiba_history_ico.nc' ) 
    434             config['Files']['file_RUN_his'] = file_RUN_his 
    435  
    436 echo ( f'{file_ATM_his = }' ) 
    437 if SRF :  
    438     echo ( f'{file_SRF_his = }' ) 
    439     if Routing == 'SIMPLE' : echo ( f'{file_RUN_his = }' ) 
     129 
     130 
    440131         
    441132d_ATM_his = xr.open_dataset ( file_ATM_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     
    444135    if Routing == 'SECHIBA' : d_RUN_his = d_SRF_his 
    445136    if Routing == 'SIMPLE'  : d_RUN_his = xr.open_dataset ( file_RUN_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
    446      
    447 if not file_OCE_his : 
    448     file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
    449     file_OCE_his = file_OCE_his 
    450 if not file_OCE_sca :     
    451     file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' ) 
    452     config['Files']['file_OCE_sca'] = file_OCE_sca 
    453 if not file_OCE_srf :     
    454     file_OCE_srf = os.path.join ( dir_OCE_his, f'{FileCommon}_sbc.nc' ) 
    455     config['Files']['file_OCE_srf'] = file_OCE_srf 
    456 if not file_ICE_his :  
    457     file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' ) 
    458     config['Files']['file_ICE_his'] = file_ICE_his 
    459137 
    460138d_OCE_his = xr.open_dataset ( file_OCE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     
    486164 
    487165## Write the full configuration 
    488 config_out = open (FullIniFile, 'w') 
    489 config.write (config_out ) 
    490 config_out.close () 
     166## ---------------------------- 
     167params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     168params = wu.dict2config ( dpar ) 
     169params.write ( params_out ) 
     170params_out.close () 
    491171 
    492172# ATM grid with cell surfaces 
     
    645325# Get mask and surfaces 
    646326sos = d_OCE_his ['sos'][0].squeeze() 
    647 OCE_msk = nemo.lbc_mask ( xr.where ( sos>0, 1., 0.0 ), cd_type = 'T' ) 
     327OCE_msk = nemo.lbc_mask ( xr.where ( sos>0, 1., 0.0 ), cd_type = 'T', nperio=nperio ) 
    648328so = sos = d_OCE_his ['sos'][0].squeeze() 
    649 OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', sval = 0. ) 
     329OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', sval = 0., nperio=nperio ) 
    650330 
    651331# lbc_mask removes the duplicate points (periodicity and north fold) 
    652 OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE_msk, cd_type = 'T', sval = 0.0 ) 
     332OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE_msk, cd_type = 'T', sval = 0.0, nperio=nperio ) 
    653333ICE_aire = OCE_aire 
    654334 
     
    722402    ATM_wsnow_sic   = rprec (d_ATM_his ['wsnow_sic']) 
    723403    echo ( f'End of ico case ') 
    724  
    725  
    726404     
    727405echo ( 'ATM wprecip_oce' ) 
     
    1023701for kk in SVN.keys(): 
    1024702    print ( SVN[kk] ) 
     703 
     704## Write the full configuration 
     705## ---------------------------- 
     706params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     707params = wu.dict2config ( dpar ) 
     708params.write ( params_out ) 
     709params_out.close () 
  • TOOLS/WATER_BUDGET/OCE_waterbudget.py

    r6665 r6676  
    1414SVN = { 
    1515    'Author'  : "$Author$", 
    16     'Date'    :   "$Date$", 
     16    'Date'    : "$Date$", 
    1717    'Revision': "$Revision$", 
    18     'Id'      : "$Id: ATM_waterbudget.py 6508 2023-06-13 10:58:38Z omamce $", 
    19     'HeadURL' : "$HeadUrl: svn+ssh://omamce@forge.ipsl.jussieu.fr/ipsl/forge/projets/igcmg/svn/TOOLS/WATER_BUDGET/ATM_waterbudget.py $" 
     18    'Id'      : "$Id: $", 
     19    'HeadURL' : "$HeadUrl: $" 
    2020    } 
    2121 
     
    2929 
    3030## Import needed scientific modules 
    31 import numpy as np 
     31import numpy  as np 
    3232import xarray as xr 
    3333 
    3434## Import local module 
    3535import WaterUtils as wu 
    36 import libIGCM_sys 
    3736import nemo 
    38  
    39 from WaterUtils import RA, GRAV, ICE_RHO_ICE, ICE_RHO_SNO, OCE_RHO_LIQ, ATM_RHO, \ 
    40                        SRF_RHO, RUN_RHO, ICE_RHO_PND, YEAR_LENGTH 
    41  
    42 ## Creates parser for reading .ini input file 
    43 ## ------------------------------------------- 
    44 config = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
    45 config.optionxform = str # To keep capitals 
    46  
    47 ## Experiment parameters 
    48 ## --------------------- 
    49 JobName=None ; TagName=None ; ExperimentName=None ; SpaceName=None 
    50 SRF=True ; RUN=True 
    51 ATM=None ; ATM_HIS='latlon' ; SRF_HIS='latlon' ; RUN_HIS='latlon' ; ORCA=None 
    52 NEMO=None ; OCE_relax=False 
    53 OCE_icb=False ; Coupled=False ; Rsouting=None ; TestInterp=None 
    54 TarRestartPeriod_beg=None ; TarRestartPeriod_end=None ; Comment=None 
    55 Period=None ; Title=None 
    56 YearBegin=None ; YearEnd=None ; DateBegin=None ; DateEnd=None 
    57 Freq=None ; libIGCM=None ; User=None; Group=None ; Routing=None 
    58 PackFrequency = None ; FreqDir=None 
    59  
    60 Timer=False ; Debug=False 
    61  
    62 ## 
    63 ARCHIVE=None ; STORAGE=None ; SCRATCHDIR=None ; R_IN=None 
    64 TmpDir=None ; FileDir=None ; FileOut=None ; R_OUT=None ; R_FIG=None 
    65 R_FIGR=None ; R_BUF=None ; R_BUFR=None ; R_SAVE=None 
    66 R_BUF_KSH=None ; POST_DIR=None ; L_EXP=None 
    67  
    68 dir_ATM_his=None ; dir_SRF_his=None ; dir_OCE_his=None ; dir_ICE_his=None 
    69 FileCommon=None ; file_ATM_his=None ; file_SRF_his=None ; file_RUN_his=None 
    70 file_OCE_his=None ;  file_ICE_his=None ; file_OCE_sca=None 
    71 tar_restart_beg=None ; tar_restart_end=None ; file_ATM_beg=None 
    72 file_ATM_end=None ; file_DYN_beg=None 
    73 file_DYN_end=None ; file_SRF_beg=None ; file_SRF_end=None 
    74 file_RUN_beg=None ; file_RUN_end=None ; file_RUN_end=None ; file_OCE_beg=None 
    75 file_ICE_beg=None ; file_OCE_beg=None 
    76 file_OCE_end=None ; file_ICE_beg=None ; file_OCE_end=None ; file_ICE_end=None 
    77 TarRestartDate_beg=None ; TarRestartDate_end=None 
    78 file_DYN_aire=None 
    79 tar_restart_beg_ATM=None ; tar_restart_beg_DYN=None ; tar_restart_beg_SRF=None 
    80 tar_restart_beg_RUN=None ; tar_restart_beg_OCE=None ; tar_restart_beg_ICE=None 
    81 tar_restart_end_ATM=None ; tar_restart_end_DYN=None ; tar_restart_end_SRF=None 
    82 tar_restart_end_RUN=None ; tar_restart_end_OCE=None ; tar_restart_end_ICE=None 
    83 ContinueOnError=False ; ErrorCount=0 ; SortIco = False 
    84  
    85 d_OCE_beg=None ; d_OCE_end=None 
    86  
    87 FileDirOCE=None ; FileDirATM=None ; FileDirICE=None ; FileDirSRF=None ; FileDirRUN=None 
    88  
    89 rebuild=None ;  REBUILD_DIR=None 
    90  
    91 ## 
    92 ## Precision of history file reading 
    93 ## --------------------------------- 
    94 # Default is float (full precision). Degrade the precision by using np.float32 
    95 # Restart files are always read at the full precision 
    96 readPrec=float 
    9737 
    9838## Read command line arguments 
     
    10545    raise FileExistsError ( f"File not found : {IniFile = }" ) 
    10646 
    107 if 'full' in IniFile : FullIniFile = IniFile 
    108 else                 : FullIniFile = 'full_' + IniFile 
    109  
    110 print ("Input file : ", IniFile ) 
    111 config.read (IniFile) 
    112 FullIniFile = 'full_' + IniFile 
    113  
    114 # Reading config.card if possible 
    115 ## ------------------------------- 
    116 ConfigCard = None 
    117  
    118 if 'Experiment' in config.keys ()  : ## Read Experiment on Config file if possible 
    119     if 'ConfigCard' in config['Experiment'].keys () : 
    120         ConfigCard = config['Experiment']['ConfigCard'] 
    121         print ( f'{ConfigCard=}' ) 
    122  
    123 if ConfigCard : ## Read config card if it exists 
    124     # Text existence of ConfigCard 
    125     if os.path.exists ( ConfigCard ) : 
    126         print ( f'Reading Config Card : {ConfigCard}' ) 
    127         ## Creates parser for reading .ini input file 
    128         MyReader = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    129         MyReader.optionxform = str # To keep capitals 
    130  
    131         MyReader.read (ConfigCard) 
    132  
    133         for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName'] : 
    134             if VarName in MyReader['UserChoices'].keys() : 
    135                 locals()[VarName] = MyReader['UserChoices'][VarName] 
    136                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    137                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    138                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    139                 exec  ( f'wu.{VarName} = {VarName}' ) 
    140                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    141  
    142         for VarName in ['PackFrequency'] : 
    143             if VarName in MyReader['Post'].keys() : 
    144                 locals()[VarName] = MyReader['Post'][VarName] 
    145                 exec  ( f'{VarName} = wu.setBool ({VarName})' ) 
    146                 exec  ( f'{VarName} = wu.setNum  ({VarName})' ) 
    147                 exec  ( f'{VarName} = wu.setNone ({VarName})' ) 
    148                 exec  ( f'wu.{VarName} = {VarName}' ) 
    149                 print ( f'    {VarName:21} set to : {locals()[VarName]:}' ) 
    150     else : 
    151         raise FileExistsError ( f"File not found : {ConfigCard = }" ) 
    152  
    153 ## Reading config file 
    154 ## ------------------- 
    155 # Each entry in the .ini file will create a Python variable with the same name 
    156 for Section in config.keys () : 
    157     print ( f'\nReading [{Section}]' ) 
    158     for VarName in config[Section].keys() : 
    159         locals()[VarName] = config[Section][VarName] 
    160         exec ( f'{VarName} = wu.setBool ({VarName})' ) 
    161         exec ( f'{VarName} = wu.setNum  ({VarName})' ) 
    162         exec ( f'{VarName} = wu.setNone ({VarName})' ) 
    163         exec ( f'wu.{VarName} = {VarName}' ) 
    164         print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
    165  
    166 print ( f'\nConfig file readed : {IniFile} ' ) 
    167  
    168 ## 
    169 ## Reading prec 
    170 if not readPrec  : 
    171     readPrec = np.float64 
     47if 'full' in IniFile or 'ATM' in IniFile : 
     48    FullIniFile = IniFile 
    17249else : 
    173     if readPrec in ["float", "float64", "r8", "double", "<class 'float'>"         ] : readPrec = float 
    174     if readPrec in [         "float32", "r4", "single", "<class 'numpy.float32'>" ] : readPrec = np.float32 
    175     if readPrec in [         "float16", "r2", "half"  , "<class 'numpy.float16'>" ] : readPrec = np.float16 
    176  
    177 ## Some physical constants 
    178 ## ======================= 
    179 if not RA           : RA          = wu.RA           #-- Earth Radius (m) 
    180 if not GRAV         : GRAV        = wu.GRAV         #-- Gravity (m^2/s 
    181 if not ICE_RHO_ICE  : ICE_RHO_ICE = wu.ICE_RHO_ICE  #-- Ice volumic mass (kg/m3) in LIM3 
    182 if not ICE_RHO_SNO  : ICE_RHO_SNO = wu.ICE_RHO_SNO  #-- Snow volumic mass (kg/m3) in LIM3 
    183 if not OCE_RHO_LIQ  : OCE_RHO_LIQ = wu.OCE_RHO_LIQ  #-- Ocean water volumic mass (kg/m3) in NEMO 
    184 if not ATM_RHO      : ATM_RHO     = wu.ATM_RHO      #-- Water volumic mass in atmosphere (kg/m^3) 
    185 if not SRF_RHO      : SRF_RHO     = wu.SRF_RHO      #-- Water volumic mass in surface reservoir (kg/m^3) 
    186 if not RUN_RHO      : RUN_RHO     = wu.RUN_RHO      #-- Water volumic mass of rivers (kg/m^3) 
    187 if not ICE_RHO_PND  : ICE_RHO_PND = wu.ICE_RHO_PND  #-- Water volumic mass in ice ponds (kg/m^3) 
    188 if not YEAR_LENGTH   : YEAR_LENGTH  = wu.YEAR_LENGTH   #-- Year length (s) 
    189  
    190 ## Set libIGCM and machine dependant values 
    191 ## ---------------------------------------- 
    192 if 'Files'   not in config.keys () : config['Files']   = {} 
    193 if 'Physics' not in config.keys () : config['Physics'] = {} 
    194 if 'Config'  not in config.keys () : config['Physics'] = {} 
    195  
    196 config['Physics'].update ( { 'RA':str(RA), 'GRAV':str(GRAV), 'ICE_RHO_ICE':str(ICE_RHO_ICE), 'ICE_RHO_SNO':str(ICE_RHO_SNO), 
    197                       'OCE_RHO_LIQ':str(OCE_RHO_LIQ), 'ATM_RHO':str(ATM_RHO), 'SRF_RHO':str(SRF_RHO), 'RUN_RHO':str(RUN_RHO)} ) 
    198  
    199 config['Config'].update ( { 'ContinueOnError':str(ContinueOnError), 'TestInterp':str(TestInterp), 'readPrec':str(readPrec), 
    200                             'Debug':str(Debug), 'Timer':str(Timer)} ) 
    201  
    202 Timer = wu.functools.partial (wu.Timer, debug=False, timer=True) 
    203  
    204  
    205 ## -------------------------- 
    206 ICO  = ( 'ICO' in ATM ) 
    207 LMDZ = ( 'LMD' in ATM ) 
    208  
    209 mm = libIGCM_sys.config ( TagName=TagName, SpaceName=SpaceName, ExperimentName=ExperimentName, JobName=JobName, User=User, Group=Group, 
    210              ARCHIVE=ARCHIVE, SCRATCHDIR=SCRATCHDIR, STORAGE=STORAGE, R_IN=R_IN, R_OUT=R_OUT, R_FIG=R_FIG, rebuild=rebuild, TmpDir=TmpDir, 
    211              R_SAVE=R_SAVE, R_FIGR=R_FIGR, R_BUFR=R_BUFR, R_BUF_KSH=R_BUF_KSH, REBUILD_DIR=REBUILD_DIR, POST_DIR=POST_DIR, L_EXP=L_EXP ) 
    212 globals().update(mm) 
    213  
    214 config['Files']['TmpDir'] = TmpDir 
    215  
    216 if 'libIGCM' not in config.keys () : config['libIGCM'] = {} 
    217 config['libIGCM'].update ( { 'ARCHIVE':str(ARCHIVE), 'STORAGE':str(STORAGE), 'TmpDir':str(TmpDir), 'R_IN':str(R_IN), 'rebuild':str(rebuild) } ) 
    218  
    219 ## Debuging and timer 
    220 Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timer) 
    221  
    222 ## Defines begining and end of experiment 
    223 ## -------------------------------------- 
    224 if not DateBegin : 
    225     DateBegin = f'{YearBegin}0101' 
    226     config['Experiment']['DateBegin'] = DateBegin 
    227 else : 
    228     YearBegin, MonthBegin, DayBegin = wu.SplitDate ( DateBegin ) 
    229     DateBegin = wu.FormatToGregorian ( DateBegin) 
    230     config['Experiment']['YearBegin'] = str(YearBegin) 
    231  
    232 if not DateEnd   : 
    233     DateEnd   = f'{YearEnd}1231' 
    234     config['Experiment']['DateEnd']   = str(DateEnd) 
    235 else : 
    236     YearEnd, MonthEnd, DayEnd = wu.SplitDate ( DateEnd ) 
    237     DateEnd   = wu.FormatToGregorian ( DateEnd) 
    238     config['Experiment']['DateEnd']   = str(DateEnd) 
    239  
    240 if not PackFrequency : 
    241     PackFrequency = YearEnd - YearBegin +1 
    242     config['Experiment']['PackFrequency']   = f'{PackFrequency}' 
    243  
    244 if isinstance ( PackFrequency, str) : 
    245     if 'Y' in PackFrequency : PackFrequency = PackFrequency.replace ( 'Y', '') 
    246     if 'M' in PackFrequency : PackFrequency = PackFrequency.replace ( 'M', '') 
    247     PackFrequency = int ( PackFrequency ) 
    248  
    249 print ( f'{YearBegin=} {DateBegin=}' ) 
    250 print ( f'{YearEnd  =} {DateEnd  =}' ) 
    251 print ( f'{PackFrequency=}' ) 
     50    FullIniFile = 'ATM_' + IniFile 
     51 
     52 
     53print ("Output file : ", FullIniFile ) 
     54 
     55## Experiment parameters 
     56## --------------------- 
     57dpar = wu.ReadConfig ( IniFile ) 
     58 
     59## Configure all needed parameter from existant parameters 
     60## ------------------------------------------------------- 
     61dpar = wu.SetDatesAndFiles ( dpar) 
    25262 
    25363## Output file with water budget diagnostics 
    25464## ----------------------------------------- 
    255 if not FileOut : 
    256     FileOut = f'OCE_waterbudget_{JobName}_{YearBegin}_{YearEnd}' 
    257     if readPrec == np.float32 : FileOut = f'{FileOut}_float32' 
    258     FileOut = f'{FileOut}.out' 
    259  
    260     config['Files']['FileOut'] = FileOut 
    261  
    262 f_out = open ( FileOut, mode = 'w', encoding='utf-8' ) 
     65f_out = dpar['Files']['f_out'] 
     66 
     67## Put dpar values in local namspace 
     68## --------------------------------- 
     69for Section in dpar.keys () :  
     70    print ( f'\nReading [{Section}]' ) 
     71    for VarName in dpar[Section].keys() : 
     72        locals()[VarName] = dpar[Section][VarName] 
     73        print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
     74 
     75## Debuging and timer 
     76Timer = wu.functools.partial (wu.Timer, debug=Debug, timer=Timing) 
    26377 
    26478## Useful functions 
     
    308122    f_out.flush () 
    309123 
    310  
    311 ## Set libIGCM directories 
    312 ## ----------------------- 
    313 if not R_OUT       : R_OUT       = os.path.join ( ARCHIVE   , 'IGCM_OUT' ) 
    314 if not R_BUF       : R_BUF       = os.path.join ( SCRATCHDIR, 'IGCM_OUT' ) 
    315 if not L_EXP       : L_EXP       = os.path.join (TagName, SpaceName, ExperimentName, JobName) 
    316 if not R_SAVE      : R_SAVE      = os.path.join ( R_OUT, L_EXP ) 
    317 if not R_BUFR      : R_BUFR      = os.path.join ( R_BUF, L_EXP ) 
    318 if not POST_DIR    : POST_DIR    = os.path.join ( R_BUFR, 'Out' ) 
    319 if not REBUILD_DIR : REBUILD_DIR = os.path.join ( R_BUFR, 'REBUILD' ) 
    320 if not R_BUF_KSH   : R_BUF_KSH   = os.path.join ( R_BUFR, 'Out' ) 
    321 if not R_FIGR      : R_FIGR      = os.path.join ( STORAGE, 'IGCM_OUT', L_EXP ) 
    322  
    323 config['libIGCM'].update ( { 'R_OUT':R_OUT, 'R_BUF':R_BUF, 'L_EXP':L_EXP, 'R_BUFR':R_BUFR, 'R_SAVE':R_SAVE, 'POST_DIR':POST_DIR, 
    324                              'REBUILD_DIR':REBUILD_DIR, 'R_BUF_KSH':R_BUF_KSH, 'R_FIGR':R_FIGR, 'rebuild':rebuild, 
    325                              'YEAR_LENGTH':str(YEAR_LENGTH)} ) 
    326  
    327 ## Set directory to extract files 
    328 ## ------------------------------ 
    329 if not FileDir : FileDir = os.path.join ( TmpDir, f'WATER_{JobName}' ) 
    330 config['Files']['FileDir'] = FileDir 
    331  
    332 if not os.path.isdir ( FileDir ) : os.makedirs ( FileDir ) 
    333  
    334 ##- Set directories to rebuild ocean and ice restart files 
    335 if not FileDirOCE : FileDirOCE = os.path.join ( FileDir, 'OCE' ) 
    336 if not FileDirICE : FileDirICE = os.path.join ( FileDir, 'ICE' ) 
    337 if not os.path.exists ( FileDirOCE ) : os.mkdir ( FileDirOCE ) 
    338 if not os.path.exists ( FileDirICE ) : os.mkdir ( FileDirICE ) 
    339  
    340 echo (' ') 
    341 echo ( f'JobName    : {JobName}'   ) 
    342 echo ( f'Comment    : {Comment}'   ) 
    343 echo ( f'TmpDir     : {TmpDir}'    ) 
    344 echo ( f'FileDir    : {FileDir}'    ) 
    345 echo ( f'FileDirOCE : {FileDirOCE}' ) 
    346 echo ( f'FileDirICE : {FileDirICE}' ) 
    347  
    348 echo ( f'\nDealing with {L_EXP}'  ) 
    349  
    350 ## Creates model output directory names 
    351 ## ------------------------------------ 
    352 if Freq == "MO" : FreqDir = os.path.join ( 'Output' , 'MO' ) 
    353 if Freq == "SE" : FreqDir = os.path.join ( 'Analyse', 'SE' ) 
    354 if not dir_OCE_his : 
    355     dir_OCE_his = os.path.join ( R_SAVE, "OCE", FreqDir ) 
    356     config['Files']['dir_OCE_his'] = dir_OCE_his 
    357 if not dir_ICE_his : 
    358     dir_ICE_his = os.path.join ( R_SAVE, "ICE", FreqDir ) 
    359     config['Files']['dir_OCE_his'] = dir_OCE_his 
    360  
    361 echo (  'The analysis relies on files from the following model output directories : ' ) 
    362 echo ( f'{dir_OCE_his}' ) 
    363 echo ( f'{dir_ICE_his}' ) 
    364  
    365 #-- Creates files names 
    366 if not Period : 
    367     if Freq == 'MO' : Period = f'{DateBegin}_{DateEnd}_1M' 
    368     if Freq == 'SE' : Period = f'SE_{DateBegin}_{DateEnd}_1M' 
    369     config['Files']['Period'] = Period 
    370  
    371 config['Files']['DateBegin'] = DateBegin 
    372 config['Files']['DateBegin'] = DateEnd 
    373  
    374 echo ( f'Period   : {Period}' ) 
    375  
    376 if not FileCommon : 
    377     FileCommon = f'{JobName}_{Period}' 
    378     config['Files']['FileCommon'] = FileCommon 
    379  
    380 if not Title : 
    381     Title = f'{JobName} : {Freq} : {DateBegin} - {DateEnd}' 
    382     config['Files']['Title'] = Title 
    383  
    384 echo ('\nOpen history files' ) 
    385 if not file_OCE_his : 
    386     file_OCE_his = os.path.join ( dir_OCE_his, f'{FileCommon}_grid_T.nc' ) 
    387     config['Files']['file_OCE_his'] = file_OCE_his 
    388 if not file_OCE_sca : 
    389     file_OCE_sca = os.path.join ( dir_OCE_his, f'{FileCommon}_scalar.nc' ) 
    390     config['Files']['file_OCE_sca'] = file_OCE_sca 
    391 if not file_ICE_his : 
    392     file_ICE_his = os.path.join ( dir_ICE_his, f'{FileCommon}_icemod.nc' ) 
    393     config['Files']['file_ICE_his'] = file_ICE_his 
     124## 
     125## Open history files 
     126## ------------------ 
    394127 
    395128d_OCE_his = xr.open_dataset ( file_OCE_his, use_cftime=True, decode_times=True, decode_cf=True ).squeeze() 
     
    409142## ------------------ 
    410143dtime = ( d_OCE_his.time_counter_bounds.max() - d_OCE_his.time_counter_bounds.min() ) 
    411 echo ( '\nRun length : {(dtime/np.timedelta64(1, "D")).values:8.2f} days' ) 
     144echo ( f'\nRun length : {(dtime/np.timedelta64(1, "D")).values:8.2f} days' ) 
    412145dtime_sec = (dtime/np.timedelta64(1, "s")).values.item() # Convert in seconds 
    413146 
     
    415148## ----------------------------- 
    416149dtime_per = ( d_OCE_his.time_counter_bounds[:,-1] - d_OCE_his.time_counter_bounds[:,0] ) 
    417 echo (  '\nPeriods lengths (days) : ') 
    418 echo ( f' {(dtime_per/np.timedelta64(1, "D")).values}' ) 
     150echo (  f'\nPeriods lengths (days) : {(dtime_per/np.timedelta64(1, "D")).values}' ) 
    419151dtime_per_sec = (dtime_per/np.timedelta64(1, "s")).values # In seconds 
    420152dtime_per_sec = xr.DataArray (dtime_per_sec, dims=["time_counter", ], coords=[d_OCE_his.time_counter,] ) 
     
    424156NbYear = dtime_sec / YEAR_LENGTH 
    425157 
    426 ##-- Extract restart files from tar 
    427  
    428 if wu.unDefined ('TarRestartDate_beg' ) : TarRestartDate_beg = wu.DateMinusOneDay ( DateBegin ) 
    429 if wu.unDefined ('TarRestartDate_end' ) : TarRestartDate_end = wu.FormatToGregorian ( DateEnd ) 
    430  
    431 if not TarRestartPeriod_beg : 
    432  
    433     TarRestartPeriod_beg_DateEnd = TarRestartDate_beg 
    434     TarRestartPeriod_beg_DateBeg = wu.DateAddYear ( TarRestartPeriod_beg_DateEnd, -PackFrequency ) 
    435     TarRestartPeriod_beg_DateBeg = wu.DatePlusOneDay ( TarRestartPeriod_beg_DateBeg ) 
    436  
    437     TarRestartPeriod_beg = f'{TarRestartPeriod_beg_DateBeg}_{TarRestartPeriod_beg_DateEnd}' 
    438     echo (f'Tar period for initial restart : {TarRestartPeriod_beg}') 
    439     config['Files']['TarRestartPeriod_beg'] = TarRestartPeriod_beg 
    440  
    441 if not TarRestartPeriod_end : 
    442  
    443     TarRestartPeriod_end_DateEnd = TarRestartDate_end 
    444     TarRestartPeriod_end_DateBeg = wu.DateAddYear ( TarRestartPeriod_end_DateEnd, -PackFrequency ) 
    445     TarRestartPeriod_end_DateBeg = wu.DatePlusOneDay ( TarRestartPeriod_end_DateBeg ) 
    446  
    447     TarRestartPeriod_end = f'{TarRestartPeriod_end_DateBeg}_{TarRestartPeriod_end_DateEnd}' 
    448     echo (f'Tar period for final restart : {TarRestartPeriod_end}') 
    449     config['Files']['TarRestartPeriod_end'] = TarRestartPeriod_end 
    450  
    451 echo (f'Restart dates - Start : {TarRestartPeriod_beg}  /  End : {TarRestartPeriod_end}') 
    452  
    453 if not tar_restart_beg : 
    454     tar_restart_beg = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_beg}_restart.tar' ) 
    455     config['Files']['tar_restart_beg'] = tar_restart_beg 
    456 if not tar_restart_end : 
    457     tar_restart_end = os.path.join ( R_SAVE, 'RESTART', f'{JobName}_{TarRestartPeriod_end}_restart.tar' ) 
    458     config['Files']['tar_restart_end'] = tar_restart_end 
     158## Define restart periods and file names 
     159## ------------------------------------- 
     160dpar = wu.SetRestartNames ( dpar, f_out)  
     161 
     162## Put dpar values in local namespace 
     163## ---------------------------------- 
     164for Section in dpar.keys () :  
     165    print ( f'\nReading [{Section}]' ) 
     166    for VarName in dpar[Section].keys() : 
     167        locals()[VarName] = dpar[Section][VarName] 
     168        print ( f'    {VarName:21} set to : {locals()[VarName]}' ) 
    459169 
    460170echo ( f'{tar_restart_beg = }' ) 
    461171echo ( f'{tar_restart_end = }' ) 
    462  
    463 # 
    464 if not tar_restart_beg_ATM : tar_restart_beg_ATM = tar_restart_beg 
    465 if not tar_restart_beg_DYN : tar_restart_beg_DYN = tar_restart_beg 
    466 if not tar_restart_beg_RUN : tar_restart_beg_RUN = tar_restart_beg 
    467 if not tar_restart_beg_OCE : tar_restart_beg_OCE = tar_restart_beg 
    468 if not tar_restart_beg_ICE : tar_restart_beg_ICE = tar_restart_beg 
    469  
    470 if not tar_restart_end_ATM : tar_restart_end_ATM = tar_restart_end 
    471 if not tar_restart_end_DYN : tar_restart_end_DYN = tar_restart_end 
    472 if not tar_restart_end_RUN : tar_restart_end_RUN = tar_restart_end 
    473 if not tar_restart_end_OCE : tar_restart_end_OCE = tar_restart_end 
    474 if not tar_restart_end_ICE : tar_restart_end_ICE = tar_restart_end 
    475  
    476 if not file_OCE_beg : 
    477     file_OCE_beg = f'{FileDir}/OCE_{JobName}_{TarRestartDate_beg}_restart.nc' 
    478     config['Files']['file_OCE_beg'] = file_OCE_beg 
    479 if not file_OCE_end : 
    480     file_OCE_end = f'{FileDir}/OCE_{JobName}_{TarRestartDate_end}_restart.nc' 
    481     config['Files']['file_OCE_end'] = file_OCE_end 
    482 if not file_ICE_beg : 
    483     file_ICE_beg = f'{FileDir}/ICE_{JobName}_{TarRestartDate_beg}_restart_icemod.nc' 
    484     config['Files']['file_ICE_beg'] = file_ICE_beg 
    485 if not file_ICE_end : 
    486     file_ICE_end = f'{FileDir}/ICE_{JobName}_{TarRestartDate_end}_restart_icemod.nc' 
    487     config['Files']['file_ICE_end'] = file_ICE_end 
    488172 
    489173echo ( f'{file_OCE_beg}' ) 
     
    495179liste_end = [file_ATM_end, file_ICE_end ] 
    496180 
     181## Write the full configuration 
     182params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     183params = wu.dict2config ( dpar ) 
     184params.write ( params_out ) 
     185params_out.close () 
     186 
    497187echo ('\nExtract and rebuild OCE and ICE restarts') 
    498188def get_ndomain (zfile) : 
     189    echo ( '--- get domain -- ' ) 
     190    echo ( f'{zfile = }' ) 
    499191    #d_zfile = xr.open_dataset (zfile, decode_times=False).squeeze() 
    500192    #ndomain_opa = d_zfile.attrs['DOMAIN_number_total'] 
    501193    #d_zfile.close () 
    502194    ndomain_opa = subprocess.getoutput ( f'ls {zfile}_*.nc | wc -l' ) #.format() 
     195    echo ( f'{ndomain_opa = }' ) 
    503196    return int (ndomain_opa) 
    504197 
    505198@Timer 
    506 def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, file_dir_comp=FileDirOCE, error_count=ErrorCount ) : 
     199def extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_end, file_dir_comp=FileDirOCE ) : 
    507200    '''Extract restart file from tar. Rebuild ocean files if needed''' 
    508     echo ( '----------') 
     201    echo ( '---------- extract_and_rebuild --') 
     202    echo ( f'{file_name = }' ) 
     203    echo ( f'{tar_restart }' ) 
     204    echo ( f'{file_dir_comp = }' ) 
     205    error_count = 0 
    509206    if os.path.exists ( file_name ) : 
    510207        echo ( f'-- File ready : {file_name = }' ) 
     
    515212        if os.path.exists ( tar_restart ) : 
    516213            command =  f'cd {file_dir_comp} ; tar xf {tar_restart} {base_resFile}.nc' 
    517             echo ( command ) 
    518             try : 
    519                 os.system ( command ) 
    520             except : 
     214            echo ( f'{command = }' ) 
     215            ierr = os.system ( command ) 
     216            if ierr != 0 : 
    521217                if not os.path.exists ( os.path.join (FileDir, f'{base_resFile}_0000.nc') ): 
    522                     command =  f'cd {file_dir_comp} ; tar xf {tar_restart_end} {base_resFile}_*.nc' 
    523                     echo ( command ) 
     218                    command =  f'cd {file_dir_comp} ; tar xf {tar_restart} {base_resFile}_*.nc' 
     219                    echo ( f'{command = }' ) 
    524220                    ierr = os.system ( command ) 
    525                     if ierr == 0 : echo ( f'tar done : {base_resFile}.nc') 
    526                     else         : raise OSError ( f'command failed : {command}' ) 
     221                    if ierr == 0 : 
     222                        echo ( f'tar done : {base_resFile}.nc') 
     223                    else         : 
     224                        if ContinueOnError : 
     225                            error_count += 1 
     226                            echo ( f'****** Command failed : {command}' ) 
     227                            echo ( '****** Trying to continue' ) 
     228                            echo ( ' ') 
     229                        else : 
     230                            raise OSError ( f'command failed : {command}' ) 
    527231                    echo ( 'extract ndomain' ) 
    528                 ndomain_opa = get_ndomain ( os.path.join (FileDir, f'{base_resFile}') ) 
     232                ndomain_opa = get_ndomain ( os.path.join (file_dir_comp, f'{base_resFile}') ) 
    529233                command = f'cd {file_dir_comp} ; {rebuild} {base_resFile} {ndomain_opa} ; mv {base_resFile}.nc {FileDir}' 
    530                 echo ( command ) 
     234                echo ( f'{command = }' ) 
    531235                ierr = os.system ( command ) 
    532                 if ierr == 0 : echo ( f'Rebuild done : {base_resFile}.nc') 
    533                 else         : raise OSError ( f'command failed : {command}' ) 
     236                if ierr == 0 : 
     237                    echo ( f'Rebuild done : {base_resFile}.nc') 
     238                else         : 
     239                    if ContinueOnError : 
     240                        error_count += 1 
     241                        echo ( f'****** Command failed : {command}' ) 
     242                        echo ( '****** Trying to continue' ) 
     243                        echo ( ' ') 
     244                    else : 
     245                        raise OSError ( f'command failed : {command}' ) 
    534246            else : 
    535247                echo ( f'tar done : {base_resFile}') 
    536248                command = f'cd {file_dir_comp} ; mv {base_resFile}.nc {FileDir}' 
     249                echo ( f'{command = }' ) 
    537250                ierr = os.system ( command ) 
    538                 if ierr == 0 : echo ( f'command done : {command}' ) 
    539                 else         : raise OSError ( f'command failed : {command = }' ) 
     251                if ierr == 0 : 
     252                    echo ( f'command done : {command}' ) 
     253                else         : 
     254                    if ContinueOnError : 
     255                        error_count = 1 
     256                        echo ( f'****** Command failed : {command}' ) 
     257                        echo ( '****** Trying to continue' ) 
     258                        echo ( ' ') 
     259                    else : 
     260                        raise OSError ( f'command failed : {command = }' ) 
    540261        else : 
    541262            echo ( f'****** Tar restart file {tar_restart = } not found ' ) 
    542263            if ContinueOnError : 
    543264                error_count += 1 
     265                echo ( '****** Command failed' ) 
     266                echo ( '****** Trying to continue' ) 
     267                echo ( ' ') 
    544268            else : 
    545269                raise OSError ( f'****** tar file not found {tar_restart = } - Stopping' ) 
    546270    return error_count 
    547271 
    548 ErrorCount += extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, file_dir_comp=FileDirOCE, error_count=ErrorCount ) 
    549 ErrorCount += extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, file_dir_comp=FileDirOCE, error_count=ErrorCount ) 
    550 ErrorCount += extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, file_dir_comp=FileDirICE, error_count=ErrorCount ) 
    551 ErrorCount += extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, file_dir_comp=FileDirICE, error_count=ErrorCount ) 
     272ErrorCount = 0 
     273 
     274ErrorCount += extract_and_rebuild ( file_name=file_OCE_beg, tar_restart=tar_restart_beg, file_dir_comp=FileDirOCE ) 
     275ErrorCount += extract_and_rebuild ( file_name=file_OCE_end, tar_restart=tar_restart_end, file_dir_comp=FileDirOCE ) 
     276ErrorCount += extract_and_rebuild ( file_name=file_ICE_beg, tar_restart=tar_restart_beg, file_dir_comp=FileDirICE ) 
     277ErrorCount += extract_and_rebuild ( file_name=file_ICE_end, tar_restart=tar_restart_end, file_dir_comp=FileDirICE ) 
     278 
     279##-- Exit in case of error in the opening file phase 
     280if ErrorCount > 0 : 
     281    echo ( '  ' ) 
     282    raise RuntimeError ( f'**** Some files missing - Stopping - {ErrorCount = }' ) 
    552283 
    553284echo ('Opening OCE and ICE restart files') 
     
    563294    d_ICE_end = xr.open_dataset ( os.path.join (FileDir, file_ICE_end), decode_times=False, decode_cf=True, drop_variables=['y', 'x']).squeeze() 
    564295 
    565 ## Write the full configuration 
    566 config_out = open (FullIniFile, 'w', encoding='utf-8') 
    567 config.write (config_out ) 
    568 config_out.close () 
    569  
    570296# Get mask and surfaces 
    571297sos = d_OCE_his ['sos'][0].squeeze() 
    572 OCE_msk = nemo.lbc_mask ( xr.where ( sos>0., 1., 0. ), cd_type = 'T', sval = 0. ) 
     298OCE_msk = nemo.lbc_mask ( xr.where ( sos>0., 1., 0. ), cd_type = 'T', nperio=nperio, sval = 0. ) 
    573299 
    574300so = sos = d_OCE_his ['sos'][0].squeeze() 
    575 OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', sval = 0. ) 
     301OCE_msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', nperio=nperio, sval = 0. ) 
    576302 
    577303# lbc_mask removes the duplicate points (periodicity and north fold) 
    578 OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE_msk, cd_type = 'T', sval = 0.0 ) 
     304OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE_msk, cd_type = 'T', nperio=nperio, sval = 0.0 ) 
    579305ICE_aire = OCE_aire 
    580306 
     
    849575prtFlux ('   Leak OCE+ICE+SNW+PND ',  ( dSEA_mas_wat + OCE_mas_emp_oce +OCE_mas_emp_ice - OCE_mas_runoffs - OCE_mas_iceshelf ) , 'e', True ) 
    850576 
    851  
    852  
    853  
    854577# check if emp     = emp_ice + emp_oce - calving 
    855578#          emp_ice = wfxsub + wfxsnw_sub + wfxsnw_pre - wfxsub_err 
     
    876599echo ( 'Freshwater flux at the interface ocean-atm         = emp_oce + calving - vfxsub_err                                  = {:12.5e} (kg) '.format ( OCE_mas_emp_oce + OCE_mas_calving - ICE_mas_wfxsub_err )) 
    877600 
    878 echo ( "scsshtot   : global_average_sea_level_change                            = {:12.3e} (m) ".format ( np.sum (d_OCE_sca['scsshtot']  )  ) ) 
    879 echo ( "scsshtot   : global_average_sea_level_change                            = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['scsshtot']  ) * OCE_aire_tot*OCE_RHO_LIQ  ) ) 
    880 echo ( "bgvolssh   : drift in global mean ssh volume wrt timestep 1             = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgvolssh']  ) * 1e9 * OCE_RHO_LIQ  ) ) 
    881 echo ( "bgvole3t   : drift in global mean volume variation (e3t) wrt timestep 1 = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgvole3t']  ) * 1e9 * OCE_RHO_LIQ  ) ) 
    882 echo ( "bgfrcvol   : global mean volume from forcing                            = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgfrcvol']  ) * 1e9 * OCE_RHO_LIQ  ) ) 
    883 echo ( "ibgvol_tot : global mean ice volume                                     = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['ibgvol_tot']) * 1e9 * OCE_RHO_LIQ  ) ) 
    884 echo ( "sbgvol_tot : global mean snow volume                                    = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['sbgvol_tot']) * 1e9 * OCE_RHO_LIQ  ) ) 
    885 echo ( "ibgvolume  : drift in ice/snow volume (equivalent ocean volume)         = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['ibgvolume'] ) * 1e9 * OCE_RHO_LIQ  ) ) 
     601echo ( "scsshtot   : global_average_sea_level_change                            = {:12.3e} (m) ".format ( np.sum (d_OCE_sca['scsshtot']  ).values  ) ) 
     602echo ( "scsshtot   : global_average_sea_level_change                            = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['scsshtot']  ).values * OCE_aire_tot*OCE_RHO_LIQ  ) ) 
     603echo ( "bgvolssh   : drift in global mean ssh volume wrt timestep 1             = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgvolssh']  ).values * 1e9 * OCE_RHO_LIQ  ) ) 
     604echo ( "bgvole3t   : drift in global mean volume variation (e3t) wrt timestep 1 = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgvole3t']  ).values * 1e9 * OCE_RHO_LIQ  ) ) 
     605echo ( "bgfrcvol   : global mean volume from forcing                            = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['bgfrcvol']  ).values * 1e9 * OCE_RHO_LIQ  ) ) 
     606echo ( "ibgvol_tot : global mean ice volume                                     = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['ibgvol_tot']).values * 1e9 * OCE_RHO_LIQ  ) ) 
     607echo ( "sbgvol_tot : global mean snow volume                                    = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['sbgvol_tot']).values * 1e9 * OCE_RHO_LIQ  ) ) 
     608echo ( "ibgvolume  : drift in ice/snow volume (equivalent ocean volume)         = {:12.3e} (kg)".format ( np.sum (d_OCE_sca['ibgvolume'] ).values * 1e9 * OCE_RHO_LIQ  ) ) 
    886609 
    887610echo ( ' ' ) 
     
    891614for kk in SVN.keys(): 
    892615    print ( SVN[kk] ) 
     616 
     617## Write the full configuration 
     618params_out = open (FullIniFile, 'w', encoding = 'utf-8') 
     619params = wu.dict2config ( dpar ) 
     620params.write ( params_out ) 
     621params_out.close () 
  • TOOLS/WATER_BUDGET/WaterUtils.py

    r6665 r6676  
    2222''' 
    2323 
     24import os, sys 
    2425import functools 
    2526import time 
    2627import configparser, re 
    2728import numpy as np 
    28  
    29 VAR_INT     = 10 
    30 RHO         = 1000.0 
    31 RA          = 6366197.7236758135 #-- Earth Radius (m) 
    32 GRAV        = 9.81               #-- Gravity (m^2/s 
    33 ICE_RHO_ICE = 917.0              #-- Ice volumic mass (kg/m3) in LIM3 
    34 ICE_RHO_SNO = 330.0              #-- Snow volumic mass (kg/m3) in LIM3 
    35 OCE_RHO_LIQ = 1026.0             #-- Ocean water volumic mass (kg/m3) in NEMO 
    36 ATM_RHO     = 1000.0             #-- Water volumic mass in atmosphere (kg/m^3) 
    37 SRF_RHO     = 1000.0             #-- Water volumic mass in surface reservoir (kg/m^3) 
    38 RUN_RHO     = 1000.0             #-- Water volumic mass of rivers (kg/m^3) 
    39 ICE_RHO_PND = 1000.              #-- Water volumic mass in ice ponds (kg/m^3) 
    40 YEAR_LENGTH = 365.25 * 24. * 60. * 60. #-- Year length (s) 
     29import libIGCM_sys 
     30 
     31def ReadConfig ( ini_file, default_ini_file='defaults.ini' ) : 
     32    ''' 
     33    Reads experiment parameters 
     34 
     35    Reads <default_ini_file> config file to set all defaults parameters 
     36    Reads <ini_file> config file to set all experiment parameters 
     37    Reads config.card files if specified in <ini_file> 
     38     
     39    ''' 
     40    ## Read file with defaults values 
     41    ## ------------------------------ 
     42    params = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
     43    params.optionxform = str # To keep capitals 
     44    params.read (default_ini_file) 
     45    print ( f'\nConfig file readed : {default_ini_file} ' ) 
     46 
     47    ## Read Experiment config file 
     48    ## ---------------------------- 
     49    exp_params = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
     50    exp_params.optionxform = str # To keep capitals 
     51    exp_params.read (ini_file) 
     52    print ( f'\nConfig file readed : {ini_file} ' ) 
     53    
     54    ## Reading config.card if possible 
     55    ## ------------------------------- 
     56    if 'Experiment' in params.keys ()  : ## Read Experiment on parameter file if possible 
     57        if 'ConfigCard' in exp_params['Experiment'].keys () : 
     58            ConfigCard = exp_params['Experiment']['ConfigCard'] 
     59            print ( f'{ConfigCard=}' ) 
     60             
     61    if ConfigCard : ## Read config card if it exists 
     62        # Text existence of ConfigCard 
     63        if os.path.exists ( ConfigCard ) : 
     64            print ( f'Reading Config Card : {ConfigCard}' ) 
     65            ## Creates parser for reading .ini input file 
     66            config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
     67            config.optionxform = str # To keep capitals 
     68             
     69            config.read (ConfigCard) 
     70             
     71            for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName', 
     72                            'ORCA_version', 'ExpType', 'PeriodLength', 'ResolAtm', 'ResolOce' ] : 
     73                if VarName in config['UserChoices'].keys() : 
     74                    exp_params['Experiment'][VarName] = str2value ( config['UserChoices'][VarName] ) 
     75                     
     76            if 'Post' in config.sections() : 
     77                if 'PackFrequency' in config['Post'] : 
     78                    PackFrequency = config['Post']['PackFrequency'] 
     79                    exp_params['Experiment']['PackFrequency'] = PackFrequency 
     80                     
     81        else : 
     82            raise FileExistsError ( f"File not found : {ConfigCard = }" ) 
     83         
     84    ## Reading config file 
     85    ## ------------------- 
     86    for Section in exp_params.keys () : 
     87        params[Section].update ( exp_params[Section] ) 
     88    print ( f'\nConfig file readed : {ini_file} ' ) 
     89 
     90    return config2dict (params) 
     91     
     92def SetDatesAndFiles ( pdict ) : 
     93    ''' 
     94    From readed experiment parameters, set all needed parameters 
     95    ''' 
     96         
     97    ## Set libIGCM and machine dependant values 
     98    ## ---------------------------------------- 
     99    pdict['Experiment']['ICO']  = 'ICO' in pdict['Experiment']['ResolAtm'] 
     100    pdict['Experiment']['LMDZ'] = 'LMD' in pdict['Experiment']['ResolAtm'] 
     101 
     102    mm = libIGCM_sys.config ( TagName       = pdict['Experiment']['TagName'], 
     103                              SpaceName     = pdict['Experiment']['SpaceName'], 
     104                              ExperimentName= pdict['Experiment']['ExperimentName'], 
     105                              JobName       = pdict['Experiment']['JobName'], 
     106                              User          = pdict['Experiment']['User'], 
     107                              Group         = pdict['Experiment']['Group'], 
     108                              ARCHIVE       = pdict['libIGCM']['ARCHIVE'], 
     109                              SCRATCHDIR    = pdict['libIGCM']['SCRATCHDIR'], 
     110                              STORAGE       = pdict['libIGCM']['STORAGE'], 
     111                              R_IN          = pdict['libIGCM']['R_IN'], 
     112                              R_OUT         = pdict['libIGCM']['R_OUT'], 
     113                              R_FIG         = pdict['libIGCM']['R_FIG'], 
     114                              TmpDir        = pdict['Files']['TmpDir'], 
     115                              R_SAVE        = pdict['libIGCM']['R_SAVE'], 
     116                              R_FIGR        = pdict['libIGCM']['R_FIGR'], 
     117                              R_BUFR        = pdict['libIGCM']['R_BUFR'], 
     118                              R_BUF_KSH     = pdict['libIGCM']['R_BUF_KSH'], 
     119                              POST_DIR      = pdict['libIGCM']['POST_DIR'], 
     120                              L_EXP         = pdict['libIGCM']['L_EXP'] ) 
     121 
     122     
     123    pdict['Files']['TmpDir'] =  mm['TmpDir'] 
     124     
     125    for key in mm.keys() : 
     126        pdict['libIGCM'][key] = mm[key] 
     127         
     128    ## Complete configuration 
     129    ## ---------------------- 
     130    if not pdict['Experiment']['NEMO'] and pdict['Experiment']['ORCA_version'] : 
     131        if '1.2' in pdict['Experiment']['ORCA_version'] : 
     132            pdict['Experiment']['NEMO'] = 3.6 
     133        if '4.0' in pdict['Experiment']['ORCA_version'] : 
     134            pdict['Experiment']['NEMO'] = 4.0 
     135        if '4.2' in pdict['Experiment']['ORCA_version'] : 
     136            pdict['Experiment']['NEMO'] = 4.2 
     137             
     138    if pdict['Experiment']['ATM_HIS'] : 
     139        if not pdict['Experiment']['SRF_HIS'] : 
     140            pdict['Experiment']['SRF_HIS'] = pdict['Experiment']['ATM_HIS'] 
     141        if not pdict['Experiment']['RUN_HIS'] : 
     142            pdict['Experiment']['RUN_HIS'] = pdict['Experiment']['ATM_HIS'] 
     143             
     144    ## 
     145    ## Reading prec 
     146    if not pdict['Config']['readPrec'] : 
     147        pdict['Config']['readPrec'] = np.float64 
     148    else : 
     149        if pdict['Config']['readPrec'] in ["float", "float64", "r8", "double", "<class 'float'>"         ] : 
     150            pdict['Config']['readPrec'] = float 
     151        if pdict['Config']['readPrec'] in [         "float32", "r4", "single", "<class 'numpy.float32'>" ] : 
     152            pdict['Config']['readPrec'] = np.float32 
     153        if pdict['Config']['readPrec'] in [         "float16", "r2", "half"  , "<class 'numpy.float16'>" ] : 
     154            pdict['Config']['readPrec'] = np.float16 
     155 
     156 
     157    ## Defines begining and end of experiment 
     158    ## -------------------------------------- 
     159    if not pdict['Experiment']['DateBegin'] : 
     160        pdict['Experiment']['DateBegin'] = f"{pdict['Experiment']['YearBegin']}0101" 
     161    else : 
     162        YearBegin, MonthBegin, DayBegin = SplitDate ( pdict['Experiment']['DateBegin'] ) 
     163        DateBegin = FormatToGregorian (pdict['Experiment']['DateBegin']) 
     164        pdict['Experiment']['YearBegin'] = YearBegin 
     165         
     166    if not pdict['Experiment']['DateEnd']  : 
     167        pdict['Experiment']['DateEnd'] = f"{pdict['Experiment']['YearEnd']}1231" 
     168    else : 
     169        YearEnd, MonthEnd, DayEnd = SplitDate ( pdict['Experiment']['DateEnd'] ) 
     170        DateEnd   = FormatToGregorian (pdict['Experiment']['DateEnd']) 
     171        pdict['Experiment']['DateEnd'] = DateEnd 
     172         
     173    if not pdict['Experiment']['PackFrequency'] : 
     174        PackFrequencypdict['Experiment']['PackFrequency'] = YearEnd - YearBegin + 1 
     175         
     176    if isinstance ( pdict['Experiment']['PackFrequency'], str ) : 
     177        if 'Y' in pdict['Experiment']['PackFrequency'] : 
     178            zPackFrequency = pdict['Experiment']['PackFrequency'].replace ( 'Y', '') 
     179            pdict['Experiment']['PackFrequency'] = f'{zPackFrequency}Y' 
     180            pdict['Experiment']['zPackFrequency'] = int (zPackFrequency) 
     181        if 'M' in pdict['Experiment']['PackFrequency'] : 
     182            zPackFrequency = pdict['Experiment']['PackFrequency'].replace ( 'M', '') 
     183            pdict['Experiment']['PackFrequency'] = f'{zPackFrequency}M' 
     184            pdict['Experiment']['zPackFrequency'] = int (zPackFrequency) 
     185 
     186    ## Set directory to extract files 
     187    ## ------------------------------ 
     188    if not pdict['Files']['FileDir'] : 
     189         pdict['Files']['FileDir'] = os.path.join ( pdict['Files']['TmpDir'], f"WATER_{pdict['Experiment']['JobName']}" ) 
     190     
     191    if not os.path.isdir ( pdict['Files']['FileDir'] ) : os.makedirs ( pdict['Files']['FileDir'] ) 
     192 
     193    FileOut = str2value (pdict['Files']['FileOut']) 
     194    if not FileOut : 
     195        FileOut = f"ATM_waterbudget_{pdict['Experiment']['JobName']}_{pdict['Experiment']['YearBegin']}_{pdict['Experiment']['YearEnd']}" 
     196        if pdict['Experiment']['ICO'] : 
     197            if pdict['Experiment']['ATM_HIS'] == 'latlon' : FileOut = f'{FileOut}_LATLON' 
     198            if pdict['Experiment']['ATM_HIS'] == 'ico'    : FileOut = f'{FileOut}_ICO' 
     199            if pdict['Config']['readPrec'] == np.float32  : FileOut = f'{FileOut}_float32' 
     200        FileOut = f'{FileOut}.out' 
     201         
     202    pdict['Files']['FileOut'] = FileOut 
     203    f_out = open ( FileOut, mode = 'w', encoding="utf-8" ) 
     204    pdict['Files']['f_out'] = f_out 
     205 
     206    echo (' ', f_out) 
     207    echo ( f"JobName     : {pdict['Experiment']['JobName']}" , f_out=f_out ) 
     208    echo ( f"Comment     : {pdict['Experiment']['Comment']}" , f_out=f_out ) 
     209    echo ( f"TmpDir      : {pdict['Files']['TmpDir']}"       , f_out=f_out ) 
     210    echo ( f"FileDir     : {pdict['Files']['FileDir']}"      , f_out=f_out ) 
     211     
     212    echo ( f"\nDealing with {pdict['libIGCM']['L_EXP']}", f_out ) 
     213 
     214    ## Creates model output directory names 
     215    ## ------------------------------------ 
     216    if not pdict['Files']['FreqDir'] :  
     217        if pdict['Experiment']['Freq'] == "MO" : 
     218            pdict['Files']['FreqDir'] = os.path.join ('Output' , 'MO' ) 
     219        if pdict['Experiment']['Freq'] == "SE" : 
     220            pdict['Files']['FreqDir'] = os.path.join ('Analyse', 'SE' ) 
     221     
     222    if not pdict['Files']['dir_ATM_his'] : 
     223        pdict['Files']['dir_ATM_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "ATM", pdict['Files']['FreqDir'] ) 
     224    if not pdict['Files']['dir_SRF_his'] : 
     225        pdict['Files']['dir_SRF_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "SRF", pdict['Files']['FreqDir'] ) 
     226         
     227    if not pdict['Files']['dir_OCE_his'] : 
     228        pdict['Files']['dir_OCE_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "OCE", pdict['Files']['FreqDir'] ) 
     229    if not pdict['Files']['dir_ICE_his'] : 
     230        pdict['Files']['dir_ICE_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "ICE", pdict['Files']['FreqDir'] ) 
     231         
     232    echo (  'The analysis relies on files from the following model output directories : ', f_out ) 
     233    echo ( f"{pdict['Files']['dir_ATM_his'] = }" , f_out ) 
     234    echo ( f"{pdict['Files']['dir_SRF_his'] = }" , f_out ) 
     235    echo ( f"{pdict['Files']['dir_OCE_his'] = }" , f_out ) 
     236    echo ( f"{pdict['Files']['dir_ICE_his'] = }" , f_out ) 
     237 
     238     
     239    ## Creates files names 
     240    ## -------------------- 
     241    if not pdict['Experiment']['Period'] : 
     242        if pdict['Experiment']['Freq'] == 'MO' : 
     243            pdict['Experiment']['Period'] = f"{pdict['Experiment']['DateBegin']}_{pdict['Experiment']['DateEnd']}_1M" 
     244        if pdict['Experiment']['Freq'] == 'SE' : 
     245            pdict['Experiment']['Period'] = f"SE_{pdict['Files']['DateBegin']}_{pdict['Files']['DateEnd']}_1M" 
     246     
     247    echo ( f"Period   : {pdict['Experiment']['Period']}", f_out ) 
     248     
     249    if not pdict['Files']['FileCommon']  : 
     250        pdict['Files']['FileCommon'] = f"{pdict['Experiment']['JobName']}_{pdict['Experiment']['Period']}" 
     251         
     252    if not pdict['Files']['Title'] : 
     253        pdict['Files']['Title'] = f"{pdict['Experiment']['JobName']} : {pdict['Experiment']['Freq']} : {pdict['Experiment']['DateBegin']} - {pdict['Experiment']['DateEnd']}" 
     254         
     255    echo ('\nOpen history files', f_out ) 
     256    if not pdict['Files']['file_ATM_his'] : 
     257        if pdict['Experiment']['ATM_HIS'] == 'latlon' : 
     258            pdict['Files']['file_ATM_his'] = os.path.join ( pdict['Files']['dir_ATM_his'], f"{pdict['Files']['FileCommon']}_histmth.nc" ) 
     259        if pdict['Experiment']['ATM_HIS'] == 'ico' : 
     260            pdict['Files']['file_ATM_his'] = os.path.join ( pdict['Files']['dir_ATM_his'], f"{pdict['Files']['FileCommon']}_histmth_ico.nc" ) 
     261    if not pdict['Files']['file_SRF_his'] : 
     262        if pdict['Experiment']['ATM_HIS'] == 'latlon' : 
     263            pdict['Files']['file_SRF_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history.nc" ) 
     264        if pdict['Experiment']['ATM_HIS'] == 'ico' : 
     265            pdict['Files']['file_SRF_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history_ico.nc" ) 
     266         
     267    if pdict['Experiment']['SRF'] and pdict['Experiment']['Routing'] == 'SIMPLE' : 
     268        if not pdict['Files']['file_RUN_his'] : 
     269            if pdict['Experiment']['RUN_HIS'] == 'latlon' : 
     270                pdict['Files']['file_RUN_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history.nc" ) 
     271            if pdict['Experiment']['SRF_HIS'] == 'ico' : 
     272                pdict['Files']['file_RUN_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history_ico.nc" ) 
     273             
     274    echo ( f"{pdict['Files']['file_ATM_his'] = }", f_out ) 
     275    if pdict['Experiment']['SRF'] : 
     276        echo ( f"{pdict['Files']['file_SRF_his'] = }", f_out ) 
     277        if pdict['Experiment']['Routing'] == 'SIMPLE' : echo ( f"{pdict['Files']['file_RUN_his'] = }", f_out ) 
     278 
     279 
     280    if not pdict['Files']['file_OCE_his'] : 
     281        pdict['Files']['file_OCE_his'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_grid_T.nc" ) 
     282    if not pdict['Files']['file_OCE_sca'] : 
     283        pdict['Files']['file_OCE_sca'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_scalar.nc" ) 
     284    if not pdict['Files']['file_OCE_srf'] : 
     285        pdict['Files']['file_OCE_srf'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_sbc.nc" ) 
     286    if not pdict['Files']['file_ICE_his'] : 
     287        pdict['Files']['file_ICE_his'] = os.path.join ( pdict['Files']['dir_ICE_his'], f"{pdict['Files']['FileCommon']}_icemod.nc" ) 
     288     
     289    return pdict 
     290 
     291def SetRestartNames ( pdict, f_out) : 
     292    zdict = pdict 
     293    if not zdict['Files']['TarRestartDate_beg'] : 
     294        zdict['Files']['TarRestartDate_beg'] = DateMinusOneDay ( zdict['Experiment']['DateBegin'] ) 
     295    if not zdict['Files']['TarRestartDate_end'] : 
     296        zdict['Files']['TarRestartDate_end'] = FormatToGregorian ( zdict['Experiment']['DateEnd'] ) 
     297     
     298    if not zdict['Files']['TarRestartPeriod_beg'] : 
     299         
     300        zdict['Files']['TarRestartPeriod_beg_DateEnd'] = zdict['Files']['TarRestartDate_beg'] 
     301        zdict['Files']['TarRestartPeriod_beg_DateBeg'] = DateAddYear ( zdict['Files']['TarRestartPeriod_beg_DateEnd'], -zdict['Experiment']['zPackFrequency'] ) 
     302        zdict['Files']['TarRestartPeriod_beg_DateBeg'] = DatePlusOneDay ( zdict['Files']['TarRestartPeriod_beg_DateBeg'] ) 
     303         
     304        zdict['Files']['TarRestartPeriod_beg'] = f"{zdict['Files']['TarRestartPeriod_beg_DateBeg']}_{zdict['Files']['TarRestartPeriod_beg_DateEnd']}" 
     305        echo ( f"Tar period for initial restart : {zdict['Files']['TarRestartPeriod_beg']}", f_out) 
     306         
     307    if not zdict['Files']['TarRestartPeriod_end'] : 
     308 
     309        zdict['Files']['TarRestartPeriod_end_DateEnd'] = zdict['Files']['TarRestartDate_end'] 
     310        zdict['Files']['TarRestartPeriod_end_DateBeg'] = DateAddYear ( zdict['Files']['TarRestartPeriod_end_DateEnd'], -zdict['Experiment']['zPackFrequency'] ) 
     311        zdict['Files']['TarRestartPeriod_end_DateBeg'] = DatePlusOneDay ( zdict['Files']['TarRestartPeriod_end_DateBeg']) 
     312         
     313        zdict['Files']['TarRestartPeriod_end'] = f"{zdict['Files']['TarRestartPeriod_end_DateBeg']}_{zdict['Files']['TarRestartPeriod_end_DateEnd']}" 
     314        echo ( f"Tar period for final restart : {zdict['Files']['TarRestartPeriod_end']}", f_out ) 
     315         
     316    echo ( f"Restart dates - Start : {zdict['Files']['TarRestartPeriod_beg']}  /  End : {zdict['Files']['TarRestartPeriod_end']}", f_out) 
     317         
     318    if not zdict['Files']['tar_restart_beg'] : 
     319        zdict['Files']['tar_restart_beg'] = os.path.join ( zdict['libIGCM']['R_SAVE'], 'RESTART', f"{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartPeriod_beg']}_restart.tar" ) 
     320    if not  zdict['Files']['tar_restart_end'] : 
     321        zdict['Files']['tar_restart_end'] = os.path.join ( zdict['libIGCM']['R_SAVE'], 'RESTART', f"{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartPeriod_end']}_restart.tar" ) 
     322         
     323    echo ( f"{ zdict['Files']['tar_restart_beg'] = }", f_out ) 
     324    echo ( f"{ zdict['Files']['tar_restart_end'] = }", f_out ) 
     325 
     326    ##-- Names of tar files with restarts 
     327     
     328    if not zdict['Files']['tar_restart_beg_ATM'] : 
     329        zdict['Files']['tar_restart_beg_ATM'] = zdict['Files']['tar_restart_beg'] 
     330    if not zdict['Files']['tar_restart_beg_DYN'] : 
     331        zdict['Files']['tar_restart_beg_DYN'] = zdict['Files']['tar_restart_beg'] 
     332    if not zdict['Files']['tar_restart_beg_RUN'] : 
     333        zdict['Files']['tar_restart_beg_RUN'] = zdict['Files']['tar_restart_beg'] 
     334    if not zdict['Files']['tar_restart_beg_OCE'] : 
     335        zdict['Files']['tar_restart_beg_OCE'] = zdict['Files']['tar_restart_beg'] 
     336    if not zdict['Files']['tar_restart_beg_ICE'] : 
     337        zdict['Files']['tar_restart_beg_ICE'] = zdict['Files']['tar_restart_beg'] 
     338         
     339    if not zdict['Files']['tar_restart_end_ATM'] : 
     340        zdict['Files']['tar_restart_end_ATM'] = zdict['Files']['tar_restart_end'] 
     341    if not zdict['Files']['tar_restart_end_DYN'] : 
     342        zdict['Files']['tar_restart_end_DYN'] = zdict['Files']['tar_restart_end'] 
     343    if not zdict['Files']['tar_restart_end_RUN'] : 
     344        zdict['Files']['tar_restart_end_RUN'] = zdict['Files']['tar_restart_end'] 
     345    if not zdict['Files']['tar_restart_end_OCE'] : 
     346        zdict['Files']['tar_restart_end_OCE'] = zdict['Files']['tar_restart_end'] 
     347    if not zdict['Files']['tar_restart_end_ICE'] : 
     348        zdict['Files']['tar_restart_end_ICE'] = zdict['Files']['tar_restart_end'] 
     349         
     350    if not zdict['Files']['file_DYN_beg'] : 
     351        if zdict['Experiment']['LMDZ'] : 
     352            zdict['Files']['file_DYN_beg'] = f"{zdict['Files']['FileDir']}/ATM_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_restart.nc" 
     353        if zdict['Experiment']['ICO']  : 
     354            zdict['Files']['file_DYN_beg'] = f"{zdict['Files']['FileDir']}/ICO_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_restart.nc" 
     355         
     356    if not zdict['Files']['file_DYN_end'] : 
     357        if zdict['Experiment']['LMDZ'] : 
     358            zdict['Files']['file_DYN_end'] = f"{zdict['Files']['FileDir']}/ATM_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_restart.nc" 
     359        if zdict['Experiment']['ICO']  : 
     360            zdict['Files']['file_DYN_end'] = f"{zdict['Files']['FileDir']}/ICO_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_restart.nc" 
     361         
     362    if zdict['Experiment']['SRF'] : 
     363        if not zdict['Files']['file_SRF_beg'] : 
     364            zdict['Files']['file_SRF_beg'] = f"{zdict['Files']['FileDir']}/SRF_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_sechiba_rest.nc" 
     365        if not zdict['Files']['file_SRF_end'] : 
     366            zdict['Files']['file_SRF_end'] = f"{zdict['Files']['FileDir']}/SRF_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_sechiba_rest.nc" 
     367         
     368    if zdict['Experiment']['SRF'] : 
     369        if not zdict['Files']['tar_restart_beg_SRF'] : 
     370            zdict['Files']['tar_restart_beg_SRF'] = zdict['Files']['tar_restart_beg'] 
     371        if not zdict['Files']['tar_restart_end_SRF'] : 
     372            zdict['Files']['tar_restart_end_SRF'] = zdict['Files']['tar_restart_end'] 
     373             
     374    if not zdict['Files']['file_ATM_beg'] : 
     375        zdict['Files']['file_ATM_beg'] = f"{zdict['Files']['FileDir']}/ATM_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_restartphy.nc" 
     376    if not zdict['Files']['file_ATM_end'] : 
     377        zdict['Files']['file_ATM_end'] = f"{zdict['Files']['FileDir']}/ATM_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_restartphy.nc" 
     378         
     379    if zdict['Experiment']['SRF'] : 
     380        echo ( f"{zdict['Files']['file_SRF_beg'] = }", f_out) 
     381        echo ( f"{zdict['Files']['file_SRF_end'] = }", f_out) 
     382         
     383    if zdict['Experiment']['ICO'] : 
     384        if not zdict['Files']['file_DYN_aire'] : 
     385            zdict['Files']['file_DYN_aire'] = os.path.join ( zdict['libIGCM']['R_IN'], 'ATM', 'GRID',  f"{zdict['Experiment']['ResolAtm']}_grid.nc" ) 
     386         
     387    if zdict['Experiment']['SRF'] and zdict['Experiment']['Routing'] == 'SIMPLE' : 
     388        if not zdict['Files']['file_RUN_beg'] : 
     389            zdict['Files']['file_RUN_beg'] = f"{ zdict['Files']['FileDir']}/SRF_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_routing_restart.nc" 
     390        if not zdict['Files']['file_RUN_end'] : 
     391            zdict['Files']['file_RUN_end'] = f"{ zdict['Files']['FileDir']}/SRF_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_routing_restart.nc" 
     392 
     393    if not zdict['Files']['tar_restart_beg_OCE'] : 
     394        zdict['Files']['tar_restart_beg_OCE'] = zdict['Files']['tar_restart_beg'] 
     395    if not zdict['Files']['tar_restart_beg_ICE'] : 
     396        zdict['Files']['tar_restart_beg_ICE'] = zdict['Files']['tar_restart_beg'] 
     397         
     398    if not zdict['Files']['tar_restart_end_OCE'] : 
     399        zdict['Files']['tar_restart_end_OCE'] = zdict['Files']['tar_restart_end'] 
     400    if not zdict['Files']['tar_restart_end_ICE'] : 
     401        zdict['Files']['tar_restart_end_ICE'] = zdict['Files']['tar_restart_end'] 
     402         
     403    if not zdict['Files']['file_OCE_beg'] : 
     404        zdict['Files']['file_OCE_beg'] = f"{zdict['Files']['FileDir']}/OCE_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_restart.nc" 
     405    if not zdict['Files']['file_OCE_end'] : 
     406        zdict['Files']['file_OCE_end'] = f"{zdict['Files']['FileDir']}/OCE_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_restart.nc" 
     407    if not zdict['Files']['file_ICE_beg'] : 
     408        zdict['Files']['file_ICE_beg'] = f"{zdict['Files']['FileDir']}/ICE_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_beg']}_restart_icemod.nc" 
     409    if not zdict['Files']['file_ICE_end'] : 
     410        zdict['Files']['file_ICE_end'] = f"{zdict['Files']['FileDir']}/ICE_{zdict['Experiment']['JobName']}_{zdict['Files']['TarRestartDate_end']}_restart_icemod.nc" 
     411             
     412    return zdict 
     413 
     414def config2dict ( pconf ) : 
     415    ''' 
     416    Convert a config parser object into a dictionary 
     417    ''' 
     418    zdict = {} 
     419    for section in pconf.keys () : 
     420        zdict[section] = {} 
     421        for key in pconf[section].keys() : 
     422            zz = str2value ( pconf[section][key] ) 
     423            zdict[section].update ( {key:zz} )         
     424    return zdict 
     425 
     426def dict2config ( pdict ): 
     427    ''' 
     428    Convert a dictionary into a configparser object 
     429 
     430    The dictionary should have two levels (see configparser) 
     431    ''' 
     432    zconf = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) 
     433    zconf.optionxform = str # To keep capitals 
     434     
     435    for section in pdict.keys () : 
     436        zconf[section] = {} 
     437        for key in pdict[section].keys() : 
     438            zconf[section][key] = str (pdict[section][key]  )   
     439     
     440    return zconf 
     441 
     442# def updateConf ( pconf, pdict ): 
     443#     ''' 
     444#     Update a config parser with a dictionary 
     445#     ''' 
     446#     zconf = pconf 
     447#     for section in pdict.keys() : 
     448#         if section not in pconf.keys() : pconf[section] = {} 
     449#         for key in pdict[section].keys() : 
     450#             pconf[section][key] = str(pdict[section][key]) 
     451#     return pconf 
     452     
     453def echo (string, f_out, end='\n') : 
     454    '''Function to print to stdout *and* output file''' 
     455    print ( str(string), end=end  ) 
     456    sys.stdout.flush () 
     457    f_out.write ( str(string) + end ) 
     458    f_out.flush () 
     459 
     460def str2value ( pz ) : 
     461    ''' 
     462    Tries to convert a string into integer, real, boolean or None 
     463    ''' 
     464    zz = pz 
     465    zz = setBool (zz) 
     466    zz = setNum  (zz) 
     467    zz = setNone (zz) 
     468    return zz 
    41469 
    42470def setBool (chars) : 
     
    65493def setNone (chars) : 
    66494    '''Convert specific char string to None if possible''' 
     495    zset_none = chars 
    67496    if isinstance (chars, str) : 
    68497        if chars in ['None', 'NONE', 'none'] : zset_none = None 
    69         else : zset_none = chars 
    70     else : zset_none = chars 
    71498    return zset_none 
    72499 
     
    255682class Timer : 
    256683    '''Measures execution time of a function''' 
    257     def __str__(self): 
    258         return str(self.__class__) 
    259      
    260     def __name__(self): 
     684    def __str__ (self): 
     685        return str (self.__class__) 
     686     
     687    def __name__ (self): 
    261688        return self.__class__.__name__ 
    262689 
  • TOOLS/WATER_BUDGET/libIGCM_sys.py

    r6652 r6676  
    2424''' 
    2525 
    26 import sys, os, subprocess, configparser, re, types 
     26import os, subprocess, configparser, types 
    2727from pathlib import Path 
    2828 
     
    3030SysName, NodeName, Release, Version, Machine = os.uname () 
    3131 
    32 def unDefined (char) : 
    33     '''Returns True if a variable is not defined, ot if it's set to None''' 
    34     if char in globals () : 
    35         if globals ()[char] == None or  globals ()[char] == 'None': unDefined = True 
    36         else                                                      : unDefined = False 
    37     else : unDefined = True 
    38     return unDefined 
    39  
    40 def Mach ( Long=False) : 
     32# def unDefined (char) : 
     33#     '''Returns True if a variable is not defined, ot if it's set to None''' 
     34#     if char in globals () : 
     35#         if globals ()[char] == None or  globals ()[char] == 'None': unDefined = True 
     36#         else                                                      : unDefined = False 
     37#     else : unDefined = True 
     38#     return unDefined 
     39 
     40def Mach ( long=False) : 
    4141    ''' 
    4242    Find the computer we are on 
    4343 
    44     On Irene, Mach returns Irene, Irene-Next, Rome or Rome-Prev if Long==True 
     44    On Irene, Mach returns Irene, Irene-Next, Rome or Rome-Prev if long==True 
    4545    ''' 
    46      
    47     Mach = 'unknown' 
    48      
    49     if SysName == 'Darwin' and 'lsce5138' in NodeName : Mach = 'Spip' 
    50     if 'obelix'    in NodeName : Mach = 'Obelix' 
    51     if 'forge'     in NodeName : Mach = 'Forge' 
    52     if 'ciclad'    in NodeName : Mach = 'Ciclad'  
    53     if 'climserv'  in NodeName : Mach = 'SpiritX' 
    54     if 'spirit'    in NodeName : Mach = 'SpiritJ' 
    55     if 'spiritj'   in NodeName : Mach = 'SpiritJ' 
    56     if 'spiritx'   in NodeName : Mach = 'SpiritX' 
    57     if 'irene'     in NodeName : Mach = 'Irene' 
    58     if 'jean-zay'  in NodeName : Mach = 'Jean-Zay' 
    59  
    60     if Long :  
    61         MachFull = Mach 
    62      
    63         if Mach == 'Irene' : 
     46 
     47    zmach = None 
     48 
     49    if SysName == 'Darwin' and 'lsce5138' in NodeName : zmach = 'Spip' 
     50    if 'obelix'    in NodeName : zmach = 'Obelix' 
     51    if 'forge'     in NodeName : zmach = 'Forge' 
     52    if 'ciclad'    in NodeName : zmach = 'Ciclad' 
     53    if 'climserv'  in NodeName : zmach = 'SpiritX' 
     54    if 'spirit'    in NodeName : zmach = 'SpiritJ' 
     55    if 'spiritj'   in NodeName : zmach = 'SpiritJ' 
     56    if 'spiritx'   in NodeName : zmach = 'SpiritX' 
     57    if 'irene'     in NodeName : zmach = 'Irene' 
     58    if 'jean-zay'  in NodeName : zmach = 'Jean-Zay' 
     59 
     60    if long : 
     61        zmachfull = zmach 
     62 
     63        if zmach == 'Irene' : 
    6464            CPU    = subprocess.getoutput ('lscpu') 
    6565            ccc_os = subprocess.getoutput ('ccc_os') 
    66          
     66 
    6767            if "Intel(R) Xeon(R) Platinum" in CPU : 
    68                 if "Atos_7__x86_64" in ccc_os : MachFull = 'Irene-Prev' 
    69                 if "Rhel_8__x86_64" in ccc_os : MachFull = 'Irene' 
    70                      
    71             if "AMD" in CPU :  
    72                 if "Atos_7__x86_64" in ccc_os : MachFull = 'Rome-Prev' 
    73                 if "Rhel_8__x86_64" in ccc_os : MachFull = 'Rome' 
    74  
    75         Mach = MachFull 
    76                  
    77     return Mach 
     68                zmachfull = 'Irene' 
     69 
     70            if "AMD" in CPU : 
     71                zmachfull = 'Rome' 
     72 
     73        zmach = zmachfull 
     74 
     75    return zmach 
    7876 
    7977def config ( JobName=None , TagName=None  , SpaceName=None, ExperimentName=None, 
     
    8179             Source=None  , Host=None     , ConfigCard=None, User=None, Group=None, 
    8280             TGCC_User='p86mart', TGCC_Group='gen12006', IDRIS_User='rces009', IDRIS_Group='ces', 
    83              ARCHIVE=None, SCRATCHDIR=None, STORAGE=None, R_IN=None, R_OUT=None, R_FIG=None, L_EXP=None, 
    84              R_SAVE=None , R_FIGR=None, R_BUF=None , R_BUFR=None, R_BUF_KSH=None, REBUILD_DIR=None, POST_DIR=None, 
    85              ThreddsPrefix=None, R_GRAF=None, DB=None,  
     81             ARCHIVE=None, SCRATCHDIR=None, STORAGE=None, R_IN=None, R_OUT=None, 
     82             R_FIG=None, L_EXP=None, 
     83             R_SAVE=None , R_FIGR=None, R_BUF=None , R_BUFR=None, R_BUF_KSH=None, 
     84             REBUILD_DIR=None, POST_DIR=None, 
     85             ThreddsPrefix=None, R_GRAF=None, DB=None, 
    8686             IGCM_OUT=None, IGCM_OUT_name=None, rebuild=None, TmpDir=None, 
    8787             Out='dict') : 
     
    9090 
    9191    Source : for Spip 
    92           Possibilities :  
     92          Possibilities : 
    9393          Local        : local (~/Data/IGCMG/...) 
    9494          TGCC_sshfs   : TGCC disks mounted via sshfs 
    95           TGCC_thredds : thredds TGCC via IPSL  ('https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds/store/...)  
     95          TGCC_thredds : thredds TGCC via IPSL 
     96                          ('https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds/store/...) 
    9697 
    9798    Exemple of use : 
     
    104105    #    else                        : IGCM_OUT_name = 'IGCM_OUT' 
    105106 
    106     if not Host : Host = Mach (Long=False) 
     107    if not Host : Host = Mach (long=False) 
    107108 
    108109    LocalUser = os.environ ['USER'] 
    109          
     110 
    110111    # =========================================================================================== 
    111112    # Reads config.card if available 
     
    118119        MyReader = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) 
    119120        MyReader.optionxform = str # To keep capitals 
    120          
     121 
    121122        MyReader.read (ConfigCard) 
    122          
     123 
    123124        JobName        = MyReader['UserChoices']['JobName'] 
    124125        #----- Short Name of Experiment 
     
    130131        TagName        = MyReader['UserChoices']['TagName'] 
    131132 
    132     ### ===========================================================================================           
     133    ### =========================================================================================== 
    133134    ## Part specific to access by OpenDAP/Thredds server 
    134135 
     
    138139        if not Group and TGCC_Group : Group = TGCC_Group 
    139140 
    140         if not ThreddsPrefix : ThreddsPrefix = 'https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds' 
    141                  
     141        if not ThreddsPrefix : 
     142            ThreddsPrefix = 'https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds' 
     143 
    142144        if not ARCHIVE : ARCHIVE = f'{ThreddsPrefix}/store/{TGCC_User}' 
    143145        if not R_FIG   : R_FIG   = f'{ThreddsPrefix}/work/{TGCC_User}' 
     
    149151        if not User  and IDRIS_User  : User  = IDRIS_User 
    150152        if not Group and IDRIS_Group : Group = IDRIS_Group 
    151              
    152         if not ThreddsPrefix : ThreddsPrefix = 'https://thredds-su.ipsl.fr/thredds/catalog/idris_thredds' 
    153                            
     153 
     154        if not ThreddsPrefix : 
     155            ThreddsPrefix = 'https://thredds-su.ipsl.fr/thredds/catalog/idris_thredds' 
     156 
    154157        if not ARCHIVE : ARCHIVE = f'{ThreddsPrefix}/store/{IDRIS_User}' 
    155158        if not R_FIG   : R_FIG   = f'{ThreddsPrefix}/work/{IDRIS_User}' 
    156159        if not R_IN    : R_IN    = f'{ThreddsPrefix}/work/igcmg/IGCM' 
    157         if not R_GRAF  : R_GRAF  = f'https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds/work/p86mart/GRAF/DATA' 
    158  
    159     ### ===========================================================================================           
     160        if not R_GRAF  : R_GRAF  = \ 
     161            'https://thredds-su.ipsl.fr/thredds/dodsC/tgcc_thredds/work/p86mart/GRAF/DATA' 
     162 
     163    ### =========================================================================================== 
    160164    ## Machine dependant part 
    161165 
     
    177181    # =========================================================================================== 
    178182    if ( 'Irene' in Host ) or ( 'Rome' in Host ) : 
    179         LocalHome  = subprocess.getoutput ( f'ccc_home --ccchome' ) 
     183        
     184        LocalHome  = subprocess.getoutput ( 'ccc_home --ccchome' ) 
    180185        LocalGroup = os.path.basename ( os.path.dirname (LocalHome)) 
    181186        if not User or User == 'marti' : 
    182187            if not TGCC_User : User = LocalUser 
    183188            else             : User = TGCC_User 
    184              
     189 
    185190        if not Group : 
    186191            if TGCC_Group : Group = TGCC_Group 
     
    188193 
    189194        IGCM_OUT_name = 'IGCM_OUT' 
    190            
    191         if not R_IN        : R_IN       = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM') 
    192         if not ARCHIVE     : ARCHIVE    = subprocess.getoutput ( f'ccc_home --cccstore   -u {User} -d {Group}' ) 
    193         if not STORAGE     : STORAGE    = subprocess.getoutput ( f'ccc_home --cccwork    -u {User} -d {Group}' ) 
    194         if not SCRATCHDIR  : SCRATCHDIR = subprocess.getoutput ( f'ccc_home --cccscratch -u {User} -d {Group}' ) 
    195         if not R_BUF       : R_BUF      = subprocess.getoutput ( f'ccc_home --cccscratch -u {User} -d {Group}' ) 
    196         if not R_FIG       : R_FIG      = subprocess.getoutput ( f'ccc_home --cccwork    -u {User} -d {Group}' ) 
    197         if not R_GRAF      : R_GRAF     = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d drf -u p86mart'), 'GRAF', 'DATA' ) 
    198         if not DB          : DB         = os.path.join ( subprocess.getoutput ( f'ccc_home --cccwork -d igcmg -u igcmg'), 'database' ) 
     195 
     196        if not R_IN        : 
     197            R_IN       = os.path.join ( subprocess.getoutput ( 
     198                'ccc_home --cccwork -d igcmg -u igcmg' ), 'IGCM') 
     199        if not ARCHIVE     : 
     200            ARCHIVE    = subprocess.getoutput ( 
     201                f'ccc_home --cccstore   -u {User} -d {Group}' ) 
     202        if not STORAGE     : 
     203            STORAGE    = subprocess.getoutput ( 
     204                f'ccc_home --cccwork    -u {User} -d {Group}' ) 
     205        if not SCRATCHDIR  : 
     206            SCRATCHDIR = subprocess.getoutput ( 
     207                f'ccc_home --cccscratch -u {User} -d {Group}' ) 
     208        if not R_BUF       : 
     209            R_BUF      = subprocess.getoutput ( 
     210                f'ccc_home --cccscratch -u {User} -d {Group}' ) 
     211        if not R_FIG       : 
     212            R_FIG      = subprocess.getoutput ( 
     213                f'ccc_home --cccwork    -u {User} -d {Group}' ) 
     214        if not R_GRAF      : 
     215            R_GRAF     = os.path.join ( subprocess.getoutput ( 
     216                'ccc_home --cccwork -d drf -u p86mart'), 'GRAF', 'DATA' ) 
     217        if not DB          : 
     218            DB         = os.path.join ( subprocess.getoutput ( 
     219                'ccc_home --cccwork -d igcmg -u igcmg'), 'database' ) 
    199220        if not rebuild : 
    200             rebuild = os.path.join ( subprocess.getoutput ( f'ccc_home --ccchome -d igcmg -u igcmg' ), 'Tools', Machine, 'rebuild_nemo', 'bin', 'rebuild_nemo' ) 
     221                rebuild = os.path.join ( 
     222                    subprocess.getoutput ( 'ccc_home --ccchome -d igcmg -u igcmg' ), 
     223                    'Tools', 'irene', 'rebuild_nemo', 'bin', 'rebuild_nemo' ) 
     224                 
    201225        if not TmpDir : TmpDir = subprocess.getoutput ( f'ccc_home --cccscratch' ) 
    202              
     226 
    203227    # =========================================================================================== 
    204228    if Host == 'SpiritJ' : 
     
    206230            if TGCC_User  : User = TGCC_User 
    207231            else          : User = LocalUser 
    208         if not ARCHIVE    : ARCHIVE    = os.path.join ( '/', 'thredds'  , 'tgcc', 'store', User ) 
    209         if not  STORAGE   : STORAGE    = os.path.join ( '/', 'thredds'  , 'tgcc', 'work' , User ) 
     232        if not ARCHIVE    : 
     233            ARCHIVE    = os.path.join ( '/', 'thredds', 'tgcc', 'store', User ) 
     234        if not  STORAGE   : 
     235            STORAGE    = os.path.join ( '/', 'thredds', 'tgcc', 'work' , User ) 
    210236        #if not SCRATCHDIR : SCRATCHDIR = os.path.join ( '/', 'thredds'  , 'tgcc', 'store', User ) 
    211         if not R_IN       : R_IN       = os.path.join ( '/', 'projsu', 'igcmg', 'IGCM' ) 
     237        if not R_IN       : 
     238            R_IN       = os.path.join ( '/', 'projsu', 'igcmg', 'IGCM' ) 
    212239        #if not R_GRAF     : R_GRAF     = os.path.join ('/', 'data', 'omamce', 'GRAF', 'DATA' ) 
    213         if not R_GRAF     : R_GRAF     = os.path.join  ( '/', 'thredds'  , 'tgcc', 'work' , 'p86mart', 'GRAF', 'DATA' ) 
    214         if not DB         : DB         = os.path.join  ( '/', 'data', 'igcmg', 'database' ) 
    215         if not TmpDir     : TmpDir = os.path.join ( '/', 'data', LocalUser ) 
    216              
     240        if not R_GRAF     : 
     241            R_GRAF     = os.path.join  ( '/', 'thredds', 'tgcc', 'work', 'p86mart', 'GRAF', 'DATA' ) 
     242        if not DB         : 
     243            DB         = os.path.join  ( '/', 'data', 'igcmg', 'database' ) 
     244        if not TmpDir     : 
     245            TmpDir = os.path.join ( '/', 'data', LocalUser ) 
     246 
    217247    # =========================================================================================== 
    218248    if Host == 'SpiritX' : 
     
    220250            if TGCC_User  : User  = TGCC_User 
    221251            else          : User = os.environ ['USER'] 
    222         if not ARCHIVE    : ARCHIVE    = os.path.join ( '/', 'thredds'  , 'tgcc', 'store', User ) 
    223         if not  STORAGE   : STORAGE    = os.path.join ( '/', 'thredds'  , 'tgcc', 'work' , User ) 
    224         #if not SCRATCHDIR : SCRATCHDIR = os.path.join ( '/', 'thredds'  , 'tgcc', 'store', User ) 
    225         if not R_IN       : R_IN       = os.path.join ( '/', 'projsu', 'igcmg', 'IGCM' ) 
    226         #if not R_GRAF     : R_GRAF     = os.path.join ('/', 'data', 'omamce', 'GRAF', 'DATA' ) 
    227         if not R_GRAF     : R_GRAF     = os.path.join  ( '/', 'thredds'  , 'tgcc', 'work' , 'p86mart', 'GRAF', 'DATA' ) 
    228         if not DB         : DB         = os.path.join  ( '/', 'data', 'igcmg', 'database' ) 
     252        if not ARCHIVE    : 
     253            ARCHIVE    = os.path.join ( '/', 'thredds', 'tgcc', 'store', User ) 
     254        if not  STORAGE   : 
     255            STORAGE    = os.path.join ( '/', 'thredds', 'tgcc', 'work' , User ) 
     256        #if not SCRATCHDIR : 
     257        #  SCRATCHDIR = os.path.join ( '/', 'thredds', 'tgcc', 'store', User ) 
     258        if not R_IN       : 
     259            R_IN       = os.path.join ( '/', 'projsu', 'igcmg', 'IGCM' ) 
     260        #if not R_GRAF     : 
     261        #    R_GRAF     = os.path.join ('/', 'data', 'omamce', 'GRAF', 'DATA' ) 
     262        if not R_GRAF     : 
     263            R_GRAF     = os.path.join  ( '/', 'thredds', 'tgcc', 'work' , 'p86mart', 'GRAF', 'DATA' ) 
     264        if not DB         : 
     265            DB         = os.path.join  ( '/', 'data', 'igcmg', 'database' ) 
    229266 
    230267    # =========================================================================================== 
     
    233270        LocalGroup = os.path.basename ( os.path.dirname ( Path.home () )) 
    234271        if not Group : Group = LocalGroup 
    235              
    236         if not ARCHIVE    : ARCHIVE    = os.path.join ( '/', 'gpfsstore'  , 'rech', Group, User ) 
    237         if not STORAGE    : STORAGE    = os.path.join ( '/', 'gpfswork'   , 'rech', Group, User ) 
    238         if not SCRATCHDIR : SCRATCHDIR = os.path.join ( '/', 'gpfsscratch', 'rech', Group, User ) 
    239         if not R_FIG      : R_FIG      = os.path.join ( '/', 'cccwork'    , 'rech', Group, User ) 
    240         if not R_BUF      : R_BUF      = os.path.join ( '/', 'gpfsscratch', 'rech', Group, User ) 
    241         if not R_IN       : R_IN       = os.path.join ( '/', 'gpfswork'   , 'rech', 'psl', 'commun', 'IGCM' ) 
    242         if not R_GRAF     : R_GRAF     = os.path.join ( '/', 'gpfswork'   , 'rech', Group, User, 'GRAF', 'DATA' ) 
    243         if not DB         : DB         = os.path.join ( '/', 'gpfswork'   , 'rech', 'psl', 'commun', 'database' ) 
     272 
     273        if not ARCHIVE    : 
     274            ARCHIVE    = os.path.join ( '/', 'gpfsstore'  , 'rech', Group, User ) 
     275        if not STORAGE    : 
     276            STORAGE    = os.path.join ( '/', 'gpfswork'   , 'rech', Group, User ) 
     277        if not SCRATCHDIR : 
     278            SCRATCHDIR = os.path.join ( '/', 'gpfsscratch', 'rech', Group, User ) 
     279        if not R_FIG      : 
     280            R_FIG      = os.path.join ( '/', 'cccwork'    , 'rech', Group, User ) 
     281        if not R_BUF      : 
     282            R_BUF      = os.path.join ( '/', 'gpfsscratch', 'rech', Group, User ) 
     283        if not R_IN       : 
     284            R_IN       = os.path.join ( '/', 'gpfswork'   , 'rech', 'psl', 'commun', 'IGCM' ) 
     285        if not R_GRAF     : 
     286            R_GRAF     = os.path.join ( '/', 'gpfswork'   , 'rech', Group, User, 'GRAF', 'DATA' ) 
     287        if not DB         : 
     288            DB         = os.path.join ( '/', 'gpfswork'   , 'rech', 'psl', 'commun', 'database' ) 
    244289        if not rebuild : 
    245             rebuild = os.path.join ( '/', 'gpfswork', 'rech', 'psl', 'commun', 'Tools', 'rebuild', 'modipsl_IOIPSL_PLUS_v2_2_4', 'bin', 'rebuild' ) 
    246         if not TmpDir : TmpDir = os.path.join ( '/', 'gpfsscratch', 'rech', os.path.basename ( os.path.dirname ( Path.home () )), LocalUser ) 
    247              
    248     ### ===========================================================================================           
     290            rebuild = os.path.join ( '/', 'gpfswork', 'rech', 'psl', 'commun', 'Tools', 
     291                                         'rebuild', 'modipsl_IOIPSL_PLUS_v2_2_4', 'bin', 'rebuild' ) 
     292        if not TmpDir : TmpDir = os.path.join ( '/', 'gpfsscratch', 'rech', 
     293                            os.path.basename ( os.path.dirname ( Path.home () )), LocalUser ) 
     294 
     295    ### =========================================================================================== 
    249296    ### The construction of the following variables is not machine dependant 
    250     ### ===========================================================================================           
     297    ### =========================================================================================== 
    251298    if SpaceName == 'TEST' : 
    252         if SCRATCHDIR and not R_OUT : SCRATCHDIR 
    253         if SCRATCHDIR and not R_FIG : SCRATCHDIR 
     299        if SCRATCHDIR and not R_OUT : R_OUT = SCRATCHDIR 
     300        if SCRATCHDIR and not R_FIG : R_FIG = SCRATCHDIR 
    254301    else  : 
    255302        if ARCHIVE    and not R_OUT : R_OUT = ARCHIVE 
    256303        if STORAGE    and not R_FIG : R_FIG = STORAGE 
    257304    if IGCM_OUT_name : 
    258          R_OUT = os.path.join ( R_OUT, IGCM_OUT_name ) 
    259          R_FIG = os.path.join ( R_FIG, IGCM_OUT_name ) 
    260          
     305        R_OUT = os.path.join ( R_OUT, IGCM_OUT_name ) 
     306        R_FIG = os.path.join ( R_FIG, IGCM_OUT_name ) 
     307 
    261308    if SCRATCHDIR and not R_BUF : R_BUF  = os.path.join ( SCRATCHDIR, IGCM_OUT_name ) 
    262309    if not IGCM_OUT : IGCM_OUT = R_OUT 
    263310 
    264311    if TagName and SpaceName and ExperimentName and JobName : 
    265         L_EXP = os.path.join ( TagName, SpaceName, ExperimentName, JobName ) 
    266      
     312        if not L_EXP : L_EXP = os.path.join ( TagName, SpaceName, ExperimentName, JobName ) 
     313 
    267314        if R_OUT and not R_SAVE : R_SAVE      = os.path.join ( R_OUT  , L_EXP ) 
    268         if IGCM_OUT_name :  
     315        if IGCM_OUT_name : 
    269316            if STORAGE and not R_FIGR : R_FIGR      = os.path.join ( STORAGE, IGCM_OUT_name, L_EXP ) 
    270317        else : 
    271             if STORAGE and not R_FIGR : R_FIGR      = os.path.join ( STORAGE, L_EXP ) 
     318            if STORAGE and not R_FIGR  : R_FIGR      = os.path.join ( STORAGE, L_EXP ) 
    272319        if R_BUF   and not R_BUFR      : R_BUFR      = os.path.join ( R_BUF  , L_EXP ) 
    273320        if R_BUFR  and not R_BUF_KSH   : R_BUF_KSH   = os.path.join ( R_BUFR , 'Out' ) 
     
    275322        if R_BUF   and not POST_DIR    : POST_DIR    = os.path.join ( R_BUF  , L_EXP, 'Out' ) 
    276323 
    277     ### ===========================================================================================           
     324    ### =========================================================================================== 
    278325    ## Builds the final dictionnary 
    279326 
    280     libIGCM = { 'TagName' : TagName , 'SpaceName' : SpaceName, 'ExperimentName': ExperimentName, 'JobName':JobName, 
    281                 'LongName': LongName, 'ModelName' : ModelName, 'ShortName'     : ShortName     , 'ConfigCard'    : ConfigCard, 
    282                 'ARCHIVE' : ARCHIVE , 'STORAGE'   : STORAGE  , 'SCRATCHDIR'    : SCRATCHDIR    , 
    283                 'R_OUT'   : R_OUT   , 'R_BUF'     : R_BUFR   , 'R_GRAF'        : R_GRAF        , 'DB' : DB,   
    284                 'IGCM_OUT': IGCM_OUT, 'R_SAVE'    : R_SAVE   , 'R_FIGR'        : R_FIGR    , 'R_BUFR': R_BUFR, 'REBUILD_DIR': REBUILD_DIR, 
    285                 'POST_DIR': POST_DIR, 'R_IN'      : R_IN     , 'Mach'          : Host      , 'Source': Source, 
    286                 'User'    : User    , 'Group'     : Group    , 'IGCM_OUT_name' : IGCM_OUT_name, 'rebuild':rebuild, 'TmpDir':TmpDir, 
    287                 'TGCC_User':TGCC_User, 'TGCC_Group':TGCC_Group, 'Thredds'      : ThreddsPrefix, 
    288                 'IDRIS_User':IDRIS_User, 'IDRIS_Group':IDRIS_Group } 
     327    libIGCM = { 'TagName'       : TagName  , 
     328                'SpaceName'     : SpaceName , 
     329                'ExperimentName': ExperimentName, 
     330                'JobName'       : JobName  , 
     331                'LongName'      : LongName  , 
     332                'ModelName'     : ModelName    , 
     333                'ShortName'     : ShortName, 
     334                'ConfigCard'    : ConfigCard, 
     335                'ARCHIVE'       : ARCHIVE  , 
     336                'STORAGE'       : STORAGE   , 
     337                'SCRATCHDIR'    : SCRATCHDIR    , 
     338                'R_OUT'         : R_OUT    , 
     339                'R_BUF'         : R_BUFR    , 
     340                'R_GRAF'        : R_GRAF        , 
     341                'DB'            : DB       , 
     342                'IGCM_OUT'      : IGCM_OUT  , 
     343                'R_SAVE'        : R_SAVE        , 
     344                'R_FIGR'        : R_FIGR   , 
     345                'R_BUFR'        : R_BUFR, 
     346                'REBUILD_DIR'   : REBUILD_DIR, 
     347                'POST_DIR'      : POST_DIR , 
     348                'R_IN'          : R_IN      , 
     349                'Mach'          : Host     , 
     350                'Source'        : Source    , 
     351                'User'          : User    , 
     352                'Group'         : Group, 
     353                'IGCM_OUT_name' : IGCM_OUT_name, 
     354                'rebuild'       : rebuild, 
     355                'TmpDir'        : TmpDir, 
     356                'TGCC_User'     : TGCC_User, 
     357                'TGCC_Group'    : TGCC_Group, 
     358                'Thredds'       : ThreddsPrefix, 
     359                'IDRIS_User'    : IDRIS_User, 
     360                'IDRIS_Group'   : IDRIS_Group } 
    289361 
    290362    if Out in ['namespace', 'space', 'name', 'Space', 'Name', 'Names', 'NameSpace'] : 
    291363        libIGCM = types.SimpleNamespace (**libIGCM) 
    292      
     364 
    293365    return libIGCM 
    294  
Note: See TracChangeset for help on using the changeset viewer.