Skip to content

Commit d12c8dc

Browse files
committed
[PWGEM] PhotonMeson: Fix bug in EMNonLin
- Fixed a bug where for higher iterations of the NonLin correction the input for iteration i was not the input value * scale_(i-1) but the unscaled input value - Changed the formluar of the NonLin from (1 + par0/x + par1/x^2) / (1 + par2/x) to (x + par0 +par1/x) / (x + par2) which is mathmatecially the same, however, it is a lot more stable since there is no 1/x^2 anymore. - Optimized the `setParams` calling inside `nonLinProducer.cxx` where it now should only be called if the collision and hence the centrality changes. Before this it was called for each photon!
1 parent 8de42cc commit d12c8dc

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

PWGEM/PhotonMeson/Core/EMNonLin.cxx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,27 @@ float EMNonLin::getCorrectionFactor(float x, const Context& ctx)
2525
return x;
2626
}
2727

28-
float val = x;
29-
// safety measure
3028
int maxIter = std::min(ctx.nIter, MaxIter - 1);
3129

30+
float scale = 1.f; // cumulative scale
31+
float refVal = x; // reference value for computing next scale
32+
3233
for (int i = 0; i <= maxIter; ++i) {
33-
if (val == 0.f) {
34+
if (refVal == 0.f) {
3435
break;
3536
}
3637

37-
float inv = 1.f / val;
38-
val *= (1.f + ctx.params[i].par0 * inv +
39-
ctx.params[i].par1 * inv * inv) /
40-
(1.f + ctx.params[i].par2 * inv);
41-
}
38+
const auto& p = ctx.params[i];
4239

43-
return val;
40+
// scale function (x + a + b/x)/(x + c) which goes towards 1 for large x since x >> a,b,c -> x/x = 1
41+
float iterScale =
42+
(refVal + p.par0 + p.par1 / refVal) /
43+
(refVal + p.par2);
44+
45+
scale *= iterScale; // total scale = product over itertaion scale
46+
refVal = x * scale; // next iteration uses scaled original input
47+
}
48+
return scale;
4449
}
4550

4651
const EMNonLin::NonLinParams* EMNonLin::resolveParams(PhotonType type, float cent)

PWGEM/PhotonMeson/TableProducer/nonLinProducer.cxx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,32 +109,30 @@ struct NonLinProducer {
109109
template <o2::soa::is_table TClusters, o2::soa::is_iterator TCollisio>
110110
void runEMC(TClusters const& clusters, TCollisio& collision)
111111
{
112-
float cent = getCentrality(collision);
113112

114113
int32_t collIndex = collision.globalIndex();
114+
float cent = getCentrality(collision);
115+
emNonLinContextEMC.setParams(emNonLinEMC.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kEMC, cent));
116+
115117
for (const auto& cluster : clusters) {
116-
float nonLinE = 0.f;
117-
float nonLinPt = 0.f;
118-
float nonLinFactor = 1.f;
119118

120119
// check that we are at the correct collision
121120
if (cluster.emphotoneventId() != collIndex) {
122121
collIndex = cluster.emphotoneventId();
123122
collision.setCursor(collIndex);
124123
cent = getCentrality(collision);
124+
emNonLinContextEMC.setParams(emNonLinEMC.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kEMC, cent));
125125
}
126126

127-
emNonLinContextEMC.setParams(emNonLinEMC.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kEMC, cent));
128-
129127
// fill before non lin histograms
130128
historeg.fill(HIST("QA/EMC/EIn"), cluster.e());
131129
historeg.fill(HIST("QA/EMC/PtIn"), cluster.pt());
132130

133131
// get NonLin factor from class dependent on the centrality
134-
nonLinFactor = emNonLinEMC.getCorrectionFactor(cluster.e(), emNonLinContextEMC);
132+
float nonLinFactor = emNonLinEMC.getCorrectionFactor(cluster.e(), emNonLinContextEMC);
135133

136-
nonLinE = nonLinFactor * cluster.e();
137-
nonLinPt = nonLinFactor * cluster.pt();
134+
float nonLinE = nonLinFactor * cluster.e();
135+
float nonLinPt = nonLinFactor * cluster.pt();
138136

139137
// fill after non lin histograms
140138
historeg.fill(HIST("QA/EMC/EOut"), nonLinE);
@@ -147,29 +145,27 @@ struct NonLinProducer {
147145
template <o2::soa::is_table TV0, o2::soa::is_iterator TCollisio>
148146
void runPCM(TV0 const& v0s, TCollisio& collision)
149147
{
150-
float cent = getCentrality(collision);
151148

152149
int32_t collIndex = collision.globalIndex();
150+
float cent = getCentrality(collision);
151+
emNonLinContextPCM.setParams(emNonLinPCM.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kPCM, cent));
153152
for (const auto& v0 : v0s) {
154-
float nonLinPt = 0.f;
155-
float nonLinFactor = 1.f;
156153

157154
// check that we are at the correct collision
158155
if (v0.emphotoneventId() != collIndex) {
159156
collIndex = v0.emphotoneventId();
160157
collision.setCursor(collIndex);
161158
cent = getCentrality(collision);
159+
emNonLinContextPCM.setParams(emNonLinPCM.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kPCM, cent));
162160
}
163161

164-
emNonLinContextPCM.setParams(emNonLinPCM.resolveParams(o2::pwgem::nonlin::EMNonLin::PhotonType::kPCM, cent));
165-
166162
// fill before non lin histograms
167163
historeg.fill(HIST("QA/PCM/PtIn"), v0.pt());
168164

169165
// get NonLin factor from class dependent on the centrality
170-
nonLinFactor = emNonLinEMC.getCorrectionFactor(v0.pt(), emNonLinContextPCM);
166+
float nonLinFactor = emNonLinEMC.getCorrectionFactor(v0.pt(), emNonLinContextPCM);
171167

172-
nonLinPt = nonLinFactor * v0.pt();
168+
float nonLinPt = nonLinFactor * v0.pt();
173169

174170
// fill after non lin histograms
175171
historeg.fill(HIST("QA/PCM/PtOut"), nonLinPt);

0 commit comments

Comments
 (0)