Precision issue with PyROOT

Hello,

I am saving double precision values into a branch, but the saved value seems to have some precision issue. My test code is as

import sys
import ROOT
import numpy as np

tree = ROOT.TTree("tree", "tree")
con = {
    "a": np.array([0.], dtype=np.dtype("float64"))
}

tree.Branch("a", con["a"], "a/d")

test_values = np.arange(5927770000, 5927770010, 1)

for i in test_values:
    con["a"][0] = i
    tree.Fill()

print("Python version: %s, ROOT version: %s" % (sys.version, ROOT.gROOT.GetVersion()))
for i, t in enumerate(tree):
    print("True = %f   Stored = %f" % (test_values[i], t.a))

and this prints out the values as (ROOT 6.22/08 + Python 3.6.8 + NumPy 1.19.5)

Python version: 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)], ROOT version: 6.22/08
True = 5927770000.000000   Stored = 5927770112.000000
True = 5927770001.000000   Stored = 5927770112.000000
True = 5927770002.000000   Stored = 5927770112.000000
True = 5927770003.000000   Stored = 5927770112.000000
True = 5927770004.000000   Stored = 5927770112.000000
True = 5927770005.000000   Stored = 5927770112.000000
True = 5927770006.000000   Stored = 5927770112.000000
True = 5927770007.000000   Stored = 5927770112.000000
True = 5927770008.000000   Stored = 5927770112.000000
True = 5927770009.000000   Stored = 5927770112.000000

The saved values are somehow quantized by ~500. The output is the same with ROOT 6.24/06 + Python 3.6.8 + NumPy 1.19.5 and ROOT 6.24/06 + Python 2.7.5 + NumPy 1.7.1.

However, if I run the same code with ROOT 6.09/03 + Python 2.7.5 + NumPy 1.12.1, it gives the correct output as

Python version: 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)], ROOT version: 6.09/03
True = 5927770000.000000   Stored = 5927770000.000000
True = 5927770001.000000   Stored = 5927770001.000000
True = 5927770002.000000   Stored = 5927770002.000000
True = 5927770003.000000   Stored = 5927770003.000000
True = 5927770004.000000   Stored = 5927770004.000000
True = 5927770005.000000   Stored = 5927770005.000000
True = 5927770006.000000   Stored = 5927770006.000000
True = 5927770007.000000   Stored = 5927770007.000000
True = 5927770008.000000   Stored = 5927770008.000000
True = 5927770009.000000   Stored = 5927770009.000000

So I tried the same thing without PyROOT as

void test_root (void) {
        double test_value = 5927770007;

        TTree *tree = new TTree("tree", "tree");
        tree->Branch("a", &test_value, "a/D");
        tree->Fill();

        double get_value = 0.;
        tree->SetBranchAddress("a", &get_value);
        tree->GetEntry(0);

        cout << fixed << "True = " << test_value << "  Stored = " << get_value << endl;
}

and I got a correct value as

   ------------------------------------------------------------------
  | Welcome to ROOT 6.24/06                        https://root.cern |
  | (c) 1995-2021, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for linuxx8664gcc on Sep 02 2021, 14:20:23                 |
  | From tags/v6-24-06@v6-24-06                                      |
  | With c++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)                 |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'       |
   ------------------------------------------------------------------

root [0]
Processing test_root.C...
True = 5927770007.000000  Stored = 5927770007.000000

I am wondering if anyone has experienced this, or simply I am doing something wrong. It would be very appreciated if anyone can help me.

tree.Branch("a", con["a"], "a/D")

Thank you very much! I made really stupid mistake!

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