@@ -176,8 +176,8 @@ void TPCFastSpaceChargeCorrectionHelper::fillSpaceChargeCorrectionFromMap(TPCFas
176176 }
177177
178178 if (processingInverseCorrection) {
179- float * splineX = correction.getSplineData (sector, row, 1 );
180- float * splineYZ = correction.getSplineData (sector, row, 2 );
179+ float * splineX = correction.getSplineDataInvX (sector, row);
180+ float * splineYZ = correction.getSplineDataInvYZ (sector, row);
181181 for (int i = 0 ; i < spline.getNumberOfParameters () / 3 ; i++) {
182182 splineX[i] = splineParameters[3 * i + 0 ];
183183 splineYZ[2 * i + 0 ] = splineParameters[3 * i + 1 ];
@@ -940,8 +940,8 @@ void TPCFastSpaceChargeCorrectionHelper::initInverse(std::vector<o2::gpu::TPCFas
940940 dataPointGridU.data (), dataPointGridV.data (),
941941 dataPointF.data (), nDataPoints);
942942
943- float * splineX = correction.getSplineData (sector, row, 1 );
944- float * splineUV = correction.getSplineData (sector, row, 2 );
943+ float * splineX = correction.getSplineDataInvX (sector, row);
944+ float * splineUV = correction.getSplineDataInvYZ (sector, row);
945945 for (int i = 0 ; i < spline.getNumberOfParameters () / 3 ; i++) {
946946 splineX[i] = splineParameters[3 * i + 0 ];
947947 splineUV[2 * i + 0 ] = splineParameters[3 * i + 1 ];
@@ -967,77 +967,129 @@ void TPCFastSpaceChargeCorrectionHelper::initInverse(std::vector<o2::gpu::TPCFas
967967 LOGP (info, " Inverse tooks: {}s" , duration);
968968}
969969
970- void TPCFastSpaceChargeCorrectionHelper::MergeCorrections (std::vector<o2::gpu::TPCFastSpaceChargeCorrection*>& corrections, const std::vector<float >& scaling, bool prn)
970+ void TPCFastSpaceChargeCorrectionHelper::MergeCorrections (
971+ o2::gpu::TPCFastSpaceChargeCorrection& mainCorrection, float mainScale,
972+ const std::vector<std::pair<const o2::gpu::TPCFastSpaceChargeCorrection*, float >>& additionalCorrections, bool /* prn*/ )
971973{
972974 // / merge several corrections
973- /*
975+
974976 TStopwatch watch;
975977 LOG (info) << " fast space charge correction helper: Merge corrections" ;
976978
977- if (corrections.size() != scaling.size()) {
978- LOGP(error, "Input corrections and scaling values have different size");
979- return;
980- }
981-
982- auto& correction = *(corrections.front());
979+ const auto & geo = mainCorrection.getGeometry ();
983980
984- for (int sector = 0; sector < mGeo .getNumberOfSectors(); sector++) {
981+ for (int sector = 0 ; sector < geo .getNumberOfSectors (); sector++) {
985982
986983 auto myThread = [&](int iThread) {
987- for (int row = iThread; row < mGeo .getNumberOfRows(); row += mNthreads) {
988- TPCFastSpaceChargeCorrection::SplineType spline = correction .getSpline(sector, row);
984+ for (int row = iThread; row < geo .getNumberOfRows (); row += mNthreads ) {
985+ const auto & spline = mainCorrection .getSpline (sector, row);
989986
990- std::vector< float> splineParameters(spline.getNumberOfParameters() );
991- std::vector< float> splineParametersInvX(spline.getNumberOfParameters() );
992- std::vector< float> splineParametersInvYZ(spline.getNumberOfParameters() );
987+ float * splineParameters = mainCorrection. getSplineData (sector, row );
988+ float * splineParametersInvX = mainCorrection. getSplineDataInvX (sector, row );
989+ float * splineParametersInvYZ = mainCorrection. getSplineDataInvYZ (sector, row );
993990
994- const auto& gridU = spline.getGridX1();
995- const auto& gridV = spline.getGridX2();
996-
997- for (int iu = 0; iu < gridU.getNumberOfKnots(); iu++) {
998- double u = gridU.getKnot(iu).u;
999- for (int iv = 0; iv < gridV.getNumberOfKnots(); iv++) {
1000- int knotIndex = spline.getKnotIndex(iu, iv);
991+ auto & secRowInfo = mainCorrection.getSectorRowInfo (sector, row);
1001992
1002- double v = gridV.getKnot(iu).u;
1003- auto [y, z] = correction.convGridToLocal(sector, row, u, v);
1004- constexpr int nKnotPar1d = 4;
1005- constexpr int nKnotPar2d = nKnotPar1d * 2;
1006- constexpr int nKnotPar3d = nKnotPar1d * 3;
993+ constexpr int nKnotPar1d = 4 ;
994+ constexpr int nKnotPar2d = nKnotPar1d * 2 ;
995+ constexpr int nKnotPar3d = nKnotPar1d * 3 ;
1007996
1008- for (int i = 0; i < corrections.size(); ++i) {
1009- double s = scaling[i];
1010- auto p = corrections[i]->getCorrectionParameters(sector, row, y, z);
1011- for (int j = 0; j < nKnotPar3d; ++j) {
1012- splineParameters[knotIndex * nKnotPar3d + j] += s * p[j];
997+ { // scale the main correction
998+ for (int i = 0 ; i < 3 ; i++) {
999+ secRowInfo.maxCorr [i] *= mainScale;
1000+ secRowInfo.minCorr [i] *= mainScale;
1001+ }
1002+ double parscale[4 ] = {mainScale, mainScale, mainScale, mainScale * mainScale};
1003+ for (int iknot = 0 , ind = 0 ; iknot < spline.getNumberOfKnots (); iknot++) {
1004+ for (int ipar = 0 ; ipar < nKnotPar1d; ++ipar) {
1005+ for (int idim = 0 ; idim < 3 ; idim++, ind++) {
1006+ splineParameters[ind] *= parscale[ipar];
10131007 }
1014- auto pInvX = corrections[i]->getCorrectionParametersInvX(sector, row, y, z);
1015- for (int j = 0; j < nKnotPar1d; ++j) {
1016- splineParametersInvX[knotIndex * nKnotPar1d + j] += s * pInvX[j];
1008+ }
1009+ }
1010+ for (int iknot = 0 , ind = 0 ; iknot < spline.getNumberOfKnots (); iknot++) {
1011+ for (int ipar = 0 ; ipar < nKnotPar1d; ++ipar) {
1012+ for (int idim = 0 ; idim < 1 ; idim++, ind++) {
1013+ splineParametersInvX[ind] *= parscale[ipar];
10171014 }
1018- auto pInvYZ = corrections[i]->getCorrectionParametersInvYZ(sector, row, y, z);
1019- for (int j = 0; j < nKnotPar2d; ++j) {
1020- splineParametersInvYZ[knotIndex * nKnotPar2d + j] += s * pInvYZ[j];
1015+ }
1016+ }
1017+ for (int iknot = 0 , ind = 0 ; iknot < spline.getNumberOfKnots (); iknot++) {
1018+ for (int ipar = 0 ; ipar < nKnotPar1d; ++ipar) {
1019+ for (int idim = 0 ; idim < 2 ; idim++, ind++) {
1020+ splineParametersInvYZ[ind] *= parscale[ipar];
10211021 }
10221022 }
1023- } // iv
1024- } // iu
1023+ }
1024+ }
10251025
1026- float* splineXYZ = correction.getSplineData(sector, row, 0);
1027- float* splineInvX = correction.getSplineData(sector, row, 1);
1028- float* splineInvYZ = correction.getSplineData(sector, row, 2);
1026+ // add the other corrections
10291027
1030- for (int i = 0; i < spline.getNumberOfParameters(); i++) {
1031- splineXYZ[i] = splineParameters[i];
1032- }
1033- for (int i = 0; i < spline.getNumberOfParameters() / 3; i++) {
1034- splineX[i] = splineParametersInvX[i];
1035- splineYZ[2 * i + 0] = splineParametersInvYZ[2 * i + 0];
1036- splineYZ[2 * i + 1] = splineParametersInvYZ[2 * i + 1];
1037- }
1028+ const auto & gridU = spline.getGridX1 ();
1029+ const auto & gridV = spline.getGridX2 ();
1030+
1031+ for (int icorr = 0 ; icorr < additionalCorrections.size (); ++icorr) {
1032+ const auto & corr = *(additionalCorrections[icorr].first );
1033+ double scale = additionalCorrections[icorr].second ;
1034+ auto & linfo = corr.getSectorRowInfo (sector, row);
1035+ secRowInfo.updateMaxValues (linfo.getMaxValues (), scale);
1036+ secRowInfo.updateMaxValues (linfo.getMinValues (), scale);
1037+
1038+ double scaleU = secRowInfo.scaleUtoGrid / linfo.scaleUtoGrid ;
1039+ double scaleV = secRowInfo.scaleVtoGrid / linfo.scaleVtoGrid ;
1040+
1041+ for (int iu = 0 ; iu < gridU.getNumberOfKnots (); iu++) {
1042+ double u = gridU.getKnot (iu).u ;
1043+ for (int iv = 0 ; iv < gridV.getNumberOfKnots (); iv++) {
1044+ double v = gridV.getKnot (iu).u ;
1045+ int knotIndex = spline.getKnotIndex (iu, iv);
1046+ float P[nKnotPar3d];
1047+
1048+ { // direct correction
1049+ auto [y, z] = mainCorrection.convGridToLocal (sector, row, u, v);
1050+ // return values: u, v, scaling factor
1051+ auto [lu, lv, ls] = corr.convLocalToGrid (sector, row, y, z);
1052+ ls *= scale;
1053+ double parscale[4 ] = {ls, ls * scaleU, ls * scaleV, ls * ls * scaleU * scaleV};
1054+ const auto & spl = corr.getSpline (sector, row);
1055+ spl.interpolateParametersAtU (corr.getSplineData (sector, row), lu, lv, P);
1056+ for (int ipar = 0 , ind = 0 ; ipar < nKnotPar1d; ++ipar) {
1057+ for (int idim = 0 ; idim < 3 ; idim++, ind++) {
1058+ splineParameters[knotIndex * nKnotPar3d + ind] += parscale[ipar] * P[ind];
1059+ }
1060+ }
1061+ }
1062+
1063+ auto [y, z] = mainCorrection.convGridToCorrectedLocal (sector, row, u, v);
1064+ // return values: u, v, scaling factor
1065+ auto [lu, lv, ls] = corr.convCorrectedLocalToGrid (sector, row, y, z);
1066+ ls *= scale;
1067+ double parscale[4 ] = {ls, ls * scaleU, ls * scaleV, ls * ls * scaleU * scaleV};
1068+
1069+ { // inverse X correction
1070+ corr.getSplineInvX (sector, row).interpolateParametersAtU (corr.getSplineDataInvX (sector, row), lu, lv, P);
1071+ for (int ipar = 0 , ind = 0 ; ipar < nKnotPar1d; ++ipar) {
1072+ for (int idim = 0 ; idim < 1 ; idim++, ind++) {
1073+ splineParametersInvX[knotIndex * nKnotPar1d + ind] += parscale[ipar] * P[ind];
1074+ }
1075+ }
1076+ }
1077+
1078+ { // inverse YZ correction
1079+ corr.getSplineInvYZ (sector, row).interpolateParametersAtU (corr.getSplineDataInvYZ (sector, row), lu, lv, P);
1080+ for (int ipar = 0 , ind = 0 ; ipar < nKnotPar1d; ++ipar) {
1081+ for (int idim = 0 ; idim < 2 ; idim++, ind++) {
1082+ splineParametersInvYZ[knotIndex * nKnotPar2d + ind] += parscale[ipar] * P[ind];
1083+ }
1084+ }
1085+ }
1086+
1087+ } // iv
1088+ } // iu
1089+ } // corrections
10381090
10391091 } // row
1040- }; // thread
1092+ }; // thread
10411093
10421094 std::vector<std::thread> threads (mNthreads );
10431095
@@ -1054,7 +1106,6 @@ void TPCFastSpaceChargeCorrectionHelper::MergeCorrections(std::vector<o2::gpu::T
10541106 } // sector
10551107 float duration = watch.RealTime ();
10561108 LOGP (info, " Merge of corrections tooks: {}s" , duration);
1057- */
10581109}
10591110
10601111} // namespace tpc
0 commit comments