Repository navigation
Make getB more batchable #883
Description
Activity
HEy @purepani
Thanks for pointing this out. We were too lazy - the original idea was that the users could do the reshaping - ofc. boadcasting i your example offers memory advantages. When moving to more array efficiency we should certainly consider this.
But also I am currently quite unhappy with the structure of
getB. I think it the functional part should be separated from the oo one completely for obvious reasons (terrible docstrings, overloding confuses, ...). Maybe something using classmethodsmagpy.magnet.Cuboid.getB( obs_array, pos_array, mag_array, )
instead of
getB("Cuboid", ....)what do you think ? I'm also discussing this with myself in #704 :)
You can maybe get away with the current interface by adding typing overloads
Something likefrom typing import overload, Literal @overload def getB(magnet: Literal["Cuboid"], ...): ... # cuboid parameters. #other typing overloads for getB #actual implementation def getB(magnet: Literal["Cuboid"] | Literal["Sphere"], ...): #actual implementation
This will definitely help with ide support. I have no clue how well docstrings work with this though.
Otherwise I think the
getB_cuboidis simple and easy to implement, and use.What you are suggesting is an improvement from a developer point of view - makes sense.
What do you mean by
getB_cuboid? You think the way its currently done is fine from a user perspective, or you think a function 'getB_cuboid()',getB_sphere()... would be nice to have (top level?) functions for the functional interface ?I think that
getB_cuboidworks sufficiently well for a top level interface. This feels like one of the situations where the simple answer is better.Alternatively, you could have something like
getCuboid(field="B",...), orgetCuboid(...).getB()but I think that's trying to be too clever here. I can't think of a usability reason that makes this any more usable on the user end compared togetB_Cuboid(...), and I don't think there's really an advantage in terms of simplicity either for trying to combine them in a unified interface.Maybe it would be useful to think of a Protocol that could declare what the interface for these getB functions look like, since they are pretty similar, but it seems a bit unnecessary to me. I can't think of any concrete use cases for it.
There's also maybe a way to do this with typing generics but again, I feel like it's maybe trying to be too smart.
Keeping it simple is the right way to go, but this would also mean that we would have a ton of top level functions ...
getB_xxx(),getH_xxx(),getJ_xxx(), andgetM_xxx()for xxx in all Magpylib classesThis is why I thought to use classmethods to give the context of the respective class rather than adding about 50 top level functions.
I personally prefer flat structures particularly for functional programming(it's part of the zen of python as well).
I'm also a bit worried about users getting confused with class methods, and maybe mixing them up with the magnet classes; and if you want to put them in the normal magnet classes, then there's no namespace separation between the 2.
I think in an ideal world, the code I would want to write looks like this:getB["Cuboid"](...)
With IDE support/auto complete when specifying the generic. Since the situation we currently have is quite similar to this, personally, I think we can try to fix the typing situation on the current
getXfunctions and see if we can make the docgen and ide support better with that, rather than trying to change the interface.- added a commit that references this issue
on Aug 4, 2026
Currently, it seems that
magpy.getBis pretty restricted in how it can work with shapes. Based on the documentation, it can essentially only work with one extra dimension. It would be useful to be able to work with any number of extra dimensions. That way, you can easily calculate a ton of field values at once with broadcasting.For example, the following is currently not possible, but should be:
I am guessing that the reason is due to the fact that the same limitation applies to
scipy.spacial.transform.Rotationclass, but this should be able to be worked around with reshaping before and after rotation.