Problem initializing a 4-vector

Hello,
I am working with root 6.24/06 on lxplus in eventloop.
I declare a 4 vector and initialize it:

ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double>> myVector;
...
myVector = cluster->p4(xAOD::CaloCluster_v1::State::UNCALIBRATED);

This returns a confusing error to me:

/cvmfs/atlas.cern.ch/repo/sw/software/21.2/AnalysisBaseExternals/21.2.186/InstallArea/x86_64-centos7-gcc8-opt/include/Math/GenVector/LorentzVector.h: In instantiation of 'ROOT::Math::LorentzVector<CoordSystem>& ROOT::Math::LorentzVector<CoordSystem>::operator=(const ForeignLorentzVector&) [with ForeignLorentzVector = TLorentzVector; CoordSystem = ROOT::Math::PtEtaPhiM4D<double>]':
/afs/cern.ch/work/a/abunka/private/dijetStudies/source/dijetVariables/Root/variableAnalysis.cxx:1089:94:   required from here
/cvmfs/atlas.cern.ch/repo/sw/software/21.2/AnalysisBaseExternals/21.2.186/InstallArea/x86_64-centos7-gcc8-opt/include/Math/GenVector/LorentzVector.h:137:22: error: 'const class TLorentzVector' has no member named 'x'
           SetXYZT( v.x(), v.y(), v.z(), v.t() );
                    ~~^

The “no member named” part is repeated for the y, z, t…
As far as I can tell, my vector is being treated as a TLorentzVector, which then does not have the ability to be initialized to the cluster p4() I am using? But I am really not sure. I do know that when I tried working with TLorentzVectors I had many issues, so i switched to the newer ROOT::Math::LorentzVector. So I am surprised to see TLorentzVector appear in the error.

Thanks!

Hi @abunka,

you see the TLorentzVector, because cluster->p4 it’s the type that cluster->p4() returns, as you can see in this xAOD documentation for example:
https://ucatlas.github.io/RootCoreDocumentation/2.4.28/dd/d91/classxAOD_1_1CaloCluster__v1.html#a4ee752abfcacde56b2a0ac06667a8e9e

The new ROOT::Math::LorentzVector doesn’t support direct assignment from TLorenzVector, but you can do it in two steps:

ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double>> myVector;
{
   TLorentzVector const& v = cluster->p4(xAOD::CaloCluster_v1::State::UNCALIBRATED);
   myVector.SetXYZT( v.X(), v.Y(), v.Z(), v.T() );
}

Maybe if this is a pattern that will happen more often in your code, you should write a little helper function to do this.

Hope that helps and thanks for asking the question!

@Axel I really expect that it is the ROOT Team responsibility to provide the corresponding assignment operators (between a TLorentzVector and a ROOT::Math::LorentzVector). Plenty of the existing source code uses the “old” class and it’s a pain to switch to the new one in new macros (which use “old” libraries).

1 Like

Agreed, see [genvector] Add construction from C-style array: by Axel-Naumann · Pull Request #11053 · root-project/root · GitHub

(I prefer not to ease the transition in the “wrong” direction.)

Not sure what you mean by the “wrong” direction.

I think it should work both ways.
Assume you have an “old” library (which knows the “old” classes only), and you need to pass your “new” object to it and then retrieve some “old” result (which you then want to process in the “new” way).

It’s always possible, and I prefer a slightly adiabatic ease of conversion :slight_smile: