Skip to content

Commit cdbce61

Browse files
TPC: fix the chain-rule grid factors in addCorrections
A correction added on a different spline grid is sampled at the main grid's knots, and its derivatives must be converted with the chain rule: with u = (y - y0) * yScale, d/du_main = (yScale_corr / yScale_main) d/du_corr, the same for v. addCorrections used the inverse ratios, and applied the u factor to the dS/dv parameter and the v factor to dS/du (knot parameters {S, dS/dv, dS/du, d2S/dudv}). For identical grids (e.g. the derivative map) the factors are 1 and nothing changes. The M-shape map is created on a 4 x 4 grid in TPCScalerSpec, with factors of 35-98 with respect to a production map: adding the M-shape map of run 544797 (up to 6 mm) to a map of run 568041 gave errors of up to 89 cm in dx and up to the kMaxCorrection limit of 100 cm in dy (rms 4 cm and 7 cm), vs the point-by-point sum. With the fix: rms 1-2 um, max 60 um (resampling of non-nested grids) inside the main map's grid. Outside of it (|z| > ~1.37 x for production voxel maps) the merged map follows the edge and z fade-out of the main grid, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f390389 commit cdbce61

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,10 +1098,11 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
10981098

10991099
auto& linfo = corr.getRowInfo(row);
11001100

1101-
double scaleU = rowInfo.gridMeasured.getYscale() / linfo.gridMeasured.getYscale();
1102-
double scaleV = rowInfo.gridMeasured.getZscale() / linfo.gridMeasured.getZscale();
1103-
double scaleRealU = rowInfo.gridReal.getYscale() / linfo.gridReal.getYscale();
1104-
double scaleRealV = rowInfo.gridReal.getZscale() / linfo.gridReal.getZscale();
1101+
// chain rule for the derivatives: u = (y - y0) * yScale, v = (z - z0) * zScale => d/du_main = (du_corr / du_main) d/du_corr
1102+
double scaleU = linfo.gridMeasured.getYscale() / rowInfo.gridMeasured.getYscale();
1103+
double scaleV = linfo.gridMeasured.getZscale() / rowInfo.gridMeasured.getZscale();
1104+
double scaleRealU = linfo.gridReal.getYscale() / rowInfo.gridReal.getYscale();
1105+
double scaleRealV = linfo.gridReal.getZscale() / rowInfo.gridReal.getZscale();
11051106

11061107
for (int iu = 0; iu < gridU.getNumberOfKnots(); iu++) {
11071108
double u = gridU.getKnot(iu).u;
@@ -1117,7 +1118,8 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
11171118
float lu, lv, ls;
11181119
corr.convLocalToGrid(sector, row, y, z, lu, lv, ls);
11191120
ls *= scale;
1120-
double parscale[4] = {ls, ls * scaleU, ls * scaleV, ls * scaleU * scaleV};
1121+
// knot parameters: {S, dS/dv, dS/du, d2S/dudv}
1122+
double parscale[4] = {ls, ls * scaleV, ls * scaleU, ls * scaleU * scaleV};
11211123
const auto& spl = corr.getSplineForRow(row);
11221124
spl.interpolateParametersAtU(corr.getCorrectionData(sector, row), lu, lv, P);
11231125
for (int ipar = 0, ind = 0; ipar < nKnotPar1d; ++ipar) {
@@ -1133,7 +1135,7 @@ void TPCFastSpaceChargeCorrectionHelper::addCorrections(
11331135
float lu, lv, ls;
11341136
corr.convRealLocalToGrid(sector, row, y, z, lu, lv, ls);
11351137
ls *= scale;
1136-
double parscale[4] = {ls, ls * scaleRealU, ls * scaleRealV, ls * scaleRealU * scaleRealV};
1138+
double parscale[4] = {ls, ls * scaleRealV, ls * scaleRealU, ls * scaleRealU * scaleRealV};
11371139

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

0 commit comments

Comments
 (0)