Skip to content

Commit f390389

Browse files
TPC: fix the weight scaling of the mixed spline derivative in addCorrections
TPCFastSpaceChargeCorrectionHelper::addCorrections scaled the 4th parameter of each spline knot (the mixed derivative d2S/dudv) with the square of the weight: secMainScale * secMainScale for the main correction, ls * ls * ... for the added ones (ls is the weight times the z fade-out factor, 1 at the knots). A spline is linear in its parameters, so scaling the correction by w scales all of them by w. The correction was therefore right at the knots but wrong between them whenever a weight != 1 was used, e.g. the derivative map added with weight lumiScale in TPCScalerSpec::buildMap. The error is proportional to w - w^2. Measured with a production map and the derivative map of run 568041 (random points, vs the weighted point-by-point sum of getCorrectionLocal and of the inverse getters), for map + 0.13 x derivative: rms ~20 um in dx and dz, ~10 um without the first 10 pad rows; deviations above 100 um are rare (0.4 % of the points) and lie mostly in the first pad rows. At a weight of -0.5 the rms is ~150 um (~60 um without the first 10 pad rows). With the fix the sum is exact to float precision (< 0.1 um) for weights from -1 to 1.5, inverse corrections included; w = 1 is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 1ddf4d9 commit f390389

1 file changed

Lines changed: 4 additions & 3 deletions

File tree

‎Detectors/TPC/calibration/src/TPCFastSpaceChargeCorrectionHelper.cxx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,8 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
10591059
constexpr int nKnotPar3d = nKnotPar1d * 3;
10601060

10611061
{ // scale the main correction
1062-
double parscale[4] = {secMainScale, secMainScale, secMainScale, secMainScale * secMainScale};
1062+
// a spline is linear in its parameters: scaling the function scales all of them, the mixed derivative included
1063+
double parscale[4] = {secMainScale, secMainScale, secMainScale, secMainScale};
10631064
for (int iknot = 0, ind = 0; iknot < spline.getNumberOfKnots(); iknot++) {
10641065
for (int ipar = 0; ipar < nKnotPar1d; ++ipar) {
10651066
for (int idim = 0; idim < 3; idim++, ind++) {
@@ -1116,7 +1117,7 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
11161117
float lu, lv, ls;
11171118
corr.convLocalToGrid(sector, row, y, z, lu, lv, ls);
11181119
ls *= scale;
1119-
double parscale[4] = {ls, ls * scaleU, ls * scaleV, ls * ls * scaleU * scaleV};
1120+
double parscale[4] = {ls, ls * scaleU, ls * scaleV, ls * scaleU * scaleV};
11201121
const auto& spl = corr.getSplineForRow(row);
11211122
spl.interpolateParametersAtU(corr.getCorrectionData(sector, row), lu, lv, P);
11221123
for (int ipar = 0, ind = 0; ipar < nKnotPar1d; ++ipar) {
@@ -1132,7 +1133,7 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
11321133
float lu, lv, ls;
11331134
corr.convRealLocalToGrid(sector, row, y, z, lu, lv, ls);
11341135
ls *= scale;
1135-
double parscale[4] = {ls, ls * scaleRealU, ls * scaleRealV, ls * ls * scaleRealU * scaleRealV};
1136+
double parscale[4] = {ls, ls * scaleRealU, ls * scaleRealV, ls * scaleRealU * scaleRealV};
11361137

11371138
{ // inverse X correction
11381139
corr.getSplineInvXforRow(row).interpolateParametersAtU(corr.getCorrectionDataInvX(sector, row), lu, lv, P);

0 commit comments

Comments
 (0)