physpyx 2.1.1__tar.gz → 2.2.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: physpyx
3
- Version: 2.1.1
3
+ Version: 2.2.1
4
4
  Summary: Provides a way to use python code in LaTeX
5
5
  Author: Jérôme Dufour
6
6
  Author-email: Jérôme Dufour <jerome.dufour@eduvaud.ch>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "physpyx"
3
- version = "2.1.1"
3
+ version = "2.2.1"
4
4
  authors = [
5
5
  { name="Jérôme Dufour", email="jerome.dufour@eduvaud.ch" },
6
6
  ]
@@ -1,6 +1,7 @@
1
1
  from .astronomy import Orbit
2
+ from .context import NuclearContext
2
3
  from .nuclide import NuclideTable
3
4
  from .physpyx import PhysPyX
4
5
  from .qty import Qty
5
6
 
6
- __all__ = ["NuclideTable", "PhysPyX", "Qty", "Orbit"]
7
+ __all__ = ["NuclideTable", "NuclearContext", "Orbit", "PhysPyX", "Qty"]
@@ -0,0 +1,35 @@
1
+ from pint.facets.context import Context
2
+ from pint.facets.plain.objects import UnitsContainer
3
+
4
+
5
+ class SiunitxContext(Context):
6
+ preferred_units: dict[UnitsContainer, str]
7
+
8
+
9
+ class NuclearContext(SiunitxContext):
10
+ def __init__(self, preferred_units: bool = True):
11
+ super().__init__("nuclear")
12
+ self.add_transformation(
13
+ "[mass]",
14
+ "[mass] * [length]**2 / [time]**2",
15
+ lambda ureg, x: x * ureg.speed_of_light * ureg.speed_of_light,
16
+ )
17
+ self.add_transformation(
18
+ "[mass] * [length]**2 / [time]**2",
19
+ "[mass]",
20
+ lambda ureg, x: x / ureg.speed_of_light / ureg.speed_of_light,
21
+ )
22
+ self.preferred_units = (
23
+ {
24
+ UnitsContainer({"[mass]": 1}): "amu",
25
+ UnitsContainer(
26
+ {
27
+ "[mass]": 1,
28
+ "[length]": 2,
29
+ "[time]": -2,
30
+ }
31
+ ): "megaelectronvolt",
32
+ }
33
+ if preferred_units
34
+ else {}
35
+ )
@@ -2,10 +2,16 @@ import re
2
2
  import sys
3
3
 
4
4
  from logging import getLogger
5
- from pint._typing import Scalar
5
+ from typing import TYPE_CHECKING
6
+
7
+ from pint.facets.context import Context
8
+
6
9
  from physpyx.manager import PTManager
7
10
  from physpyx.quantity import AltDict, Constants, SiunitxQuantity, SiunitxUnitRegistry
8
11
 
12
+ if TYPE_CHECKING:
13
+ from pint._typing import Scalar
14
+
9
15
  logger = getLogger(__name__)
10
16
 
11
17
 
@@ -14,7 +20,7 @@ class Qty(PTManager):
14
20
  This class should be used as a context manager.
15
21
  """
16
22
 
17
- def __init__(self, fname: str, context: str = ""):
23
+ def __init__(self, fname: str, context: Context | str = ""):
18
24
  """
19
25
  :param fname: name of the ".pyx" file saved on exit
20
26
  :param context: `Pint` feature that allows unit conversion. For Instance, if
@@ -24,18 +30,6 @@ class Qty(PTManager):
24
30
  super().__init__(fname)
25
31
  self._constants = Constants(self._fname.parent / "physpyx_constants.json")
26
32
  self._ureg = SiunitxUnitRegistry()
27
- self._ureg.define("heure = hour")
28
- self._ureg.define("heures = hours")
29
- self._ureg.define("jour = day")
30
- self._ureg.define("jours = days")
31
- self._ureg.define("semaine = week")
32
- self._ureg.define("semaines = weeks")
33
- self._ureg.define("mois = month")
34
- self._ureg.define("an = year")
35
- self._ureg.define("ans = years")
36
- self._ureg.define("celerity = speed_of_light")
37
- self._ureg.define("chf = [currency] = franc")
38
- self._ureg.define("ct = 0.01 * chf = centime")
39
33
  if context:
40
34
  self._ureg.enable_contexts(context)
41
35
 
@@ -2,12 +2,16 @@ from json import loads
2
2
  from logging import getLogger
3
3
  from numpy import cross, ndarray, linalg
4
4
  from pathlib import Path
5
- from pint._typing import Magnitude, UnitLike
6
5
  from pint.registry import GenericUnitRegistry, Quantity, Unit
7
- from typing import Generator, TypedDict, cast
6
+ from pint.facets.context import Context
7
+ from typing import TYPE_CHECKING, Any, Generator, TypedDict, cast
8
8
 
9
+ from physpyx.context import SiunitxContext
9
10
  from physpyx.nuclide import NuclideTable
10
11
 
12
+ if TYPE_CHECKING:
13
+ from pint._typing import Magnitude, UnitLike
14
+
11
15
  logger = getLogger(__name__)
12
16
 
13
17
 
@@ -40,29 +44,6 @@ class SiunitxQuantity(Quantity):
40
44
  "meter_Hg": "mHg",
41
45
  "watt_hour": "watthour",
42
46
  }
43
- _preferred_units = {
44
- Unit(name).dimensionality: name
45
- for name in [
46
- "meter",
47
- "second",
48
- "kilogram",
49
- "ampere",
50
- "kelvin",
51
- "mole",
52
- "meter per second",
53
- "meter per second squared",
54
- "newton",
55
- "joule",
56
- "watt",
57
- "pascal",
58
- "volt",
59
- "ohm",
60
- "tesla",
61
- "henry",
62
- "farad",
63
- "coulomb",
64
- ]
65
- }
66
47
 
67
48
  def __new__(
68
49
  cls,
@@ -110,12 +91,7 @@ class SiunitxQuantity(Quantity):
110
91
  if self._base:
111
92
  quantity = cast(SiunitxQuantity, self.to_base_units())
112
93
  elif self._preferred:
113
- quantity = cast(
114
- SiunitxQuantity,
115
- self.to(to)
116
- if (to := self._preferred_units.get(self.dimensionality, None))
117
- else self.to_reduced_units(),
118
- )
94
+ quantity = self._REGISTRY.to_preferred_units(self)
119
95
  if self._compact:
120
96
  quantity = cast(SiunitxQuantity, self.to_compact())
121
97
 
@@ -170,6 +146,11 @@ class SiunitxQuantity(Quantity):
170
146
  # "PlainQuantity[Unknown]"'
171
147
  return cast(SiunitxQuantity, super().__neg__())
172
148
 
149
+ def __add__(self, other: object) -> "SiunitxQuantity":
150
+ # NOTE: to fix typing warning 'Cannot access attribute "???" for class
151
+ # "PlainQuantity[Unknown]"'
152
+ return cast(SiunitxQuantity, super().__add__(other))
153
+
173
154
  def _format_unit(self) -> str:
174
155
  num = ""
175
156
  den = ""
@@ -209,9 +190,8 @@ class SiunitxQuantity(Quantity):
209
190
  else str(self),
210
191
  )
211
192
  except ValueError as e:
212
- # TODO: report the correct error in
213
- # PTManager.write_errorfile, not the one raised in
214
- # PTManager.__exit__
193
+ # TODO: report the correct error in PTManager.write_errorfile, not
194
+ # the one raised in PTManager.__exit__
215
195
  logger.error(f"exporting {name} failed, {self._fmt}")
216
196
  e.add_note(f"exporting {name} failed")
217
197
  raise e
@@ -288,6 +268,58 @@ class SiunitxUnitRegistry(GenericUnitRegistry):
288
268
  Quantity: type = SiunitxQuantity
289
269
  Unit: type = Unit
290
270
 
271
+ def __init__(self):
272
+ super().__init__()
273
+ self.define("heure = hour")
274
+ self.define("heures = hours")
275
+ self.define("jour = day")
276
+ self.define("jours = days")
277
+ self.define("semaine = week")
278
+ self.define("semaines = weeks")
279
+ self.define("mois = month")
280
+ self.define("an = year")
281
+ self.define("ans = years")
282
+ self.define("celerity = speed_of_light")
283
+ self.define("chf = [currency] = franc")
284
+ self.define("ct = 0.01 * chf = centime")
285
+ self._preferred_units = {
286
+ Unit(name).dimensionality: name
287
+ for name in [
288
+ "meter",
289
+ "second",
290
+ "kilogram",
291
+ "ampere",
292
+ "kelvin",
293
+ "mole",
294
+ "meter per second",
295
+ "meter per second squared",
296
+ "newton",
297
+ "joule",
298
+ "watt",
299
+ "pascal",
300
+ "volt",
301
+ "ohm",
302
+ "tesla",
303
+ "henry",
304
+ "farad",
305
+ "coulomb",
306
+ ]
307
+ }
308
+
309
+ def enable_contexts(self, *names_or_contexts: str | Context, **kwargs: Any) -> None:
310
+ for context in names_or_contexts:
311
+ if isinstance(context, SiunitxContext):
312
+ self._preferred_units |= context.preferred_units
313
+ return super().enable_contexts(*names_or_contexts, **kwargs)
314
+
315
+ def to_preferred_units(self, qty: SiunitxQuantity) -> SiunitxQuantity:
316
+ return cast(
317
+ SiunitxQuantity,
318
+ qty.to(to)
319
+ if (to := self._preferred_units.get(qty.dimensionality, None))
320
+ else qty.to_reduced_units(),
321
+ )
322
+
291
323
 
292
324
  class Constants:
293
325
  _CONSTANTS = {
File without changes
File without changes
File without changes
File without changes
File without changes