Finding x, y of the 2D histogram in pyROOT

I have a 2D histogram, and I want to find its minimum x and y positions in pyROOT.

Several posts on the forum discussed how to do that in pyROOT.
For example:

The posts I found are quite old, from 2008 and 2016.
I am trying this solution in ROOT 6.30/04, which does not work.
It also does not work also in 6.26 and 6.28

h = ROOT.TH2F("h", "t", 10, -10, 10, 10, -10, 10)
print(h.GetMinimumBin()) # 13
x, y, z = ROOT.long(0), ROOT.long(0), ROOT.long(0) # using Long does not work.
h.GetBinXYZ(13, x, y, z)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: void TH1::GetBinXYZ(int binglobal, int& binx, int& biny, int& binz) =>
    TypeError: could not convert argument 2 (use ctypes.c_int for pass-by-ref of ints)

What am I doing wrong, and how can I find the minimum x and y of a 2D histogram?

Hello, @FoxWise

It seems like you’re encountering a type error because ROOT.long is not the correct type for pass-by-reference in PyROOT. Instead, you should use ctypes.c_int to define your variables for storing the coordinates. Here’s how you can modify your code to find the minimum x and y positions of a 2D histogram in PyROOT:

import ctypes

Create a 2D histogram

h = ROOT.TH2F(“h”, “t”, 10, -10, 10, 10, -10, 10)

Find the bin with the minimum value

min_bin = h.GetMinimumBin()

Define variables to store the x, y, and z coordinates

x, y, z = ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0)

Get the x, y, and z coordinates of the minimum bin

h.GetBinXYZ(min_bin, ctypes.byref(x), ctypes.byref(y), ctypes.byref(z))

Print the x and y coordinates

print(f"The minimum x and y positions are: {x.value}, {y.value}")

This code uses ctypes.byref() to pass the integers by reference, which should resolve the type error you were experiencing. The x.value and y.value will give you the minimum x and y positions in the histogram. Remember to import ctypes at the beginning of your script.

Best Regard,
Ryan1969

Dear @ryan1969,

I have tried your solution, and it does not work, resulting in the same error.
Does this work for you? If so, with which environment?

Python 3.9.12 (main, Jun 10 2022, 16:28:01) 
[GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> import ctypes
>>> h = ROOT.TH2F("h", "t", 10, -10, 10, 10, -10, 10)
>>> min_bin = h.GetMinimumBin()
>>> x, y, z = ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0)
>>> h.GetBinXYZ(min_bin, ctypes.byref(x), ctypes.byref(y), ctypes.byref(z))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: void TH1::GetBinXYZ(int binglobal, int& binx, int& biny, int& binz) =>
    TypeError: could not convert argument 2 (use ctypes.c_int for pass-by-ref of ints)
>>> ROOT.__version__
'6.30/04'
>>>

I also would like to highlight that your answer is generated with chatGPT or a similar tool, which is very obvious.
I don’t mind using these tools to get answers, but please check if the generated solution works at least.

I am also capable of using chatGPT, but it is a forum where I would like to get an answer from live people, and I am not sure if filling it with auto-generated content is a good thing.

Try

h.GetBinXYZ(min_bin, x, y, z)

(keeping the other ctypes line)

1 Like

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