[] and () operators for ROOT::Math::XYZVector

Hi all,

I’m working on Belle II, and in our code base we have used TVector3 so far. But we are in the process of exchanging TVector3 by ROOT::Math::XYZVector. For ease of use, in several instances there are loops over the TVector3, like

TVector3 a, b; // with some content of course, just to demonstrate
TMatrix matrix;
for (int i = 0; i < 3; i++)
  for (int j = 0; j < 3; j++)
    matrix(i, j) = a[i] * b[j]; // or similar, like + or - or whatever

which is not possible anymore if a and b are changed to XYZVector, as both the [] and () operators are not present in the class. I’m wondering about the reason not to include these operators, and whether it’s possible to add them.
It’s a lot of work to change all the loops to manually fill matrices (and all other instances where the TVector3 are accessed by index rather than x/y/z), and of course it’s also very error prone - just a typo, and the full track fitting or alignment doesn’t work anymore.

Thanks a lot!

ROOT Version: 6.24/06
Platform: Ubuntu 18.04(5.4.0-122-generic)
Compiler: Not Provided

Welcome to the ROOT forum.
Maybe @moneta can help you.

What you can do in this case is to transform the internal vector data in a C array using the method GetCoordinates:

ROOT::Math::XYZVector va,vb;
TMatrix matrix;
double a[3],b[3];
for (int i = 0; i < 3; i++)
  for (int j = 0; j < 3; j++)
    matrix(i, j) = a[i] * b[j];

Will this be enough or there is still too much code to change ?

Best regards

Hi Lorenzo,

thanks. I overlooked that solution. Although straight forward, I hoped to be able to solve this without an extra step like assigning the C-style arrays first, as we are running time critical reconstruction code and every instruction matters :wink:

Best regards,

@moneta , it would be helpful for Christian if the following functionality would exist in XYZVector:

double *a = va.GetCoordinates();

He then could implement:

ROOT::Math::XYZVector va,vb;
TMatrixD Ma; Ma.Use(3,1,va.GetCoordinates();
TMatrixD Mb; Mb.Use(1,3,vb.GetCoordinates();
TMatrixD matrix(Ma,TMatrixD::kMult,Mb);

which minimizes copying of information

Thank you Eddy for the suggestion. Unfortunately this is not possible because the 3 vector components aren’t stored in XYZVector in an array but as separate data member of the class.
If the allocations can be done outside the hot loop, normally copying 3 values should be fast, otherwise we need to think of a possible solution.


Hi Lorenzo,

Since these 3-vector components are private members and can only be accessed through getters and setters you can replace them with an array or make a union of them with an array of length 3:


     T fX;  // x coordinate
     T fY;  // y coordinate
     T fZ;  // z coordinate


    T v[3]; // v[0], x coordinate, v[1], y coordinate, z v[2]

or a union statement

   struct V {T fX; T fY; T fZ;}
   union vec {V v; T va[3];}

Hi ,
This is a possibility, but it might have some consequences for the I/O of the class and its backward compatibility. In addition, one needs to be sure performances are not affected.
It would be better to understand if this is really needed.
The previous code using operator[](int ) for TVector3 was certainly not optimal, given the presence of a switch statement for every call of the operator[].



@pcanal tells me automatic schema evolution works from three members of type double to a single double[3]! @moneta do you want to give it a go?

We would need to check first if this will be beneficial for the performances and we do not penalise other use cases of the vectors


…and turns out Philippe and I were talking past each other and one needs to do

#pragma read sourceClass="XYZVector" \
  targetClass="XYZVector" \
  source="double fX; double fY; double fZ;" \
  target="fX" \
  code="{ fX[0] = onfile.fX; fX[1] = onfile.fY; fX[2] = onfile.fZ; }"

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.