Проблемы при попытке открыть двумерный массив, содержащийся в дереве ROOT в Pyroot - PullRequest
0 голосов
/ 08 мая 2020

У меня возникла проблема с использованием Py root. Я не могу прочитать лист на дереве, который представляет собой двумерный массив значений с плавающей запятой. Вы можете увидеть соответствующее Дерево в следующем виде:

root [1] TTree tr=(TTree)g->Get(“tevent_2nd_integral”)
root [2] tr.Print()
*Tree :tevent_2nd_integral: Event packet tree 2nd GTUs integral *
*Entries : 57344 : Total = 548967602 bytes File Size = 412690067 *

:          : Tree compression factor =   1.33                 *
*Br 7 :photon_count_data : photon_count_data[1][1][48][48]/F *
*Entries : 57344 : Total Size= 530758073 bytes File Size = 411860735 *
*Baskets : 19121 : Basket Size= 32000 bytes Compression= 1.29 *
…

Массив (выделенный жирным шрифтом) - это photon_count_data [1] [1] [48] [48]. На самом деле у меня есть несколько файлов root, и я попытался как составить цепочку, так и использовать метод hadd, например файл hadd. root 'ls /path/.root'.* Я пробовал несколько способов, как я скоро покажу. Каждый раз, когда я обнаруживал другую проблему: как только массив numpy, который должен содержать значения 48x48 для каждого события, вообще не создавался, другие просто не записывали ничего или странные значения (отрицательные, что также невозможно). Мой код следующий:

# calling the root file after using hadd to merge all files
rootFile = path+"merge.root"
f = XROOT.TFile(rootFile,'read')
tree = f.Get('tevent_2nd_integral')

# making a chain
PDMchain=TChain("tevent_2nd_integral")
for filename in sorted(os.listdir(path)):
    if filename.endswith('.root') and("CPU_RUN_MAIN"  in filename) :
        PDMchain.Add(filename)

pdm_counts = []
#First method using python pyl class
leaves = tree.GetListOfLeaves()
# define dynamically a python class containing root Leaves objects
class PyListOfLeaves(dict) :
    pass

# create an istance
pyl = PyListOfLeaves()

for i in range(0,leaves.GetEntries() ) :
    leaf = leaves.At(i)
    name = leaf.GetName()
    # add dynamically attribute to my class 
    pyl.__setattr__(name,leaf)

for iev in range(0,nEntries_pixel) :
    tree.GetEntry(iev) 
    pdm_counts.append(pyl.photon_count_data.GetValue())

# the Draw method
count = tree.Draw("photon_count_data","","")
pdm_counts.append(np.array(np.frombuffer(tree.GetV1(), dtype=np.float64, count=count)))

#ROOT buffer method
for event in PDMchain:
    pdm_data_for_this_event = event.photon_count_data
    pdm_data_for_this_event.SetSize(2304)  #ROOT buffer
    pdm_couts.append(np.array(pdm_data_for_this_event,copy=True))
  1. с помощью метода класса python массив pdm_counts заполняется только первым элементом, содержащимся в photon_count_data
  2. с помощью метода Draw, который я получаю нарушение сегментации или странная проблема ядра
  3. с помощью буферного метода root Я получаю обратно список, содержащий все значения 2304 (48x48), но они полностью отличаются от значений в photon_count_data, т.е. отрицательное значения или порядки величины бессмысленны

Не могли бы вы сказать мне, где я ошибаюсь, или может быть более элегантный и быстрый способ сделать это. Заранее спасибо

1 Ответ

0 голосов
/ 04 июня 2020

На самом деле я нашел решение и хотел бы поделиться им, если оно кому-то понадобится! На самом деле третий объясненный метод

for event in PDMchain:
    pdm_data_for_this_event = event.photon_count_data
    pdm_data_for_this_event.SetSize(2304)  #ROOT buffer
    pdm_couts.append(np.array(pdm_data_for_this_event,copy=True))

работает, но, к сожалению, я использовал Spyder для визуализации данных и по какой-то причине он возвращал странные значения, которые не верны! Итак ... не используйте Spyder !!! Кроме того, отлично работает другой метод:

from root_pandas import read_root
data = read_root('merge.root', 'tevent_2nd_integral', columns=['cpu_packet_time', 'photon_count_data'])

Ура!

...