lsapy 0.1.0.dev1__py3-none-any.whl → 0.1.0.dev2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
lsapy/__init__.py CHANGED
@@ -6,4 +6,4 @@ from lsapy.lsa import LandSuitability
6
6
 
7
7
  __author__ = "Baptiste Hamon"
8
8
  __email__ = "baptiste.hamon@pg.canterbury.ac.nz"
9
- __version__ = "0.1.0-dev1"
9
+ __version__ = "0.1.0-dev2"
lsapy/criteria.py CHANGED
@@ -8,16 +8,72 @@ __all__ = ["SuitabilityCriteria"]
8
8
 
9
9
 
10
10
  class SuitabilityCriteria:
11
- def __init__(
12
- self,
13
- name: str,
14
- indicator: xr.Dataset | xr.DataArray,
15
- func: SuitabilityFunction | MembershipSuitFunction | DiscreteSuitFunction,
16
- weight: int | float | None = 1,
17
- category: str | None = None,
18
- long_name: str | None = None,
19
- description: str | None = None
11
+ """
12
+ A data structure for suitability criteria.
13
+
14
+ Suitability criteria are used to compute the suitability of a location from an indicator and based on a set of rules
15
+ defined by a suitability function. The suitability criteria can be weighted and categorized defining how it will be
16
+ aggregated with other criteria.
17
+
18
+ Parameters
19
+ ----------
20
+ name : str
21
+ Name of the suitability criteria.
22
+ indicator : xr.DataArray
23
+ Indicator on which the criteria is based.
24
+ func : SuitabilityFunction | MembershipSuitFunction | DiscreteSuitFunction
25
+ Suitability function describing how the suitability of the criteria is computed.
26
+ weight : int | float | None, optional
27
+ Weight of the criteria used in the aggregation process if a weighted aggregation method is used.
28
+ The default is 1.
29
+ category : str | None, optional
30
+ Category of the criteria. The default is None.
31
+ long_name : str | None, optional
32
+ A long name for the criteria. The default is None.
33
+ description : str | None, optional
34
+ A description for the criteria. The default is None. # TODO: check default behavior
35
+
36
+ Examples
37
+ --------
38
+ Here is an example using the sample soil data with the drainage class (DRC) as indicator for the criteria.
39
+
40
+ >>> from lsapy.utils import load_soil_data, load_climate_data
41
+ >>> from xclim.indicators.atmos import growing_degree_days # doctest: +SKIP
42
+ <BLANKLINE>
43
+ >>> soil_data = load_soil_data()
44
+ >>> sc = SuitabilityCriteria( # doctest: +SKIP
45
+ ... name="drainage_class",
46
+ ... long_name="Drainage Class Suitability",
47
+ ... weight=3,
48
+ ... category="soilTerrain",
49
+ ... indicator=soil_data["DRC"],
50
+ ... func=SuitabilityFunction(
51
+ ... func_method="discrete", func_params={"rules": {"1": 0, "2": 0.1, "3": 0.5, "4": 0.9, "5": 1}}
52
+ ... ),
53
+ ... )
20
54
 
55
+ Here is another example using the sample climate data with the growing degree days (GDD)
56
+ as indicator for the criteria computing using the `xclim` package.
57
+
58
+ >>> gdd = growing_degree_days(clim_data["tas"], thresh="10 degC", freq="YS-JUL") # doctest: +SKIP
59
+ >>> sc = SuitabilityCriteria( # doctest: +SKIP
60
+ ... name = "growing_degree_days"
61
+ ... long_name= "Growing Degree Days Suitability",
62
+ ... weight= 1,
63
+ ... category= "climate",
64
+ ... indicator=gdd,
65
+ ... func = SuitabilityFunction(func_method='vetharaniam2022_eq5', func_params={'a': -1.41, 'b': 801}))
66
+ """
67
+
68
+ def __init__(
69
+ self,
70
+ name: str,
71
+ indicator: xr.Dataset | xr.DataArray, # TODO: check if it's work with ds
72
+ func: SuitabilityFunction | MembershipSuitFunction | DiscreteSuitFunction,
73
+ weight: int | float | None = 1,
74
+ category: str | None = None,
75
+ long_name: str | None = None,
76
+ description: str | None = None,
21
77
  ) -> None:
22
78
  self.name = name
23
79
  self.indicator = indicator
@@ -29,6 +85,7 @@ class SuitabilityCriteria:
29
85
  self._from_indicator = _get_indicator_description(indicator)
30
86
 
31
87
  def __repr__(self) -> str:
88
+ """Returns a string representation for a particular criteria."""
32
89
  attrs = []
33
90
  attrs.append(f"name='{self.name}'")
34
91
  attrs.append(f"indicator={self.indicator.name}")
@@ -43,29 +100,44 @@ class SuitabilityCriteria:
43
100
  return f"{self.__class__.__name__}({', '.join(attrs) if attrs else ''})"
44
101
 
45
102
  def compute(self) -> xr.DataArray:
46
- if self.func.func_method == 'discrete': # need to vectorize the discrete function
103
+ """
104
+ Compute the suitability of the criteria.
105
+
106
+ Returns a xarray DataArray with criteria suitability. The attributes of the DataArray describe how
107
+ the suitability was computed.
108
+
109
+ Returns
110
+ -------
111
+ xr.DataArray
112
+ Criteria suitability.
113
+ """
114
+ if self.func.func_method == "discrete": # need to vectorize the discrete function
47
115
  sc: xr.DataArray = xr.apply_ufunc(self.func.map, self.indicator).rename(self.name)
48
116
  else:
49
117
  sc: xr.DataArray = self.func.map(self.indicator).rename(self.name)
50
118
  return sc.assign_attrs(
51
- dict({k: v for k, v in self.attrs.items() if k not in ['name', 'func_method', 'from_indicator']},
52
- **{
53
- 'history': f"func_method: {self.func}; from_indicator: [{self._from_indicator}]",
54
- 'compute': 'done'
55
- })
119
+ dict(
120
+ {k: v for k, v in self.attrs.items() if k not in ["name", "func_method", "from_indicator"]},
121
+ **{"history": f"func_method: {self.func}; from_indicator: [{self._from_indicator}]", "compute": "done"},
122
+ )
56
123
  )
57
124
 
58
125
  @property
59
- def attrs(self):
60
- return {k: v for k, v in {
61
- 'name': self.name,
62
- 'weight': self.weight,
63
- 'category': self.category,
64
- 'long_name': self.long_name,
65
- 'description': self.description,
66
- 'func_method': self.func,
67
- 'from_indicator': self._from_indicator
68
- }.items() if v is not None}
126
+ def attrs(self) -> dict:
127
+ """Dictionary of the criteria attributes."""
128
+ return {
129
+ k: v
130
+ for k, v in {
131
+ "name": self.name,
132
+ "weight": self.weight,
133
+ "category": self.category,
134
+ "long_name": self.long_name,
135
+ "description": self.description,
136
+ "func_method": self.func,
137
+ "from_indicator": self._from_indicator,
138
+ }.items()
139
+ if v is not None
140
+ }
69
141
 
70
142
 
71
143
  def _get_indicator_description(indicator: xr.Dataset | xr.DataArray) -> str: