Skip to content

Commit 866fa14

Browse files
committed
Remove some more potential list code that cannot be accessed anymore with the switch to CompositePotential and add some further tests
1 parent 154c37b commit 866fa14

7 files changed

Lines changed: 91 additions & 52 deletions

File tree

galpy/orbit/Orbits.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2694,7 +2694,7 @@ def Jacobi(self, *args, **kwargs):
26942694
raise AttributeError("Integrate orbit or specify pot=")
26952695
else:
26962696
pot = kwargs["pot"]
2697-
if isinstance(pot, (list, CompositePotential)):
2697+
if isinstance(pot, (CompositePotential, planarCompositePotential)):
26982698
for p in pot:
26992699
if hasattr(p, "OmegaP"):
27002700
OmegaP = p.OmegaP()

galpy/potential/Potential.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ def _check_potential_list_and_deprecate(Pot):
118118
elif all(d >= 2 for d in dims):
119119
from .planarCompositePotential import planarCompositePotential
120120

121-
if any(d != 2 for d in dims):
121+
if any(d != 2 for d in dims): # pragma: no cover
122122
# Mixed 2D and 3D potentials: convert 3D to 2D
123+
# not worrying about coverage, because this is behavior that isn't
124+
# really recommended and will be deprecated
123125
Pot = [p.toPlanar() if _dim(p) == 3 else p for p in Pot]
124126

125127
Pot = planarCompositePotential(Pot)
@@ -4102,12 +4104,10 @@ def _dim(Pot):
41024104
Notes
41034105
-----
41044106
- 2016-04-19 - Written - Bovy (UofT)
4107+
- 2025-12-29 - Just returns Pot.dim now that lists of potentials are being deprecated - Bovy (UofT)
41054108
41064109
"""
4107-
if isinstance(Pot, list):
4108-
return min([_dim(p) for p in Pot])
4109-
else:
4110-
return Pot.dim
4110+
return Pot.dim
41114111

41124112

41134113
def _isNonAxi(Pot):

galpy/potential/planarForce.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def __add__(self, b):
150150
# Physical compatibility is checked in planarCompositePotential.__init__
151151
return planarCompositePotential(self, b)
152152

153-
# Define separately to keep order
153+
# Define separately to catch errors
154154
def __radd__(self, b):
155155
from ..potential import flatten as flatten_pot
156156
from .planarCompositePotential import planarCompositePotential
@@ -160,8 +160,8 @@ def __radd__(self, b):
160160
"""Can only combine galpy Force objects with """
161161
"""other Force objects or combinations thereof"""
162162
)
163-
# Physical compatibility is checked in planarCompositePotential.__init__
164-
return planarCompositePotential(b, self)
163+
164+
# Can't add anything that isn't handled elsewhere, so no further code here
165165

166166
def turn_physical_off(self):
167167
"""

galpy/potential/planarPotential.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,7 @@ def RZToplanarPotential(RZPot):
707707
if isinstance(RZPot, CompositePotential):
708708
out = []
709709
for pot in RZPot:
710-
if isinstance(pot, planarPotential) and not pot.isNonAxi:
711-
out.append(pot)
712-
elif isinstance(pot, Potential) and not pot.isNonAxi:
710+
if isinstance(pot, Potential) and not pot.isNonAxi:
713711
out.append(planarPotentialFromRZPotential(pot))
714712
else:
715713
raise PotentialError(
@@ -975,15 +973,15 @@ def toPlanarPotential(Pot):
975973
if isinstance(Pot, CompositePotential):
976974
out = []
977975
for pot in Pot:
978-
if isinstance(pot, planarForce):
979-
out.append(pot)
980-
elif isinstance(pot, Potential) and pot.isNonAxi:
976+
if isinstance(pot, Potential) and pot.isNonAxi:
981977
out.append(planarPotentialFromFullPotential(pot))
982978
elif isinstance(pot, Potential):
983979
out.append(planarPotentialFromRZPotential(pot))
984980
elif isinstance(pot, DissipativeForce):
985981
out.append(planarDissipativeForceFromFullDissipativeForce(pot))
986-
else:
982+
else: # pragma: no cover
983+
# Can't get here, because there can't be something that's not a proper
984+
# potential/force in a CompositePotential, but leaving it in case this ever changes
987985
raise PotentialError(
988986
"Input to 'toPlanarPotential' is neither an Potential-instance or a list of such instances"
989987
)

galpy/potential/verticalPotential.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,8 @@ def RZToverticalPotential(RZPot, R):
182182
if isinstance(RZPot, CompositePotential):
183183
out = []
184184
for pot in RZPot:
185-
if isinstance(pot, linearPotential):
186-
out.append(pot)
187-
elif isinstance(pot, Potential):
185+
if isinstance(pot, Potential):
188186
out.append(verticalPotential(pot, R))
189-
elif isinstance(pot, planarPotential):
190-
raise PotentialError(
191-
"Input to 'RZToverticalPotential' cannot be a planarPotential"
192-
)
193187
else: # pragma: no cover
194188
raise PotentialError(
195189
"Input to 'RZToverticalPotential' is neither an RZPotential-instance or a combination of such instances"
@@ -259,14 +253,8 @@ def toVerticalPotential(Pot, R, phi=None, t0=0.0):
259253
if isinstance(Pot, CompositePotential):
260254
out = []
261255
for pot in Pot:
262-
if isinstance(pot, linearPotential):
263-
out.append(pot)
264-
elif isinstance(pot, Potential):
256+
if isinstance(pot, Potential):
265257
out.append(verticalPotential(pot, R, phi=phi, t0=t0))
266-
elif isinstance(pot, planarPotential):
267-
raise PotentialError(
268-
"Input to 'toVerticalPotential' cannot be a planarPotential"
269-
)
270258
else: # pragma: no cover
271259
# All other cases should have been caught by the
272260
# conversion.get_physical test above

galpy/util/conversion.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -843,27 +843,11 @@ def physical_output(obj: Any, kwargs: dict, quantity: str) -> Tuple[bool, float,
843843
ro = kwargs.get("ro", None)
844844
if ro is None and (roSet or (hasattr(obj, "_roSet") and obj._roSet)):
845845
ro = obj._ro
846-
if (
847-
ro is None
848-
and isinstance(obj, list)
849-
and hasattr(obj[0], "_roSet")
850-
and obj[0]._roSet
851-
):
852-
# For lists of Potentials
853-
ro = obj[0]._ro
854846
if _APY_LOADED and isinstance(ro, units.Quantity):
855847
ro = ro.to(units.kpc).value
856848
vo = kwargs.get("vo", None)
857849
if vo is None and (voSet or (hasattr(obj, "_voSet") and obj._voSet)):
858850
vo = obj._vo
859-
if (
860-
vo is None
861-
and isinstance(obj, list)
862-
and hasattr(obj[0], "_voSet")
863-
and obj[0]._voSet
864-
):
865-
# For lists of Potentials
866-
vo = obj[0]._vo
867851
if _APY_LOADED and isinstance(vo, units.Quantity):
868852
vo = vo.to(units.km / units.s).value
869853
return (
@@ -1075,18 +1059,12 @@ def wrapper(*args, **kwargs):
10751059
ro = kwargs.get("ro", None)
10761060
if ro is None and hasattr(Pot, "_ro"):
10771061
ro = Pot._ro
1078-
if ro is None and isinstance(Pot, list) and hasattr(Pot[0], "_ro"):
1079-
# For lists of Potentials
1080-
ro = Pot[0]._ro
10811062
if _APY_LOADED and isinstance(ro, units.Quantity):
10821063
ro = ro.to(units.kpc).value
10831064
if "t" in kwargs or "M" in kwargs:
10841065
vo = kwargs.get("vo", None)
10851066
if vo is None and hasattr(Pot, "_vo"):
10861067
vo = Pot._vo
1087-
if vo is None and isinstance(Pot, list) and hasattr(Pot[0], "_vo"):
1088-
# For lists of Potentials
1089-
vo = Pot[0]._vo
10901068
if _APY_LOADED and isinstance(vo, units.Quantity):
10911069
vo = vo.to(units.km / units.s).value
10921070
# Loop through args

tests/test_potential.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8171,6 +8171,34 @@ def test_CompositePotential_explicit_units():
81718171
return None
81728172

81738173

8174+
def test_planarCompositePotential_explicit_units():
8175+
# Test that explicit ro/vo initialization works correctly
8176+
from galpy.potential import LogarithmicHaloPotential, planarCompositePotential
8177+
8178+
pot1 = LogarithmicHaloPotential(normalize=0.5).toPlanar()
8179+
pot2 = LogarithmicHaloPotential(normalize=0.5).toPlanar()
8180+
8181+
# Create CompositePotential with explicit ro and vo
8182+
comp = planarCompositePotential(pot1, pot2, ro=8.5, vo=220.0)
8183+
# Check that ro and vo are set correctly
8184+
assert comp._ro == 8.5, "Explicit ro not set correctly"
8185+
assert comp._vo == 220.0, "Explicit vo not set correctly"
8186+
assert comp._roSet, "roSet should be True when ro is explicitly provided"
8187+
assert comp._voSet, "voSet should be True when vo is explicitly provided"
8188+
8189+
# Test with only ro set
8190+
comp_ro = planarCompositePotential(pot1, pot2, ro=9.0)
8191+
assert comp_ro._ro == 9.0, "Explicit ro not set correctly"
8192+
assert comp_ro._roSet, "roSet should be True when ro is explicitly provided"
8193+
8194+
# Test with only vo set
8195+
comp_vo = planarCompositePotential(pot1, pot2, vo=230.0)
8196+
assert comp_vo._vo == 230.0, "Explicit vo not set correctly"
8197+
assert comp_vo._voSet, "voSet should be True when vo is explicitly provided"
8198+
8199+
return None
8200+
8201+
81748202
def test_CompositePotential_setitem_error():
81758203
# Test that __setitem__ raises TypeError for non-Potential values
81768204
from galpy.potential import CompositePotential, LogarithmicHaloPotential
@@ -8563,8 +8591,10 @@ def test_planarCompositePotential_from_addition():
85638591
# Create planar potentials
85648592
pot1 = MiyamotoNagaiPotential(normalize=0.6)
85658593
pot2 = LogarithmicHaloPotential(normalize=0.4)
8594+
pot3 = LogarithmicHaloPotential(normalize=0.2)
85668595
planar1 = toPlanarPotential(pot1)
85678596
planar2 = toPlanarPotential(pot2)
8597+
planar3 = toPlanarPotential(pot3)
85688598

85698599
# Add them together
85708600
combined = planar1 + planar2
@@ -8582,6 +8612,51 @@ def test_planarCompositePotential_from_addition():
85828612
"planarCompositePotential from addition evaluates incorrectly"
85838613
)
85848614

8615+
# Some further testing copied from CompositePotential
8616+
# Test adding individual to planarCompositePotential
8617+
comp12 = planar1 + planar2
8618+
comp123 = comp12 + planar3
8619+
assert len(comp123) == 3
8620+
assert comp123[0] == planar1
8621+
assert comp123[1] == planar2
8622+
assert comp123[2] == planar3
8623+
8624+
# Test adding planarCompositePotential to individual
8625+
comp23 = planar2 + planar3
8626+
comp123_2 = planar1 + comp23
8627+
assert len(comp123_2) == 3
8628+
assert comp123_2[0] == planar1
8629+
8630+
# Test adding two planarCompositePotentials
8631+
comp12 = planar1 + planar2
8632+
comp3 = planar3 + planar3
8633+
comp_all = comp12 + comp3
8634+
assert len(comp_all) == 4
8635+
return None
8636+
8637+
8638+
def test_planarCompositePotential_add_error():
8639+
# Test that __add__ raises TypeError for incompatible types
8640+
from galpy.potential import LogarithmicHaloPotential, planarCompositePotential
8641+
8642+
pot1 = LogarithmicHaloPotential(normalize=0.5).toPlanar()
8643+
pot2 = LogarithmicHaloPotential(normalize=0.5).toPlanar()
8644+
comp = planarCompositePotential(pot1, pot2)
8645+
8646+
# Try to add a string
8647+
try:
8648+
result = comp + "not a potential"
8649+
assert False, "Should have raised TypeError"
8650+
except TypeError as e:
8651+
assert "Can only add planarPotential" in str(e)
8652+
8653+
# Try to add a number
8654+
try:
8655+
result = comp + 42
8656+
assert False, "Should have raised TypeError"
8657+
except TypeError as e:
8658+
assert "Can only add planarPotential" in str(e)
8659+
85858660
return None
85868661

85878662

0 commit comments

Comments
 (0)