Skip to content

Commit

Permalink
added max_scaling_factor for linear_scaling (*) and delta_method (*) …
Browse files Browse the repository at this point in the history
…to avoid unrealistic results in some cases
  • Loading branch information
btschwertfeger committed Nov 5, 2022
1 parent 60ab4a4 commit a555820
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bias-Adjustment-Python
# Bias adjustment/correction procedures for climatic reasearch

<div style="text-align: center">

Expand All @@ -9,7 +9,7 @@

</div>

Collection of different scale- and distribution-based bias adjustment techniques for climatic research. (see `examples.ipynb` for help)
Collection of different scale- and distribution-based bias adjustment techniques for climatic research (see `examples.ipynb` for help).

Bias adjustment procedures in Python are very slow, so they should not be used on large data sets.
A C++ implementation that works way faster can be found [here](https://github.com/btschwertfeger/Bias-Adjustment-Cpp).
Expand Down Expand Up @@ -88,6 +88,11 @@ qdm_result = cm.adjust_3d( # 3d = 2 spatial and 1 time dimension
# ratio based variables like precipitation)
```

Notes:

- When using the `adjust_3d` method you have to specify the method by name.
- For the multiplicative linear scaling and delta method is a maximum scaling factor of 10 set. This can be changed by the `max_scaling_factor` parameter.

---

## Examples (see repository on [GitHub](https://github.com/btschwertfeger/Bias-Adjustment-Python))
Expand Down
20 changes: 18 additions & 2 deletions cmethods/CMethods.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ def __init__(self, method: str, available_methods: list):
ADDITIVE = ['+', 'add']
MULTIPLICATIVE = ['*', 'mult']

MAX_SCALING_FACTOR = 10

def __init__(self):
pass

Expand Down Expand Up @@ -289,7 +291,14 @@ def linear_scaling(cls,
if group != None: return cls.grouped_correction(method='linear_scaling', obs=obs, simh=simh, simp=simp, group=group, kind=kind, **kwargs)
else:
if kind in cls.ADDITIVE: return np.array(simp) + (np.nanmean(obs) - np.nanmean(simh)) # Eq. 1
elif kind in cls.MULTIPLICATIVE: return np.array(simp) * (np.nanmean(obs) / np.nanmean(simh)) # Eq. 2
elif kind in cls.MULTIPLICATIVE:
scaling_factor = (np.nanmean(obs) / np.nanmean(simh))
if scaling_factor > 0 and scaling_factor > abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR)):
return np.array(simp) * abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR))
elif scaling_factor < 0 and scaling_factor < -abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR)):
return np.array(simp) * -abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR))
else:
return np.array(simp) * scaling_factor # Eq. 2
else: raise ValueError('Scaling type invalid. Valid options for param kind: "+" and "*"')

# ? -----========= V A R I A N C E - S C A L I N G =========------
Expand Down Expand Up @@ -404,7 +413,14 @@ def delta_method(cls,
if group != None: return cls.grouped_correction(method='delta_method', obs=obs, simh=simh, simp=simp, group=group, kind=kind, **kwargs)
else:
if kind in cls.ADDITIVE: return np.array(obs) + (np.nanmean(simp) - np.nanmean(simh)) # Eq. 1
elif kind in cls.MULTIPLICATIVE: return np.array(obs) * (np.nanmean(simp) / np.nanmean(simh)) # Eq. 2
elif kind in cls.MULTIPLICATIVE:
scaling_factor = (np.nanmean(simp) / np.nanmean(simh))
if scaling_factor > 0 and scaling_factor > abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR)):
return np.array(obs) * abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR))
elif scaling_factor < 0 and scaling_factor < -abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR)):
return np.array(obs) * -abs(kwargs.get('max_scaling_factor', cls.MAX_SCALING_FACTOR))
else:
return np.array(obs) * scaling_factor # Eq. 2
else: raise ValueError(f'{kind} not implemented! Use "+" or "*" instead.')


Expand Down
2 changes: 1 addition & 1 deletion cmethods/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VERSION = (0,5,3)
VERSION = (0,5,4)
__version__ = '.'.join(map(str, VERSION))
4 changes: 4 additions & 0 deletions cmethods/tests/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
sys.path.append('../../')
from cmethods.CMethods import CMethods

if True: # local space
import cmethods
print(cmethods.__file__)

formatter = logging.Formatter(
fmt='%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' # %I:%M:%S %p AM|PM format
Expand Down

0 comments on commit a555820

Please sign in to comment.