-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected behavior with np.nan
only initialized vectors
#138
Comments
The "zero vs nan" decisions are determined in part by coordinate system—if you're in cylindrical coordinates, for example, a nan in Since you're in Cartesian coordinates, the relevant calculator for pseudorapidity is vector/src/vector/_compute/spatial/eta.py Lines 30 to 31 in e39ddb1
and yes, that deliberately replaces nan with zero. Looking again at ROOT's implementation, ours is not quite right, since they would have an all-nan vector return nan. ROOT either calculates it from or from What we were trying to avoid with the >>> ROOT.Math.XYZVector(0, 0, 0).Eta()
0.0
>>> ROOT.Math.PxPyPzEVector(0, 0, 0, 0).Eta()
0.0 Let's explore this more: >>> ROOT.Math.XYZVector(0, 0, np.nan).Eta()
nan
>>> ROOT.Math.XYZVector(0, np.nan, 0).Eta()
0.0
>>> ROOT.Math.XYZVector(np.nan, 0, 0).Eta()
0.0
>>> ROOT.Math.PxPyPzEVector(0, 0, 0, np.nan).Eta()
0.0
>>> ROOT.Math.PxPyPzEVector(0, 0, np.nan, 0).Eta()
nan
>>> ROOT.Math.PxPyPzEVector(0, np.nan, 0, 0).Eta()
0.0
>>> ROOT.Math.PxPyPzEVector(np.nan, 0, 0, 0).Eta()
0.0 Only a nan in the We have an additional constraint that our formulas need to be pure expressions (i.e. no "if" statements) since they need to be vectorizable in all current and future backends. I suppose we could get the " vector/src/vector/_compute/spatial/eta.py Lines 30 to 31 in e39ddb1
by >>> z = 0; np.absolute(np.sign(z))
0
>>> z = 1e-16; np.absolute(np.sign(z))
1.0
>>> z = -1e-16; np.absolute(np.sign(z))
1.0
>>> z = 1e16; np.absolute(np.sign(z))
1.0
>>> z = -1e16; np.absolute(np.sign(z))
1.0
>>> z = np.nan; np.absolute(np.sign(z))
nan
>>> z = np.inf; np.absolute(np.sign(z))
1.0
>>> z = -np.inf; np.absolute(np.sign(z))
1.0 There might be other cases where this is needed; we'd need to do a general survey. I think that's what #36 is. |
Thank you very much for the detailed and fast answer. According to #36, you always compare with ROOT. In my first intention, this was not even the point, since it makes no sense to calculate anything at all from a vector that only contains The solution with the usage of |
I am currently working with this package in combination with pandas on an assignment for study exercises in particle physics and have encountered an unexpected behavior. For a homogenized structure of my data I use
np.nan
to fill some missing values (particles). Consequently, it often comes to a situation where an initialization of a vector obj/array/... withnp.nan
occurs. This works perfectly fine, especially the property query, except forpseudorapidity
,rapidity
and other related quantities.A small example:
My expectation would be that, in this case, any quantity of an object that is initialized with (only)
np.nan
should also return anp.nan
and not an actual number.Is this behavior, especially for a case described above, intended?
P.S.: I know that via
vector.awk
there is a possibility to work with inhomogeneous data structures, but in our workgroup we decided against that and for an approach using pandas.The text was updated successfully, but these errors were encountered: