如何在Python中使用fastjet-contrib的EnergyCorrelator与Nsubjettiness
解决PyROOT中fastjet-contrib模块调用问题
核心问题分析
你遇到的问题主要有两个:一是pip安装的fastjet包通常未包含fastjet-contrib的Python绑定;二是代码中对contrib模块的调用方式、喷流处理逻辑存在错误。
步骤1:确认fastjet-contrib Python绑定是否存在
pip默认安装的fastjet仅包含核心库绑定,fastjet-contrib的Python绑定需要单独编译或源码安装。你看到的.hh头文件是C++头文件,并非Python可直接调用的绑定模块。
手动编译fastjet-contrib绑定(Linux环境)
- 安装依赖:确保系统有
cmake、python-dev、fastjet核心库(可通过apt install fastjet-dev等系统包管理器安装)。 - 下载并编译源码:
git clone https://github.com/fastjet/fastjet-contrib.git cd fastjet-contrib mkdir build && cd build cmake .. -DPYTHON_EXECUTABLE=$(which python) -DBUILD_PYTHON_BINDINGS=ON make -j4 make install - 验证绑定:在Python中执行
import fastjet.contrib,无报错则说明绑定成功。
步骤2:修正代码中的调用逻辑
你的代码存在两个关键错误:直接将粒子列表传给Nsubjettiness/ECF(它们需要单个喷流对象),以及ECF的模块引用错误。以下是修正后的完整代码:
import fastjet import math def to_pseudojets(constits): return [fastjet.PseudoJet( c.pt * math.cos(c.phi), c.pt * math.sin(c.phi), c.pt * math.sinh(c.eta), c.pt * math.cosh(c.eta) ) for c in constits] def compute_nsubjettiness(jet, beta=1.0): # 参数为单个喷流对象,而非粒子列表 axis_def = fastjet.contrib.KT_Axes() measure_def = fastjet.contrib.UnnormalizedMeasure(beta) tau1 = fastjet.contrib.Nsubjettiness(1, axis_def, measure_def)(jet) tau2 = fastjet.contrib.Nsubjettiness(2, axis_def, measure_def)(jet) tau3 = fastjet.contrib.Nsubjettiness(3, axis_def, measure_def)(jet) return tau1, tau2, tau3 def compute_ecfs(jet, beta=1.0): # ECF属于fastjet.contrib模块,而非fjcontrib ecf2 = fastjet.contrib.ECF(2, beta) ecf3 = fastjet.contrib.ECF(3, beta) e2 = ecf2(jet) e3 = ecf3(jet) return e2, e3 def compute_c2_d2(e2, e3): c2 = e3 / (e2**2) if e2 > 0 else -1 d2 = e3 / (e2**3) if e2 > 0 else -1 return c2, d2 class ConstituentData: """存储粒子运动学信息,用于转换为fastjet伪喷流""" def __init__(self, pt, eta, phi, m=0.0): self.pt = pt self.eta = eta self.phi = phi self.m = m # 示例使用:从ROOT文件读取粒子后聚类喷流,再计算特征 if __name__ == "__main__": # 模拟从ROOT读取的粒子数据 constits = [ConstituentData(50, 0.1, 0.2), ConstituentData(30, -0.3, 0.5), ConstituentData(20, 0.2, -0.1)] pseudojets = to_pseudojets(constits) # 用anti-kt算法聚类喷流(R=1.0) jet_def = fastjet.JetDefinition(fastjet.antikt_algorithm, 1.0) cluster_seq = fastjet.ClusterSequence(pseudojets, jet_def) jets = cluster_seq.inclusive_jets(pt_min=20) # 筛选pt>20的喷流 # 对每个喷流计算特征 for jet in jets: tau1, tau2, tau3 = compute_nsubjettiness(jet) e2, e3 = compute_ecfs(jet) c2, d2 = compute_c2_d2(e2, e3) print(f"喷流pt: {jet.pt()}, eta: {jet.eta()}") print(f"tau1: {tau1}, tau2: {tau2}, tau3: {tau3}") print(f"ECF2: {e2}, ECF3: {e3}, C2: {c2}, D2: {d2}\n")
关键修正点说明
- 喷流聚类:必须先通过
ClusterSequence将粒子聚类为喷流对象,Nsubjettiness和ECF都是针对单个喷流计算的,不能直接传入粒子列表。 - 模块引用:所有fastjet-contrib工具都在
fastjet.contrib命名空间下,不存在fjcontrib模块。 - 参数传递:Nsubjettiness构造后调用时,传入的是单个
PseudoJet喷流对象,而非粒子列表。
内容的提问来源于stack exchange,提问作者A.M.M Elsayed
相关产品推荐
相关产品推荐

