|
1 |
| -#!/bin/python3 |
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
2 | 3 |
|
3 |
| -__descrption__ = 'Script to adjust climate biases in 3D Climate data' |
4 |
| -__author__ = 'Benjamin Thomas Schwertfeger' |
| 4 | +__descrption__ = "Script to adjust climate biases in 3D Climate data" |
| 5 | +__author__ = "Benjamin Thomas Schwertfeger" |
5 | 6 | __copyright__ = __author__
|
6 |
| - |
7 |
| -__link__ = 'https://b-schwertfeger.de' |
8 |
| -__github__ = 'https://github.com/btschwertfeger/Bias-Adjustment-Python'; |
| 7 | + |
| 8 | +__link__ = "https://b-schwertfeger.de" |
| 9 | +__github__ = "https://github.com/btschwertfeger/Bias-Adjustment-Python" |
9 | 10 |
|
10 | 11 | import argparse
|
11 |
| -import logging, sys |
| 12 | +import logging |
| 13 | +import sys |
| 14 | + |
12 | 15 | import xarray as xr
|
13 | 16 |
|
14 | 17 | from cmethods.CMethods import CMethods
|
15 | 18 |
|
16 | 19 | # * ----- L O G G I N G -----
|
17 | 20 | formatter = logging.Formatter(
|
18 |
| - fmt='%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s', |
19 |
| - datefmt='%Y-%m-%d %H:%M:%S' |
| 21 | + fmt="%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s", |
| 22 | + datefmt="%Y-%m-%d %H:%M:%S", |
20 | 23 | )
|
21 | 24 |
|
22 | 25 | log = logging.getLogger()
|
|
26 | 29 | logging.getLogger().addHandler(screen_handler)
|
27 | 30 |
|
28 | 31 | # * ----- I N P U T - H A N D L I N G -----
|
29 |
| -parser = argparse.ArgumentParser(description='Adjust climate data based on bias correction algorithms and magic.') |
30 |
| -parser.add_argument('--obs', '--observation', dest='obs_fpath', type=str, help='Observation dataset') |
31 |
| -parser.add_argument('--contr', '--control', dest='contr_fpath', type=str, help='Control dataset') |
32 |
| -parser.add_argument('--scen', '--scenario', dest='scen_fpath', type=str, help='Scenario dataset (data to adjust)') |
| 32 | +parser = argparse.ArgumentParser( |
| 33 | + description="Adjust climate data based on bias correction algorithms and magic." |
| 34 | +) |
| 35 | +parser.add_argument( |
| 36 | + "--obs", "--observation", dest="obs_fpath", type=str, help="Observation dataset" |
| 37 | +) |
| 38 | +parser.add_argument( |
| 39 | + "--contr", "--control", dest="contr_fpath", type=str, help="Control dataset" |
| 40 | +) |
| 41 | +parser.add_argument( |
| 42 | + "--scen", |
| 43 | + "--scenario", |
| 44 | + dest="scen_fpath", |
| 45 | + type=str, |
| 46 | + help="Scenario dataset (data to adjust)", |
| 47 | +) |
33 | 48 |
|
34 |
| -parser.add_argument('-m', '--method', dest='method', type=str, help='Correction method') |
35 |
| -parser.add_argument('-v', '--variable', dest='var', type=str, default='tas', help='Variable to adjust') |
36 |
| -parser.add_argument('-u', '--unit', dest='unit', type=str, default='°C', help='Unit of the varible') |
| 49 | +parser.add_argument("-m", "--method", dest="method", type=str, help="Correction method") |
| 50 | +parser.add_argument( |
| 51 | + "-v", "--variable", dest="var", type=str, default="tas", help="Variable to adjust" |
| 52 | +) |
| 53 | +parser.add_argument( |
| 54 | + "-u", "--unit", dest="unit", type=str, default="°C", help="Unit of the varible" |
| 55 | +) |
37 | 56 |
|
38 |
| -parser.add_argument('-g', '--group', dest='group', type=str, default=None, help='Value grouping, default: time, (options: time.month, time.dayofyear, time.year') |
39 |
| -parser.add_argument('-k', '--kind', dest='kind', type=str, default='+', help='+ or *, default: +') |
40 |
| -parser.add_argument('-n', '--nquantiles', dest='n_quantiles', type=int, default=100, help='Nr. of Quantiles to use') |
| 57 | +parser.add_argument( |
| 58 | + "-g", |
| 59 | + "--group", |
| 60 | + dest="group", |
| 61 | + type=str, |
| 62 | + default=None, |
| 63 | + help="Value grouping, default: time, (options: time.month, time.dayofyear, time.year", |
| 64 | +) |
| 65 | +parser.add_argument( |
| 66 | + "-k", "--kind", dest="kind", type=str, default="+", help="+ or *, default: +" |
| 67 | +) |
| 68 | +parser.add_argument( |
| 69 | + "-n", |
| 70 | + "--nquantiles", |
| 71 | + dest="n_quantiles", |
| 72 | + type=int, |
| 73 | + default=100, |
| 74 | + help="Nr. of Quantiles to use", |
| 75 | +) |
41 | 76 |
|
42 |
| -parser.add_argument('-p', '--processes', dest='p', type=int, default=1, help='Multiprocessing with n processes, default: 1') |
| 77 | +parser.add_argument( |
| 78 | + "-p", |
| 79 | + "--processes", |
| 80 | + dest="p", |
| 81 | + type=int, |
| 82 | + default=1, |
| 83 | + help="Multiprocessing with n processes, default: 1", |
| 84 | +) |
43 | 85 | params = vars(parser.parse_args())
|
44 | 86 |
|
45 |
| -obs_fpath = params['obs_fpath'] |
46 |
| -contr_fpath = params['contr_fpath'] |
47 |
| -scen_fpath = params['scen_fpath'] |
| 87 | +obs_fpath = params["obs_fpath"] |
| 88 | +contr_fpath = params["contr_fpath"] |
| 89 | +scen_fpath = params["scen_fpath"] |
| 90 | + |
| 91 | +method = params["method"] |
| 92 | +var = params["var"] |
| 93 | +unit = params["unit"] |
| 94 | +group = params["group"] |
| 95 | +kind = params["kind"] |
| 96 | +n_quantiles = params["n_quantiles"] |
| 97 | +n_jobs = params["p"] |
48 | 98 |
|
49 |
| -method = params['method'] |
50 |
| -var = params['var'] |
51 |
| -unit = params['unit'] |
52 |
| -group = params['group'] |
53 |
| -kind = params['kind'] |
54 |
| -n_quantiles = params['n_quantiles'] |
55 |
| -n_jobs = params['p'] |
56 | 99 |
|
57 | 100 | # * ----- ----- -----M A I N ----- ----- -----
|
58 | 101 | def main() -> None:
|
59 | 102 | cm = CMethods()
|
60 | 103 |
|
61 |
| - if method not in cm.get_available_methods(): raise ValueError(f'Unknown method {method}. Available methods: {cm.get_available_methods()}') |
| 104 | + if method not in cm.get_available_methods(): |
| 105 | + raise ValueError( |
| 106 | + f"Unknown method {method}. Available methods: {cm.get_available_methods()}" |
| 107 | + ) |
62 | 108 |
|
63 | 109 | ds_obs = xr.open_dataset(obs_fpath)[var]
|
64 | 110 | ds_simh = xr.open_dataset(contr_fpath)[var]
|
65 | 111 | ds_simp = xr.open_dataset(scen_fpath)[var]
|
66 |
| - log.info('Data Loaded') |
| 112 | + log.info("Data Loaded") |
67 | 113 |
|
68 |
| - ds_obs.attrs['unit'] = unit |
69 |
| - ds_simh.attrs['unit'] = unit |
70 |
| - ds_simp.attrs['unit'] = unit |
| 114 | + ds_obs.attrs["unit"] = unit |
| 115 | + ds_simh.attrs["unit"] = unit |
| 116 | + ds_simp.attrs["unit"] = unit |
71 | 117 |
|
72 |
| - start_date: str = ds_simp['time'][0].dt.strftime('%Y%m%d').values.ravel()[0] |
73 |
| - end_date: str = ds_simp['time'][-1].dt.strftime('%Y%m%d').values.ravel()[0] |
| 118 | + start_date: str = ds_simp["time"][0].dt.strftime("%Y%m%d").values.ravel()[0] |
| 119 | + end_date: str = ds_simp["time"][-1].dt.strftime("%Y%m%d").values.ravel()[0] |
74 | 120 |
|
75 |
| - descr1, descr2 = '', '' |
| 121 | + descr1, descr2 = "", "" |
76 | 122 | if method in cm.DISTRIBUTION_METHODS:
|
77 |
| - descr1 = f'_quantiles-{n_quantiles}' |
| 123 | + descr1 = f"_quantiles-{n_quantiles}" |
78 | 124 |
|
79 | 125 | # ----- Adjustment -----
|
80 |
| - log.info(f'Starting {method} adjustment') |
| 126 | + log.info(f"Starting {method} adjustment") |
81 | 127 | result = cm.adjust_3d(
|
82 |
| - method = method, |
83 |
| - obs = ds_obs, |
84 |
| - simh = ds_simh, |
85 |
| - simp = ds_simp, |
86 |
| - n_quantiles = n_quantiles, |
87 |
| - kind = kind, |
88 |
| - group = group, |
89 |
| - n_jobs = n_jobs |
| 128 | + method=method, |
| 129 | + obs=ds_obs, |
| 130 | + simh=ds_simh, |
| 131 | + simp=ds_simp, |
| 132 | + n_quantiles=n_quantiles, |
| 133 | + kind=kind, |
| 134 | + group=group, |
| 135 | + n_jobs=n_jobs, |
90 | 136 | )
|
91 |
| - log.info('Saving now') |
| 137 | + log.info("Saving now") |
92 | 138 | result.name = var
|
93 |
| - result['time'] = ds_simp['time'] |
94 |
| - result.to_netcdf(f'{method}_result_var-{var}{descr1}_kind-{kind}_group-{group}{descr2}_{start_date}_{end_date}.nc') |
95 |
| - log.info('Done') |
| 139 | + result["time"] = ds_simp["time"] |
| 140 | + result.to_netcdf( |
| 141 | + f"{method}_result_var-{var}{descr1}_kind-{kind}_group-{group}{descr2}_{start_date}_{end_date}.nc" |
| 142 | + ) |
| 143 | + log.info("Done") |
96 | 144 |
|
97 | 145 |
|
98 |
| -if __name__ == '__main__': |
| 146 | +if __name__ == "__main__": |
99 | 147 | main()
|
100 | 148 |
|
101 | 149 |
|
|
0 commit comments