[6508] | 1 | #!/usr/bin/env python3 |
---|
[6620] | 2 | ''' |
---|
| 3 | Script to check water conservation in the IPSL coupled model |
---|
[6665] | 4 | |
---|
[6620] | 5 | Here, some common utilities to all scripts |
---|
[6665] | 6 | |
---|
[6620] | 7 | Warning, to install, configure, run, use any of included software or |
---|
| 8 | to read the associated documentation you'll need at least one (1) |
---|
| 9 | brain in a reasonably working order. Lack of this implement will |
---|
| 10 | void any warranties (either express or implied). Authors assumes |
---|
| 11 | no responsability for errors, omissions, data loss, or any other |
---|
| 12 | consequences caused directly or indirectly by the usage of his |
---|
| 13 | software by incorrectly or partially configured personal |
---|
[6508] | 14 | |
---|
[6620] | 15 | SVN information |
---|
| 16 | $Author$ |
---|
| 17 | $Date$ |
---|
| 18 | $Revision$ |
---|
[6665] | 19 | $Id: $ |
---|
[6620] | 20 | $HeadURL$ |
---|
| 21 | ''' |
---|
| 22 | |
---|
[6688] | 23 | import os, sys, types |
---|
[6665] | 24 | import functools |
---|
| 25 | import time |
---|
| 26 | import configparser, re |
---|
[6508] | 27 | import numpy as np |
---|
[6688] | 28 | import xarray as xr |
---|
| 29 | import libIGCM_sys, libIGCM_date as ldate |
---|
| 30 | import nemo |
---|
| 31 | import lmdz |
---|
[6508] | 32 | |
---|
[6676] | 33 | def ReadConfig ( ini_file, default_ini_file='defaults.ini' ) : |
---|
| 34 | ''' |
---|
| 35 | Reads experiment parameters |
---|
[6508] | 36 | |
---|
[6676] | 37 | Reads <default_ini_file> config file to set all defaults parameters |
---|
| 38 | Reads <ini_file> config file to set all experiment parameters |
---|
| 39 | Reads config.card files if specified in <ini_file> |
---|
[6688] | 40 | |
---|
| 41 | Returns a dictionary with all parameters |
---|
[6676] | 42 | ''' |
---|
| 43 | ## Read file with defaults values |
---|
| 44 | ## ------------------------------ |
---|
| 45 | params = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) |
---|
| 46 | params.optionxform = str # To keep capitals |
---|
| 47 | params.read (default_ini_file) |
---|
| 48 | print ( f'\nConfig file readed : {default_ini_file} ' ) |
---|
| 49 | |
---|
| 50 | ## Read Experiment config file |
---|
| 51 | ## ---------------------------- |
---|
| 52 | exp_params = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) |
---|
| 53 | exp_params.optionxform = str # To keep capitals |
---|
| 54 | exp_params.read (ini_file) |
---|
| 55 | print ( f'\nConfig file readed : {ini_file} ' ) |
---|
| 56 | |
---|
| 57 | ## Reading config.card if possible |
---|
| 58 | ## ------------------------------- |
---|
| 59 | if 'Experiment' in params.keys () : ## Read Experiment on parameter file if possible |
---|
| 60 | if 'ConfigCard' in exp_params['Experiment'].keys () : |
---|
| 61 | ConfigCard = exp_params['Experiment']['ConfigCard'] |
---|
| 62 | print ( f'{ConfigCard=}' ) |
---|
| 63 | |
---|
| 64 | if ConfigCard : ## Read config card if it exists |
---|
| 65 | # Text existence of ConfigCard |
---|
| 66 | if os.path.exists ( ConfigCard ) : |
---|
| 67 | print ( f'Reading Config Card : {ConfigCard}' ) |
---|
| 68 | ## Creates parser for reading .ini input file |
---|
| 69 | config = configparser.ConfigParser (interpolation=configparser.ExtendedInterpolation() ) |
---|
| 70 | config.optionxform = str # To keep capitals |
---|
| 71 | config.read (ConfigCard) |
---|
| 72 | |
---|
| 73 | for VarName in ['JobName', 'ExperimentName', 'SpaceName', 'LongName', 'ModelName', 'TagName', |
---|
[6688] | 74 | 'ORCA_version', 'ExpType', 'PeriodLength', 'ResolAtm', 'ResolOce', 'CalendarType' ] : |
---|
[6676] | 75 | if VarName in config['UserChoices'].keys() : |
---|
[6688] | 76 | exp_params['Experiment'][VarName] = config['UserChoices'][VarName] |
---|
[6676] | 77 | |
---|
| 78 | if 'Post' in config.sections() : |
---|
| 79 | if 'PackFrequency' in config['Post'] : |
---|
| 80 | PackFrequency = config['Post']['PackFrequency'] |
---|
| 81 | exp_params['Experiment']['PackFrequency'] = PackFrequency |
---|
| 82 | |
---|
| 83 | else : |
---|
| 84 | raise FileExistsError ( f"File not found : {ConfigCard = }" ) |
---|
| 85 | |
---|
| 86 | ## Reading config file |
---|
| 87 | ## ------------------- |
---|
| 88 | for Section in exp_params.keys () : |
---|
| 89 | params[Section].update ( exp_params[Section] ) |
---|
| 90 | print ( f'\nConfig file readed : {ini_file} ' ) |
---|
| 91 | |
---|
| 92 | return config2dict (params) |
---|
| 93 | |
---|
| 94 | def SetDatesAndFiles ( pdict ) : |
---|
| 95 | ''' |
---|
| 96 | From readed experiment parameters, set all needed parameters |
---|
| 97 | ''' |
---|
| 98 | |
---|
| 99 | ## Set libIGCM and machine dependant values |
---|
| 100 | ## ---------------------------------------- |
---|
| 101 | pdict['Experiment']['ICO'] = 'ICO' in pdict['Experiment']['ResolAtm'] |
---|
[6688] | 102 | #pdict['Experiment']['LMDZ'] = 'LMD' in pdict['Experiment']['ResolAtm'] |
---|
| 103 | pdict['Experiment']['LMDZ'] = not pdict['Experiment']['ICO'] |
---|
[6676] | 104 | |
---|
[6688] | 105 | mm = libIGCM_sys.config ( |
---|
| 106 | JobName = pdict['Experiment']['JobName'], |
---|
| 107 | ExperimentName = pdict['Experiment']['ExperimentName'], |
---|
| 108 | TagName = pdict['Experiment']['TagName'], |
---|
| 109 | SpaceName = pdict['Experiment']['SpaceName'], |
---|
| 110 | User = pdict['Experiment']['User'], |
---|
| 111 | Group = pdict['Experiment']['Group'], |
---|
| 112 | TmpDir = pdict['Files']['TmpDir'], |
---|
| 113 | ARCHIVE = pdict['libIGCM']['ARCHIVE'], |
---|
| 114 | SCRATCHDIR = pdict['libIGCM']['SCRATCHDIR'], |
---|
| 115 | STORAGE = pdict['libIGCM']['STORAGE'], |
---|
| 116 | R_IN = pdict['libIGCM']['R_IN'], |
---|
| 117 | R_OUT = pdict['libIGCM']['R_OUT'], |
---|
| 118 | R_FIG = pdict['libIGCM']['R_FIG'], |
---|
| 119 | R_SAVE = pdict['libIGCM']['R_SAVE'], |
---|
| 120 | R_FIGR = pdict['libIGCM']['R_FIGR'], |
---|
| 121 | R_BUFR = pdict['libIGCM']['R_BUFR'], |
---|
| 122 | R_BUF_KSH = pdict['libIGCM']['R_BUF_KSH'], |
---|
| 123 | POST_DIR = pdict['libIGCM']['POST_DIR'], |
---|
| 124 | L_EXP = pdict['libIGCM']['L_EXP'] |
---|
| 125 | ) |
---|
[6676] | 126 | |
---|
[6688] | 127 | pdict['Files']['TmpDir'] = mm['TmpDir'] |
---|
| 128 | pdict['libIGCM'].update (mm) |
---|
[6676] | 129 | |
---|
| 130 | ## Complete configuration |
---|
| 131 | ## ---------------------- |
---|
| 132 | if not pdict['Experiment']['NEMO'] and pdict['Experiment']['ORCA_version'] : |
---|
| 133 | if '1.2' in pdict['Experiment']['ORCA_version'] : |
---|
| 134 | pdict['Experiment']['NEMO'] = 3.6 |
---|
| 135 | if '4.0' in pdict['Experiment']['ORCA_version'] : |
---|
| 136 | pdict['Experiment']['NEMO'] = 4.0 |
---|
| 137 | if '4.2' in pdict['Experiment']['ORCA_version'] : |
---|
| 138 | pdict['Experiment']['NEMO'] = 4.2 |
---|
| 139 | |
---|
| 140 | if pdict['Experiment']['ATM_HIS'] : |
---|
| 141 | if not pdict['Experiment']['SRF_HIS'] : |
---|
| 142 | pdict['Experiment']['SRF_HIS'] = pdict['Experiment']['ATM_HIS'] |
---|
| 143 | if not pdict['Experiment']['RUN_HIS'] : |
---|
| 144 | pdict['Experiment']['RUN_HIS'] = pdict['Experiment']['ATM_HIS'] |
---|
| 145 | |
---|
| 146 | ## |
---|
| 147 | ## Reading prec |
---|
| 148 | if not pdict['Config']['readPrec'] : |
---|
| 149 | pdict['Config']['readPrec'] = np.float64 |
---|
| 150 | else : |
---|
| 151 | if pdict['Config']['readPrec'] in ["float", "float64", "r8", "double", "<class 'float'>" ] : |
---|
| 152 | pdict['Config']['readPrec'] = float |
---|
| 153 | if pdict['Config']['readPrec'] in [ "float32", "r4", "single", "<class 'numpy.float32'>" ] : |
---|
| 154 | pdict['Config']['readPrec'] = np.float32 |
---|
| 155 | if pdict['Config']['readPrec'] in [ "float16", "r2", "half" , "<class 'numpy.float16'>" ] : |
---|
| 156 | pdict['Config']['readPrec'] = np.float16 |
---|
| 157 | |
---|
| 158 | |
---|
| 159 | ## Defines begining and end of experiment |
---|
| 160 | ## -------------------------------------- |
---|
| 161 | if not pdict['Experiment']['DateBegin'] : |
---|
| 162 | pdict['Experiment']['DateBegin'] = f"{pdict['Experiment']['YearBegin']}0101" |
---|
| 163 | else : |
---|
[6688] | 164 | YearBegin, MonthBegin, DayBegin = ldate.GetYearMonthDay ( pdict['Experiment']['DateBegin'] ) |
---|
[6676] | 165 | DateBegin = FormatToGregorian (pdict['Experiment']['DateBegin']) |
---|
| 166 | pdict['Experiment']['YearBegin'] = YearBegin |
---|
| 167 | |
---|
| 168 | if not pdict['Experiment']['DateEnd'] : |
---|
| 169 | pdict['Experiment']['DateEnd'] = f"{pdict['Experiment']['YearEnd']}1231" |
---|
| 170 | else : |
---|
[6688] | 171 | YearEnd, MonthEnd, DayEnd = ldate.GetYearMonthDay ( pdict['Experiment']['DateEnd'] ) |
---|
[6676] | 172 | DateEnd = FormatToGregorian (pdict['Experiment']['DateEnd']) |
---|
| 173 | pdict['Experiment']['DateEnd'] = DateEnd |
---|
| 174 | |
---|
| 175 | if not pdict['Experiment']['PackFrequency'] : |
---|
[6688] | 176 | PackFrequencypdict['Experiment']['PackFrequency'] = f"{YearEnd - YearBegin + 1}YE" |
---|
| 177 | |
---|
[6676] | 178 | |
---|
| 179 | ## Set directory to extract files |
---|
| 180 | ## ------------------------------ |
---|
| 181 | if not pdict['Files']['FileDir'] : |
---|
| 182 | pdict['Files']['FileDir'] = os.path.join ( pdict['Files']['TmpDir'], f"WATER_{pdict['Experiment']['JobName']}" ) |
---|
| 183 | |
---|
| 184 | if not os.path.isdir ( pdict['Files']['FileDir'] ) : os.makedirs ( pdict['Files']['FileDir'] ) |
---|
| 185 | |
---|
| 186 | FileOut = str2value (pdict['Files']['FileOut']) |
---|
| 187 | if not FileOut : |
---|
| 188 | FileOut = f"ATM_waterbudget_{pdict['Experiment']['JobName']}_{pdict['Experiment']['YearBegin']}_{pdict['Experiment']['YearEnd']}" |
---|
| 189 | if pdict['Experiment']['ICO'] : |
---|
| 190 | if pdict['Experiment']['ATM_HIS'] == 'latlon' : FileOut = f'{FileOut}_LATLON' |
---|
| 191 | if pdict['Experiment']['ATM_HIS'] == 'ico' : FileOut = f'{FileOut}_ICO' |
---|
| 192 | if pdict['Config']['readPrec'] == np.float32 : FileOut = f'{FileOut}_float32' |
---|
| 193 | FileOut = f'{FileOut}.out' |
---|
| 194 | |
---|
| 195 | pdict['Files']['FileOut'] = FileOut |
---|
| 196 | f_out = open ( FileOut, mode = 'w', encoding="utf-8" ) |
---|
| 197 | pdict['Files']['f_out'] = f_out |
---|
| 198 | |
---|
| 199 | echo (' ', f_out) |
---|
[6688] | 200 | echo ( f"JobName : {pdict['Experiment']['JobName']}" , f_out=f_out ) |
---|
| 201 | echo ( f"Comment : {pdict['Experiment']['Comment']}" , f_out=f_out ) |
---|
| 202 | echo ( f"TmpDir : {pdict['Files']['TmpDir']}" , f_out=f_out ) |
---|
| 203 | echo ( f"FileDir : {pdict['Files']['FileDir']}" , f_out=f_out ) |
---|
[6676] | 204 | |
---|
| 205 | echo ( f"\nDealing with {pdict['libIGCM']['L_EXP']}", f_out ) |
---|
| 206 | |
---|
| 207 | ## Creates model output directory names |
---|
| 208 | ## ------------------------------------ |
---|
| 209 | if not pdict['Files']['FreqDir'] : |
---|
| 210 | if pdict['Experiment']['Freq'] == "MO" : |
---|
| 211 | pdict['Files']['FreqDir'] = os.path.join ('Output' , 'MO' ) |
---|
| 212 | if pdict['Experiment']['Freq'] == "SE" : |
---|
| 213 | pdict['Files']['FreqDir'] = os.path.join ('Analyse', 'SE' ) |
---|
| 214 | |
---|
| 215 | if not pdict['Files']['dir_ATM_his'] : |
---|
| 216 | pdict['Files']['dir_ATM_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "ATM", pdict['Files']['FreqDir'] ) |
---|
| 217 | if not pdict['Files']['dir_SRF_his'] : |
---|
| 218 | pdict['Files']['dir_SRF_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "SRF", pdict['Files']['FreqDir'] ) |
---|
| 219 | |
---|
| 220 | if not pdict['Files']['dir_OCE_his'] : |
---|
| 221 | pdict['Files']['dir_OCE_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "OCE", pdict['Files']['FreqDir'] ) |
---|
| 222 | if not pdict['Files']['dir_ICE_his'] : |
---|
| 223 | pdict['Files']['dir_ICE_his'] = os.path.join ( pdict['libIGCM']['R_SAVE'], "ICE", pdict['Files']['FreqDir'] ) |
---|
| 224 | |
---|
| 225 | echo ( 'The analysis relies on files from the following model output directories : ', f_out ) |
---|
| 226 | echo ( f"{pdict['Files']['dir_ATM_his'] = }" , f_out ) |
---|
| 227 | echo ( f"{pdict['Files']['dir_SRF_his'] = }" , f_out ) |
---|
| 228 | echo ( f"{pdict['Files']['dir_OCE_his'] = }" , f_out ) |
---|
| 229 | echo ( f"{pdict['Files']['dir_ICE_his'] = }" , f_out ) |
---|
| 230 | |
---|
| 231 | ## Creates files names |
---|
| 232 | ## -------------------- |
---|
| 233 | if not pdict['Experiment']['Period'] : |
---|
| 234 | if pdict['Experiment']['Freq'] == 'MO' : |
---|
| 235 | pdict['Experiment']['Period'] = f"{pdict['Experiment']['DateBegin']}_{pdict['Experiment']['DateEnd']}_1M" |
---|
| 236 | if pdict['Experiment']['Freq'] == 'SE' : |
---|
| 237 | pdict['Experiment']['Period'] = f"SE_{pdict['Files']['DateBegin']}_{pdict['Files']['DateEnd']}_1M" |
---|
| 238 | |
---|
| 239 | echo ( f"Period : {pdict['Experiment']['Period']}", f_out ) |
---|
| 240 | |
---|
| 241 | if not pdict['Files']['FileCommon'] : |
---|
| 242 | pdict['Files']['FileCommon'] = f"{pdict['Experiment']['JobName']}_{pdict['Experiment']['Period']}" |
---|
| 243 | |
---|
| 244 | if not pdict['Files']['Title'] : |
---|
| 245 | pdict['Files']['Title'] = f"{pdict['Experiment']['JobName']} : {pdict['Experiment']['Freq']} : {pdict['Experiment']['DateBegin']} - {pdict['Experiment']['DateEnd']}" |
---|
| 246 | |
---|
| 247 | echo ('\nOpen history files', f_out ) |
---|
| 248 | if not pdict['Files']['file_ATM_his'] : |
---|
| 249 | if pdict['Experiment']['ATM_HIS'] == 'latlon' : |
---|
| 250 | pdict['Files']['file_ATM_his'] = os.path.join ( pdict['Files']['dir_ATM_his'], f"{pdict['Files']['FileCommon']}_histmth.nc" ) |
---|
| 251 | if pdict['Experiment']['ATM_HIS'] == 'ico' : |
---|
| 252 | pdict['Files']['file_ATM_his'] = os.path.join ( pdict['Files']['dir_ATM_his'], f"{pdict['Files']['FileCommon']}_histmth_ico.nc" ) |
---|
| 253 | if not pdict['Files']['file_SRF_his'] : |
---|
| 254 | if pdict['Experiment']['ATM_HIS'] == 'latlon' : |
---|
| 255 | pdict['Files']['file_SRF_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history.nc" ) |
---|
| 256 | if pdict['Experiment']['ATM_HIS'] == 'ico' : |
---|
| 257 | pdict['Files']['file_SRF_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history_ico.nc" ) |
---|
| 258 | |
---|
[6688] | 259 | if pdict['Experiment']['SECHIBA'] and pdict['Experiment']['Routing'] == 'SIMPLE' : |
---|
[6676] | 260 | if not pdict['Files']['file_RUN_his'] : |
---|
| 261 | if pdict['Experiment']['RUN_HIS'] == 'latlon' : |
---|
| 262 | pdict['Files']['file_RUN_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history.nc" ) |
---|
| 263 | if pdict['Experiment']['SRF_HIS'] == 'ico' : |
---|
| 264 | pdict['Files']['file_RUN_his'] = os.path.join ( pdict['Files']['dir_SRF_his'], f"{pdict['Files']['FileCommon']}_sechiba_history_ico.nc" ) |
---|
| 265 | |
---|
| 266 | echo ( f"{pdict['Files']['file_ATM_his'] = }", f_out ) |
---|
[6688] | 267 | if pdict['Experiment']['SECHIBA'] : |
---|
[6676] | 268 | echo ( f"{pdict['Files']['file_SRF_his'] = }", f_out ) |
---|
| 269 | if pdict['Experiment']['Routing'] == 'SIMPLE' : echo ( f"{pdict['Files']['file_RUN_his'] = }", f_out ) |
---|
| 270 | |
---|
| 271 | if not pdict['Files']['file_OCE_his'] : |
---|
| 272 | pdict['Files']['file_OCE_his'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_grid_T.nc" ) |
---|
| 273 | if not pdict['Files']['file_OCE_sca'] : |
---|
| 274 | pdict['Files']['file_OCE_sca'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_scalar.nc" ) |
---|
| 275 | if not pdict['Files']['file_OCE_srf'] : |
---|
| 276 | pdict['Files']['file_OCE_srf'] = os.path.join ( pdict['Files']['dir_OCE_his'], f"{pdict['Files']['FileCommon']}_sbc.nc" ) |
---|
| 277 | if not pdict['Files']['file_ICE_his'] : |
---|
| 278 | pdict['Files']['file_ICE_his'] = os.path.join ( pdict['Files']['dir_ICE_his'], f"{pdict['Files']['FileCommon']}_icemod.nc" ) |
---|
| 279 | |
---|
| 280 | return pdict |
---|
| 281 | |
---|
| 282 | def SetRestartNames ( pdict, f_out) : |
---|
[6688] | 283 | ''' |
---|
| 284 | Defines dates for restart files |
---|
| 285 | Define names of tar files with restart |
---|
| 286 | |
---|
| 287 | Returns a dictionary |
---|
| 288 | ''' |
---|
[6676] | 289 | |
---|
[6688] | 290 | if not pdict['Files']['TarRestartDate_beg'] : |
---|
| 291 | pdict['Files']['TarRestartDate_beg'] = ldate.SubOneDayToDate ( pdict['Experiment']['DateBegin'], pdict['Experiment']['CalendarType'] ) |
---|
| 292 | if not pdict['Files']['TarRestartDate_end'] : |
---|
| 293 | pdict['Files']['TarRestartDate_end'] = ldate.ConvertFormatToGregorian ( pdict['Experiment']['DateEnd'] ) |
---|
| 294 | |
---|
| 295 | if not pdict['Files']['TarRestartPeriod_beg'] : |
---|
[6676] | 296 | |
---|
[6688] | 297 | pdict['Files']['TarRestartPeriod_beg_DateEnd'] = pdict['Files']['TarRestartDate_beg'] |
---|
| 298 | pdict['Files']['TarRestartPeriod_beg_DateBeg'] = ldate.DateAddPeriod ( pdict['Files']['TarRestartPeriod_beg_DateEnd'], |
---|
| 299 | f"-{pdict['Experiment']['PackFrequency']}") |
---|
| 300 | pdict['Files']['TarRestartPeriod_beg_DateBeg'] = ldate.AddOneDayToDate ( pdict['Files']['TarRestartPeriod_beg_DateBeg'], |
---|
| 301 | pdict['Experiment']['CalendarType'] ) |
---|
[6676] | 302 | |
---|
[6688] | 303 | pdict['Files']['TarRestartPeriod_beg'] = f"{pdict['Files']['TarRestartPeriod_beg_DateBeg']}_{pdict['Files']['TarRestartPeriod_beg_DateEnd']}" |
---|
| 304 | echo ( f"Tar period for initial restart : {pdict['Files']['TarRestartPeriod_beg']}", f_out) |
---|
[6676] | 305 | |
---|
[6688] | 306 | if not pdict['Files']['TarRestartPeriod_end'] : |
---|
[6676] | 307 | |
---|
[6688] | 308 | pdict['Files']['TarRestartPeriod_end_DateEnd'] = pdict['Files']['TarRestartDate_end'] |
---|
| 309 | pdict['Files']['TarRestartPeriod_end_DateBeg'] = ldate.DateAddPeriod ( pdict['Files']['TarRestartPeriod_end_DateEnd'], |
---|
| 310 | f"-{pdict['Experiment']['PackFrequency']}" ) |
---|
| 311 | pdict['Files']['TarRestartPeriod_end_DateBeg'] = ldate.AddOneDayToDate ( pdict['Files']['TarRestartPeriod_end_DateBeg'], |
---|
| 312 | pdict['Experiment']['CalendarType'] ) |
---|
[6676] | 313 | |
---|
[6688] | 314 | pdict['Files']['TarRestartPeriod_end'] = f"{pdict['Files']['TarRestartPeriod_end_DateBeg']}_{pdict['Files']['TarRestartPeriod_end_DateEnd']}" |
---|
| 315 | echo ( f"Tar period for final restart : {pdict['Files']['TarRestartPeriod_end']}", f_out ) |
---|
[6676] | 316 | |
---|
[6688] | 317 | echo ( f"Restart dates - Start : {pdict['Files']['TarRestartPeriod_beg']} / End : {pdict['Files']['TarRestartPeriod_end']}", f_out) |
---|
[6676] | 318 | |
---|
[6688] | 319 | if not pdict['Files']['tar_restart_beg'] : |
---|
| 320 | pdict['Files']['tar_restart_beg'] = os.path.join ( pdict['libIGCM']['R_SAVE'], 'RESTART', f"{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartPeriod_beg']}_restart.tar" ) |
---|
| 321 | if not pdict['Files']['tar_restart_end'] : |
---|
| 322 | pdict['Files']['tar_restart_end'] = os.path.join ( pdict['libIGCM']['R_SAVE'], 'RESTART', f"{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartPeriod_end']}_restart.tar" ) |
---|
[6676] | 323 | |
---|
[6688] | 324 | echo ( f"{ pdict['Files']['tar_restart_beg'] = }", f_out ) |
---|
| 325 | echo ( f"{ pdict['Files']['tar_restart_end'] = }", f_out ) |
---|
[6676] | 326 | |
---|
| 327 | ##-- Names of tar files with restarts |
---|
| 328 | |
---|
[6688] | 329 | if not pdict['Files']['tar_restart_beg_ATM'] : |
---|
| 330 | pdict['Files']['tar_restart_beg_ATM'] = pdict['Files']['tar_restart_beg'] |
---|
| 331 | if not pdict['Files']['tar_restart_beg_DYN'] : |
---|
| 332 | pdict['Files']['tar_restart_beg_DYN'] = pdict['Files']['tar_restart_beg'] |
---|
| 333 | if not pdict['Files']['tar_restart_beg_RUN'] : |
---|
| 334 | pdict['Files']['tar_restart_beg_RUN'] = pdict['Files']['tar_restart_beg'] |
---|
| 335 | if not pdict['Files']['tar_restart_beg_OCE'] : |
---|
| 336 | pdict['Files']['tar_restart_beg_OCE'] = pdict['Files']['tar_restart_beg'] |
---|
| 337 | if not pdict['Files']['tar_restart_beg_ICE'] : |
---|
| 338 | pdict['Files']['tar_restart_beg_ICE'] = pdict['Files']['tar_restart_beg'] |
---|
[6676] | 339 | |
---|
[6688] | 340 | if not pdict['Files']['tar_restart_end_ATM'] : |
---|
| 341 | pdict['Files']['tar_restart_end_ATM'] = pdict['Files']['tar_restart_end'] |
---|
| 342 | if not pdict['Files']['tar_restart_end_DYN'] : |
---|
| 343 | pdict['Files']['tar_restart_end_DYN'] = pdict['Files']['tar_restart_end'] |
---|
| 344 | if not pdict['Files']['tar_restart_end_RUN'] : |
---|
| 345 | pdict['Files']['tar_restart_end_RUN'] = pdict['Files']['tar_restart_end'] |
---|
| 346 | if not pdict['Files']['tar_restart_end_OCE'] : |
---|
| 347 | pdict['Files']['tar_restart_end_OCE'] = pdict['Files']['tar_restart_end'] |
---|
| 348 | if not pdict['Files']['tar_restart_end_ICE'] : |
---|
| 349 | pdict['Files']['tar_restart_end_ICE'] = pdict['Files']['tar_restart_end'] |
---|
[6676] | 350 | |
---|
[6688] | 351 | if not pdict['Files']['file_DYN_beg'] : |
---|
| 352 | if pdict['Experiment']['LMDZ'] : |
---|
| 353 | pdict['Files']['file_DYN_beg'] = f"{pdict['Files']['FileDir']}/ATM_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_restart.nc" |
---|
| 354 | if pdict['Experiment']['ICO'] : |
---|
| 355 | pdict['Files']['file_DYN_beg'] = f"{pdict['Files']['FileDir']}/ICO_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_restart.nc" |
---|
[6676] | 356 | |
---|
[6688] | 357 | if not pdict['Files']['file_DYN_end'] : |
---|
| 358 | if pdict['Experiment']['LMDZ'] : |
---|
| 359 | pdict['Files']['file_DYN_end'] = f"{pdict['Files']['FileDir']}/ATM_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_restart.nc" |
---|
| 360 | if pdict['Experiment']['ICO'] : |
---|
| 361 | pdict['Files']['file_DYN_end'] = f"{pdict['Files']['FileDir']}/ICO_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_restart.nc" |
---|
[6676] | 362 | |
---|
[6688] | 363 | if pdict['Experiment']['SECHIBA'] : |
---|
| 364 | if not pdict['Files']['file_SRF_beg'] : |
---|
| 365 | pdict['Files']['file_SRF_beg'] = f"{pdict['Files']['FileDir']}/SRF_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_sechiba_rest.nc" |
---|
| 366 | if not pdict['Files']['file_SRF_end'] : |
---|
| 367 | pdict['Files']['file_SRF_end'] = f"{pdict['Files']['FileDir']}/SRF_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_sechiba_rest.nc" |
---|
[6676] | 368 | |
---|
[6688] | 369 | if pdict['Experiment']['SECHIBA'] : |
---|
| 370 | if not pdict['Files']['tar_restart_beg_SRF'] : |
---|
| 371 | pdict['Files']['tar_restart_beg_SRF'] = pdict['Files']['tar_restart_beg'] |
---|
| 372 | if not pdict['Files']['tar_restart_end_SRF'] : |
---|
| 373 | pdict['Files']['tar_restart_end_SRF'] = pdict['Files']['tar_restart_end'] |
---|
[6676] | 374 | |
---|
[6688] | 375 | if not pdict['Files']['file_ATM_beg'] : |
---|
| 376 | pdict['Files']['file_ATM_beg'] = f"{pdict['Files']['FileDir']}/ATM_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_restartphy.nc" |
---|
| 377 | if not pdict['Files']['file_ATM_end'] : |
---|
| 378 | pdict['Files']['file_ATM_end'] = f"{pdict['Files']['FileDir']}/ATM_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_restartphy.nc" |
---|
[6676] | 379 | |
---|
[6688] | 380 | if pdict['Experiment']['SECHIBA'] : |
---|
| 381 | echo ( f"{pdict['Files']['file_SRF_beg'] = }", f_out) |
---|
| 382 | echo ( f"{pdict['Files']['file_SRF_end'] = }", f_out) |
---|
[6676] | 383 | |
---|
[6688] | 384 | if pdict['Experiment']['ICO'] : |
---|
| 385 | if not pdict['Files']['file_DYN_aire'] : |
---|
| 386 | pdict['Files']['file_DYN_aire'] = os.path.join ( pdict['libIGCM']['R_IN'], 'ATM', 'GRID', f"{pdict['Experiment']['ResolAtm']}_grid.nc" ) |
---|
[6676] | 387 | |
---|
[6688] | 388 | if pdict['Experiment']['SECHIBA'] and pdict['Experiment']['Routing'] == 'SIMPLE' : |
---|
| 389 | if not pdict['Files']['file_RUN_beg'] : |
---|
| 390 | pdict['Files']['file_RUN_beg'] = f"{ pdict['Files']['FileDir']}/SRF_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_routing_restart.nc" |
---|
| 391 | if not pdict['Files']['file_RUN_end'] : |
---|
| 392 | pdict['Files']['file_RUN_end'] = f"{ pdict['Files']['FileDir']}/SRF_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_routing_restart.nc" |
---|
[6676] | 393 | |
---|
[6688] | 394 | if not pdict['Files']['tar_restart_beg_OCE'] : |
---|
| 395 | pdict['Files']['tar_restart_beg_OCE'] = pdict['Files']['tar_restart_beg'] |
---|
| 396 | if not pdict['Files']['tar_restart_beg_ICE'] : |
---|
| 397 | pdict['Files']['tar_restart_beg_ICE'] = pdict['Files']['tar_restart_beg'] |
---|
[6676] | 398 | |
---|
[6688] | 399 | if not pdict['Files']['tar_restart_end_OCE'] : |
---|
| 400 | pdict['Files']['tar_restart_end_OCE'] = pdict['Files']['tar_restart_end'] |
---|
| 401 | if not pdict['Files']['tar_restart_end_ICE'] : |
---|
| 402 | pdict['Files']['tar_restart_end_ICE'] = pdict['Files']['tar_restart_end'] |
---|
[6676] | 403 | |
---|
[6688] | 404 | if not pdict['Files']['file_OCE_beg'] : |
---|
| 405 | pdict['Files']['file_OCE_beg'] = f"{pdict['Files']['FileDir']}/OCE_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_restart.nc" |
---|
| 406 | if not pdict['Files']['file_OCE_end'] : |
---|
| 407 | pdict['Files']['file_OCE_end'] = f"{pdict['Files']['FileDir']}/OCE_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_restart.nc" |
---|
| 408 | if not pdict['Files']['file_ICE_beg'] : |
---|
| 409 | pdict['Files']['file_ICE_beg'] = f"{pdict['Files']['FileDir']}/ICE_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_beg']}_restart_icemod.nc" |
---|
| 410 | if not pdict['Files']['file_ICE_end'] : |
---|
| 411 | pdict['Files']['file_ICE_end'] = f"{pdict['Files']['FileDir']}/ICE_{pdict['Experiment']['JobName']}_{pdict['Files']['TarRestartDate_end']}_restart_icemod.nc" |
---|
[6676] | 412 | |
---|
[6688] | 413 | return pdict |
---|
[6676] | 414 | |
---|
[6688] | 415 | def ComputeGridATM ( dpar, d_ATM_his ) : |
---|
| 416 | readPrec = dpar['Config']['readPrec'] |
---|
| 417 | if repr(readPrec) in [ "<class 'numpy.float64'>" , float ] : |
---|
| 418 | def rprec (ptab) : |
---|
| 419 | return ptab |
---|
| 420 | else : |
---|
| 421 | def rprec (ptab) : |
---|
| 422 | return ptab.astype(readPrec).astype(float) |
---|
| 423 | |
---|
| 424 | ATM = types.SimpleNamespace () |
---|
| 425 | |
---|
| 426 | # ATM grid with cell surfaces |
---|
| 427 | if dpar['Experiment']['LMDZ'] : |
---|
| 428 | #echo ('ATM grid with cell surfaces : LMDZ', f_out) |
---|
| 429 | ATM.lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1d='cell' ) |
---|
| 430 | ATM.lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1d='cell' ) |
---|
| 431 | ATM.aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'] [0]), cumul_poles=True, dim1d='cell' ) |
---|
| 432 | ATM.fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1d='cell' ) |
---|
| 433 | ATM.foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1d='cell' ) |
---|
| 434 | ATM.fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1d='cell' ) |
---|
| 435 | ATM.flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1d='cell' ) |
---|
| 436 | |
---|
| 437 | if dpar['Experiment']['ICO'] : |
---|
| 438 | if dpar['Experiment']['ATM_HIS'] == 'latlon' : |
---|
| 439 | #echo ( 'ATM areas and fractions on LATLON grid' ) |
---|
| 440 | if 'lat_dom_out' in d_ATM_his.variables : |
---|
| 441 | ATM.lat = lmdz.geo2point ( rprec (d_ATM_his ['lat_dom_out'])+0*rprec (d_ATM_his ['lon_dom_out']), dim1d='cell' ) |
---|
| 442 | ATM.lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat_dom_out'])+ rprec (d_ATM_his ['lon_dom_out']), dim1d='cell' ) |
---|
| 443 | else : |
---|
| 444 | ATM.lat = lmdz.geo2point ( rprec (d_ATM_his ['lat'])+0*rprec (d_ATM_his ['lon']), dim1d='cell' ) |
---|
| 445 | ATM.lon = lmdz.geo2point ( 0*rprec (d_ATM_his ['lat'])+ rprec (d_ATM_his ['lon']), dim1d='cell' ) |
---|
| 446 | ATM.aire = lmdz.geo2point ( rprec (d_ATM_his ['aire'][0]).squeeze(), cumul_poles=True, dim1d='cell' ) |
---|
| 447 | ATM.fter = lmdz.geo2point ( rprec (d_ATM_his ['fract_ter'][0]), dim1d='cell' ) |
---|
| 448 | ATM.foce = lmdz.geo2point ( rprec (d_ATM_his ['fract_oce'][0]), dim1d='cell' ) |
---|
| 449 | ATM.fsic = lmdz.geo2point ( rprec (d_ATM_his ['fract_sic'][0]), dim1d='cell' ) |
---|
| 450 | ATM.flic = lmdz.geo2point ( rprec (d_ATM_his ['fract_lic'][0]), dim1d='cell' ) |
---|
| 451 | |
---|
| 452 | |
---|
| 453 | if dpar['Experiment']['ATM_HIS'] == 'ico' : |
---|
| 454 | #echo ( 'ATM areas and fractions on ICO grid' ) |
---|
| 455 | ATM.aire = rprec (d_ATM_his ['aire'] [0]).squeeze() |
---|
| 456 | ATM.lat = rprec (d_ATM_his ['lat'] ) |
---|
| 457 | ATM.lon = rprec (d_ATM_his ['lon'] ) |
---|
| 458 | ATM.fter = rprec (d_ATM_his ['fract_ter'][0]) |
---|
| 459 | ATM.foce = rprec (d_ATM_his ['fract_oce'][0]) |
---|
| 460 | ATM.fsic = rprec (d_ATM_his ['fract_sic'][0]) |
---|
| 461 | ATM.flic = rprec (d_ATM_his ['fract_lic'][0]) |
---|
| 462 | |
---|
| 463 | |
---|
| 464 | ATM.fsea = ATM.foce + ATM.fsic |
---|
| 465 | ATM.flnd = ATM.fter + ATM.flic |
---|
| 466 | ATM.aire_fter = ATM.aire * ATM.fter |
---|
| 467 | ATM.aire_flic = ATM.aire * ATM.flic |
---|
| 468 | ATM.aire_fsic = ATM.aire * ATM.fsic |
---|
| 469 | ATM.aire_foce = ATM.aire * ATM.foce |
---|
| 470 | ATM.aire_flnd = ATM.aire * ATM.flnd |
---|
| 471 | ATM.aire_fsea = ATM.aire * ATM.fsea |
---|
| 472 | |
---|
| 473 | ATM.aire_sea = ATM.aire * ATM.fsea |
---|
| 474 | ATM.aire_tot = P1sum ( ATM.aire ) |
---|
| 475 | ATM.aire_sea_tot = P1sum ( ATM.aire_fsea ) |
---|
| 476 | ATM.aire_ter_tot = P1sum ( ATM.aire_fter ) |
---|
| 477 | ATM.aire_lic_tot = P1sum ( ATM.aire_flic ) |
---|
| 478 | |
---|
| 479 | return dpar, ATM |
---|
| 480 | |
---|
| 481 | def ComputeGridSRF ( dpar, d_SRF_his ) : |
---|
| 482 | readPrec = dpar['Config']['readPrec'] |
---|
| 483 | if repr(readPrec) in [ "<class 'numpy.float64'>" , float ] : |
---|
| 484 | def rprec (ptab) : |
---|
| 485 | return ptab |
---|
| 486 | else : |
---|
| 487 | def rprec (ptab) : |
---|
| 488 | return ptab.astype(readPrec).astype(float) |
---|
| 489 | |
---|
| 490 | SRF = types.SimpleNamespace () |
---|
| 491 | |
---|
| 492 | if dpar['Experiment']['SECHIBA'] : |
---|
| 493 | if dpar['Experiment']['LMDZ'] : |
---|
| 494 | SRF.lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1d='cell' ) |
---|
| 495 | SRF.lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1d='cell' ) |
---|
| 496 | SRF.aire = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) * rprec (d_SRF_his ['Contfrac']), dim1d='cell', cumul_poles=True ) |
---|
| 497 | SRF.areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas']) , dim1d='cell', cumul_poles=True ) |
---|
| 498 | SRF.contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']), dim1d='cell' ) |
---|
| 499 | |
---|
| 500 | if dpar['Experiment']['ICO'] : |
---|
| 501 | if dpar['Experiment']['SRF_HIS'] == 'latlon' : |
---|
| 502 | #echo ( 'SRF areas and fractions on LATLON grid' ) |
---|
| 503 | if 'lat_domain_landpoints_out' in d_SRF_his : |
---|
| 504 | SRF.lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_domain_landpoints_out'])+0*rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1d='cell' ) |
---|
| 505 | SRF.lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_domain_landpoints_out'])+ rprec (d_SRF_his ['lon_domain_landpoints_out']), dim1d='cell' ) |
---|
| 506 | else : |
---|
| 507 | if 'lat_domain_landpoints_out' in d_SRF_his : |
---|
| 508 | SRF.lat = lmdz.geo2point ( rprec (d_SRF_his ['lat_dom_out'])+0*rprec (d_SRF_his ['lon_dom_out']), dim1d='cell' ) |
---|
| 509 | SRF.lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat_dom_out'])+ rprec (d_SRF_his ['lon_dom_out']), dim1d='cell' ) |
---|
| 510 | else : |
---|
| 511 | SRF.lat = lmdz.geo2point ( rprec (d_SRF_his ['lat'])+0*rprec (d_SRF_his ['lon']), dim1d='cell' ) |
---|
| 512 | SRF.lon = lmdz.geo2point ( 0*rprec (d_SRF_his ['lat'])+ rprec (d_SRF_his ['lon']), dim1d='cell' ) |
---|
| 513 | |
---|
| 514 | SRF.areas = lmdz.geo2point ( rprec (d_SRF_his ['Areas'] ) , dim1d='cell', cumul_poles=True ) |
---|
| 515 | SRF.areafrac = lmdz.geo2point ( rprec (d_SRF_his ['AreaFrac']) , dim1d='cell', cumul_poles=True ) |
---|
| 516 | SRF.contfrac = lmdz.geo2point ( rprec (d_SRF_his ['Contfrac']) , dim1d='cell', cumul_poles=True ) |
---|
| 517 | SRF.aire = SRF.areafrac |
---|
| 518 | |
---|
| 519 | if dpar['Experiment']['SRF_HIS'] == 'ico' : |
---|
| 520 | #echo ( 'SRF areas and fractions on ICO grid' ) |
---|
| 521 | SRF.lat = rprec (d_SRF_his ['lat'] ) |
---|
| 522 | SRF.lon = rprec (d_SRF_his ['lon'] ) |
---|
| 523 | SRF.areas = rprec (d_SRF_his ['Areas'] ) |
---|
| 524 | SRF.contfrac = rprec (d_SRF_his ['Contfrac']) |
---|
| 525 | SRF.aire = SRF.areas * SRF.contfrac |
---|
| 526 | |
---|
| 527 | SRF.aire_tot = P1sum ( SRF.aire ) |
---|
| 528 | |
---|
| 529 | return dpar, SRF |
---|
| 530 | |
---|
| 531 | def ComputeGridDYN ( dpar, ATM, d_DYN_aire, d_ATM_beg ) : |
---|
| 532 | readPrec = dpar['Config']['readPrec'] |
---|
| 533 | if repr(readPrec) in [ "<class 'numpy.float64'>" , float ] : |
---|
| 534 | def rprec (ptab) : |
---|
| 535 | return ptab |
---|
| 536 | else : |
---|
| 537 | def rprec (ptab) : |
---|
| 538 | return ptab.astype(readPrec).astype(float) |
---|
| 539 | |
---|
| 540 | DYN = types.SimpleNamespace () |
---|
| 541 | if dpar['Experiment']['ICO'] : |
---|
| 542 | if dpar['Config']['SortIco'] : |
---|
| 543 | # Creation d'une clef de tri pour le fichier aire |
---|
| 544 | DYN.aire_keysort = np.lexsort ( (d_DYN_aire['lat'], d_DYN_aire['lon']) ) |
---|
| 545 | else : |
---|
| 546 | DYN.aire_keysort = np.arange ( len ( d_DYN_aire['lat'] ) ) |
---|
| 547 | |
---|
| 548 | DYN.lat = d_DYN_aire['lat'] |
---|
| 549 | DYN.lon = d_DYN_aire['lon'] |
---|
| 550 | |
---|
| 551 | DYN.aire = d_DYN_aire['aire'] |
---|
| 552 | DYN.fsea = d_DYN_aire['fract_oce'] + d_DYN_aire['fract_sic'] |
---|
| 553 | |
---|
| 554 | DYN.flnd = 1.0 - DYN.fsea |
---|
| 555 | DYN.fter = d_ATM_beg['FTER'] |
---|
| 556 | DYN.flic = d_ATM_beg['FLIC'] |
---|
| 557 | DYN.foce = d_ATM_beg['FOCE'] |
---|
| 558 | DYN.aire_fter = DYN.aire * DYN.fter |
---|
| 559 | |
---|
| 560 | if dpar['Experiment']['ATM_HIS'] == 'ico' : |
---|
| 561 | DYN.aire = ATM.aire |
---|
| 562 | DYN.foce = ATM.foce |
---|
| 563 | DYN.fsic = ATM.fsic |
---|
| 564 | DYN.flic = ATM.flic |
---|
| 565 | DYN.fter = ATM.fter |
---|
| 566 | DYN.fsea = ATM.fsea |
---|
| 567 | DYN.flnd = ATM.flnd |
---|
| 568 | DYN.aire_fter = ATM.aire_fter |
---|
| 569 | DYN.aire_flic = ATM.aire_flic |
---|
| 570 | DYN.aire_fsic = ATM.aire_fsic |
---|
| 571 | DYN.aire_foce = ATM.aire_foce |
---|
| 572 | DYN.aire_flnd = ATM.aire_flnd |
---|
| 573 | DYN.aire_fsea = ATM.aire_fsea |
---|
| 574 | |
---|
| 575 | if dpar['Experiment']['LMDZ'] : |
---|
| 576 | # Area on lon/lat grid |
---|
| 577 | DYN.aire = ATM.aire |
---|
| 578 | DYN.fsea = ATM.fsea |
---|
| 579 | DYN.flnd = ATM.flnd |
---|
| 580 | DYN.fter = rprec (d_ATM_beg['FTER']) |
---|
| 581 | DYN.flic = rprec (d_ATM_beg['FLIC']) |
---|
| 582 | DYN.aire_fter = DYN.aire * DYN.fter |
---|
| 583 | |
---|
| 584 | DYN.aire_tot = P1sum ( DYN.aire ) |
---|
| 585 | |
---|
| 586 | return dpar, DYN |
---|
| 587 | |
---|
| 588 | def ComputeGridOCE ( dpar, d_OCE_his, nperio=None ) : |
---|
| 589 | OCE = types.SimpleNamespace () |
---|
| 590 | |
---|
| 591 | # Get mask and surfaces |
---|
| 592 | sos = d_OCE_his ['sos'][0].squeeze() |
---|
| 593 | OCE.OCE_msk = nemo.lbc_mask ( xr.where ( sos>0., 1., 0. ), cd_type = 'T', nperio=nperio, sval = 0. ) |
---|
| 594 | |
---|
| 595 | so = sos = d_OCE_his ['sos'][0].squeeze() |
---|
| 596 | OCE.msk3 = nemo.lbc_mask ( xr.where ( so>0., 1., 0. ), cd_type = 'T', nperio=nperio, sval = 0. ) |
---|
| 597 | |
---|
| 598 | # lbc_mask removes the duplicate points (periodicity and north fold) |
---|
| 599 | OCE.OCE_aire = nemo.lbc_mask ( d_OCE_his ['area'] * OCE.OCE_msk, cd_type = 'T', nperio=nperio, sval = 0.0 ) |
---|
| 600 | OCE.ICE_aire = OCE.OCE_aire |
---|
| 601 | |
---|
| 602 | OCE.OCE_aire_tot = P1sum ( OCE.OCE_aire ) |
---|
| 603 | OCE.ICE_aire_tot = P1sum ( OCE.ICE_aire ) |
---|
| 604 | |
---|
| 605 | return dpar, OCE |
---|
| 606 | |
---|
[6676] | 607 | def config2dict ( pconf ) : |
---|
| 608 | ''' |
---|
| 609 | Convert a config parser object into a dictionary |
---|
| 610 | ''' |
---|
[6688] | 611 | pdict = {} |
---|
[6676] | 612 | for section in pconf.keys () : |
---|
[6688] | 613 | pdict[section] = {} |
---|
[6676] | 614 | for key in pconf[section].keys() : |
---|
| 615 | zz = str2value ( pconf[section][key] ) |
---|
[6688] | 616 | pdict[section].update ( {key:zz} ) |
---|
| 617 | return pdict |
---|
[6676] | 618 | |
---|
| 619 | def dict2config ( pdict ): |
---|
| 620 | ''' |
---|
| 621 | Convert a dictionary into a configparser object |
---|
[6688] | 622 | All values are converted to strings |
---|
[6676] | 623 | |
---|
[6688] | 624 | The dictionary must have two levels (see configparser) |
---|
[6676] | 625 | ''' |
---|
| 626 | zconf = configparser.ConfigParser ( interpolation=configparser.ExtendedInterpolation() ) |
---|
| 627 | zconf.optionxform = str # To keep capitals |
---|
[6688] | 628 | zconf.read_dict(dict2str(pdict)) |
---|
[6676] | 629 | |
---|
| 630 | return zconf |
---|
| 631 | |
---|
[6688] | 632 | def updateConf ( pconf, pdict ): |
---|
| 633 | ''' |
---|
| 634 | Update a config parser with a dictionary |
---|
| 635 | All values are converted to strings |
---|
| 636 | |
---|
| 637 | The dictionary must have two levels (see configparser) |
---|
| 638 | ''' |
---|
| 639 | pconf.read_dict (dict1str(pdict)) |
---|
| 640 | #for section in pdict.keys() : |
---|
| 641 | # if section not in pconf.keys() : pconf[section] = {} |
---|
| 642 | # for key in pdict[section].keys() : |
---|
| 643 | # pconf[section][key] = str(pdict[section][key]) |
---|
| 644 | return pconf |
---|
| 645 | |
---|
| 646 | def dict2str (pdict) : |
---|
| 647 | ''' |
---|
| 648 | Convert all values of a dictionary to strings |
---|
| 649 | ''' |
---|
| 650 | zout = {} |
---|
| 651 | for section in pdict.keys() : |
---|
| 652 | zout[section] = {} |
---|
| 653 | for key in pdict[section].keys() : |
---|
| 654 | zout[section][key] = str(pdict[section][key]) |
---|
| 655 | return zout |
---|
| 656 | |
---|
[6676] | 657 | def echo (string, f_out, end='\n') : |
---|
| 658 | '''Function to print to stdout *and* output file''' |
---|
| 659 | print ( str(string), end=end ) |
---|
| 660 | sys.stdout.flush () |
---|
| 661 | f_out.write ( str(string) + end ) |
---|
| 662 | f_out.flush () |
---|
| 663 | |
---|
| 664 | def str2value ( pz ) : |
---|
| 665 | ''' |
---|
| 666 | Tries to convert a string into integer, real, boolean or None |
---|
| 667 | ''' |
---|
| 668 | zz = pz |
---|
| 669 | zz = setBool (zz) |
---|
| 670 | zz = setNum (zz) |
---|
| 671 | zz = setNone (zz) |
---|
| 672 | return zz |
---|
| 673 | |
---|
[6508] | 674 | def setBool (chars) : |
---|
| 675 | '''Convert specific char string in boolean if possible''' |
---|
[6665] | 676 | z_set_bool = chars |
---|
| 677 | if isinstance (chars, str) : |
---|
[6508] | 678 | for key in configparser.ConfigParser.BOOLEAN_STATES.keys () : |
---|
[6665] | 679 | if chars.lower() == key : |
---|
| 680 | z_set_bool = configparser.ConfigParser.BOOLEAN_STATES[key] |
---|
| 681 | return z_set_bool |
---|
[6508] | 682 | |
---|
| 683 | def setNum (chars) : |
---|
| 684 | '''Convert specific char string in integer or real if possible''' |
---|
[6688] | 685 | zset_num = chars |
---|
[6665] | 686 | if isinstance (chars, str) : |
---|
| 687 | realnum = re.compile ("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$") |
---|
| 688 | is_number = realnum.match(chars.strip()) != None |
---|
| 689 | is_int = chars.strip().isdigit() |
---|
| 690 | if is_number : |
---|
| 691 | if is_int : zset_num = int (chars) |
---|
| 692 | else : zset_num = float (chars) |
---|
[6688] | 693 | |
---|
[6665] | 694 | return zset_num |
---|
[6508] | 695 | |
---|
| 696 | def setNone (chars) : |
---|
| 697 | '''Convert specific char string to None if possible''' |
---|
[6676] | 698 | zset_none = chars |
---|
[6665] | 699 | if isinstance (chars, str) : |
---|
| 700 | if chars in ['None', 'NONE', 'none'] : zset_none = None |
---|
| 701 | return zset_none |
---|
[6508] | 702 | |
---|
| 703 | def unDefined (char) : |
---|
[6620] | 704 | '''True if a variable is not defined, or set to None''' |
---|
[6647] | 705 | if char in globals () : |
---|
[6688] | 706 | if globals()[char] : |
---|
| 707 | zun_defined = False |
---|
| 708 | else : zun_defined = True |
---|
[6665] | 709 | else : zun_defined = True |
---|
| 710 | return zun_defined |
---|
[6508] | 711 | |
---|
[6620] | 712 | def Defined (char) : |
---|
| 713 | '''True if a variable is defined and not equal to None''' |
---|
| 714 | if char in globals () : |
---|
[6665] | 715 | if globals()[char] is None : |
---|
| 716 | zdefined = False |
---|
| 717 | else : zdefined = True |
---|
| 718 | else : zdefined = False |
---|
| 719 | return zdefined |
---|
[6620] | 720 | |
---|
[6508] | 721 | def Ksum (tab) : |
---|
[6665] | 722 | '''Kahan summation algorithm, also known as compensated summation |
---|
| 723 | |
---|
[6508] | 724 | https://en.wikipedia.org/wiki/Kahan_summation_algorithm |
---|
| 725 | ''' |
---|
[6665] | 726 | # Prepare the accumulator. |
---|
| 727 | ksum = 0.0 |
---|
| 728 | # A running compensation for lost low-order bits. |
---|
| 729 | comp = 0.0 |
---|
[6508] | 730 | |
---|
[6665] | 731 | for xx in np.where ( np.isnan(tab), 0., tab ) : |
---|
| 732 | # comp is zero the first time around. |
---|
| 733 | yy = xx - comp |
---|
| 734 | # Alas, sum is big, y small, so low-order digits of y are lost. |
---|
| 735 | tt = ksum + yy |
---|
| 736 | # (tt - Ksum) cancels the high-order part of y; subtracting y recovers negative (low part of yy) |
---|
| 737 | comp = (tt - ksum) - yy |
---|
| 738 | # Algebraically, comp should always be zero. Beware overly-aggressive optimizing compilers ! |
---|
| 739 | ksum = tt |
---|
| 740 | # Next time around, the lost low part will be added to y in a fresh attempt. |
---|
| 741 | |
---|
| 742 | return ksum |
---|
| 743 | |
---|
[6508] | 744 | def Ssum (tab) : |
---|
[6665] | 745 | '''Precision summation by sorting by absolute values''' |
---|
| 746 | ssum = np.sum ( tab[np.argsort(np.abs(tab))] ) |
---|
| 747 | return ssum |
---|
[6508] | 748 | |
---|
| 749 | def KSsum (tab) : |
---|
[6665] | 750 | '''Precision summation by sorting by absolute value, and applying Kahan summation''' |
---|
| 751 | kssum = Ksum ( tab[np.argsort(np.abs(tab))] ) |
---|
| 752 | return kssum |
---|
[6508] | 753 | |
---|
| 754 | # Choosing algorithm for precise summation |
---|
| 755 | Psum = KSsum |
---|
| 756 | |
---|
[6688] | 757 | def P1sum (ptab) : |
---|
| 758 | return Psum ( ptab.to_masked_array().ravel() ) |
---|
[6508] | 759 | |
---|
[6665] | 760 | class Timer : |
---|
| 761 | '''Measures execution time of a function''' |
---|
[6676] | 762 | def __str__ (self): |
---|
| 763 | return str (self.__class__) |
---|
[6620] | 764 | |
---|
[6676] | 765 | def __name__ (self): |
---|
[6665] | 766 | return self.__class__.__name__ |
---|
[6620] | 767 | |
---|
[6665] | 768 | def __init__ (self, func, debug=False, timer=True) : |
---|
| 769 | functools.update_wrapper (self, func) |
---|
| 770 | self.func = func |
---|
| 771 | self.num_calls = 0 |
---|
| 772 | self.cumul_time = 0. |
---|
| 773 | self.debug = debug |
---|
| 774 | self.timer = timer |
---|
| 775 | |
---|
| 776 | def __call__ (self, *args, **kwargs) : |
---|
| 777 | self.num_calls += 1 |
---|
| 778 | if self.debug : |
---|
| 779 | print ( f'>-- Calling {self.__name__} --------------------------------------------------' ) |
---|
| 780 | args_repr = [f"{repr (a)}" for a in args] |
---|
| 781 | kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items ()] |
---|
| 782 | signature = ", ".join (args_repr + kwargs_repr) |
---|
| 783 | print ( f"Signature : ({signature}") |
---|
| 784 | start_time = time.perf_counter () |
---|
| 785 | values = self.func (*args, **kwargs) |
---|
| 786 | end_time = time.perf_counter () |
---|
| 787 | run_time = end_time - start_time |
---|
| 788 | self.cumul_time += run_time |
---|
| 789 | if self.timer : |
---|
| 790 | print ( f"--> Calling {self.__name__!r} : {run_time:.3f} secs / cumul {self.cumul_time:.3f} # {self.num_calls:2d} calls") |
---|
| 791 | if self.debug : |
---|
| 792 | print ( '<------------------------------------------------------------' ) |
---|
| 793 | return values |
---|
| 794 | |
---|