使用mktree创建含char*类型分支的ROOT文件时遇Uproot类型识别问题
解决Uproot创建char*类型TTree分支的问题
可以实现创建char*类型的分支,你遇到的问题是因为NumPy字节字符串类型的使用方式有误,以及Uproot对字符串类型的声明需要匹配ROOT的存储逻辑,并非功能缺失。
具体实现方案
方案1:直接声明ROOT固定长度char数组类型
在创建TTree时,用ROOT原生的类型字符串指定分支,这是最贴合C++ char*逻辑的方式:
import uproot with uproot.recreate("output.root") as f: # 声明分支为char[256],对应C++中可存储最长255字符的char*(含终止符) f.mktree("tree", {"my_string": "char[256]"}) # 直接传入Python字符串列表,Uproot会自动转换为对应长度的字节串 data = {"my_string": ["hello", "world", "uproot string test"]} f["tree"].extend(data)
方案2:用Python对象类型存储字符串
如果要和Uproot读取时的AsStrings()方法兼容,可以用np.object_类型存储Python原生字符串:
import uproot import numpy as np with uproot.recreate("output.root") as f: # 用np.object_类型声明分支 f.mktree("tree", {"my_string": np.dtype("O")}) # 传入object类型的字符串数组 data = {"my_string": np.array(["foo", "bar", "baz"], dtype="O")} f["tree"].extend(data)
这种方式写入的分支,读取时调用tree["my_string"].AsStrings()可以正常解析为Python字符串列表。
你之前尝试失败的原因
np.dtype('string'):Uproot暂不支持NumPy的Unicode字符串类型(<U),因为ROOT的char*是字节存储,和Unicode字符串的编码逻辑不匹配。np.dtype('S'):未指定长度时默认生成|S0(空字节串类型),ROOT不接受长度为0的字符数组,必须指定具体长度(如np.dtype('S256')),但这种方式不如直接声明ROOT类型直观。
内容的提问来源于stack exchange,提问作者Jorge Caraça-Valente Barrera
相关产品推荐
相关产品推荐

